From d07aa3f15756d96ff1fe22221ea3b64909cd31a9 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Wed, 16 Jul 2014 05:48:43 +0000
Subject: [PATCH] new options to specify the python and octave interpreters

---
 Common/CommandLine.cpp           | 19 ++++++++++++++++++-
 Common/Context.h                 |  2 +-
 Common/DefaultOptions.h          |  5 +++++
 Common/OS.cpp                    | 21 ++++++++++++++-------
 Common/OpenFile.cpp              |  1 +
 Common/Options.cpp               | 24 ++++++++++++++++++++++++
 Common/Options.h                 |  2 ++
 Fltk/optionWindow.cpp            | 12 ++++++++++++
 utils/misc/gmsh_app.plist        |  2 +-
 utils/misc/package_gmsh_getdp.sh |  4 ++--
 10 files changed, 80 insertions(+), 12 deletions(-)

diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp
index 60eefc288b..21cd26ddb5 100644
--- a/Common/CommandLine.cpp
+++ b/Common/CommandLine.cpp
@@ -105,6 +105,10 @@ std::vector<std::pair<std::string, std::string> > GetUsage()
   s.push_back(mp("-link int",          "Select link mode between views (0, 1, 2, 3, 4)"));
   s.push_back(mp("-combine",           "Combine views having identical names into "
                                        "multi-time-step views"));
+  s.push_back(mp("Solver options:", ""));
+  s.push_back(mp("-listen",            "Always listen to incoming connection requests"));
+  s.push_back(mp("-minterpreter string", "Name of Octave interpreter"));
+  s.push_back(mp("-pyinterpreter string", "Name of Python interpreter"));
   s.push_back(mp("Display options:", ""));
   s.push_back(mp("-n",                 "Hide all meshes and post-processing views on startup"));
   s.push_back(mp("-nodb",              "Disable double buffering"));
@@ -127,7 +131,6 @@ std::vector<std::pair<std::string, std::string> > GetUsage()
                                        "post-processing mode"));
 #endif
   s.push_back(mp("-pid",               "Print process id on stdout"));
-  s.push_back(mp("-listen",            "Always listen to incoming connection requests"));
   s.push_back(mp("-watch pattern",     "Pattern of files to merge as they become available"));
   s.push_back(mp("-bg file",           "Load background (image or PDF) file"));
   s.push_back(mp("-v int",             "Set verbosity level"));
@@ -893,6 +896,20 @@ void GetOptions(int argc, char *argv[])
         CTX::instance()->solver.listen = 1;
         i++;
       }
+      else if(!strcmp(argv[i] + 1, "minterpreter")) {
+        i++;
+        if(argv[i])
+          CTX::instance()->solver.octaveInterpreter = argv[i++];
+        else
+          Msg::Fatal("Missing interpreter name");
+      }
+      else if(!strcmp(argv[i] + 1, "pyinterpreter")) {
+        i++;
+        if(argv[i])
+          CTX::instance()->solver.pythonInterpreter = argv[i++];
+        else
+          Msg::Fatal("Missing interpreter name");
+      }
       else if(!strcmp(argv[i] + 1, "bg")){
         i++;
         if(argv[i])
diff --git a/Common/Context.h b/Common/Context.h
index 2079af124b..68baa663ce 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -239,7 +239,7 @@ class CTX {
   struct{
     int plugins, listen;
     double timeout;
-    std::string socketName;
+    std::string socketName, pythonInterpreter, octaveInterpreter;
     std::string name[NUM_SOLVERS], executable[NUM_SOLVERS], remoteLogin[NUM_SOLVERS];
     int autoSaveDatabase, autoArchiveOutputFiles, autoMesh, autoMergeFile;
     int autoShowViews, autoShowLastStep, autoCheck, showInvisibleParameters;
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index a4ad06b266..7e0cc601ba 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -168,6 +168,11 @@ StringXString SolverOptions_String[] = {
   { F|S, "Name9" , opt_solver_name9 , "" ,
     "Name of solver 9" },
 
+  { F|S, "OctaveInterpreter" , opt_solver_octave_interpreter , "octave" ,
+    "Name of the Octave interpreter (used to run .m files)" },
+  { F|S, "PythonInterpreter" , opt_solver_python_interpreter , "python" ,
+    "Name of the Python interpreter (used to run .py files if they are not executable)" },
+
   { F|S, "RemoteLogin0" , opt_solver_remote_login0 , "",
     "Command to login to a remote host to launch solver 0" },
   { F|S, "RemoteLogin1" , opt_solver_remote_login1 , "" ,
diff --git a/Common/OS.cpp b/Common/OS.cpp
index 808b26b949..c6a0246f88 100644
--- a/Common/OS.cpp
+++ b/Common/OS.cpp
@@ -16,6 +16,7 @@
 #include <math.h>
 #include "GmshConfig.h"
 #include "StringUtils.h"
+#include "Context.h"
 
 #if defined(__APPLE__)
 #include <sys/sysctl.h>
@@ -394,11 +395,12 @@ int SystemCall(const std::string &command, bool blocking)
   // get executable extension
   std::vector<std::string> split = SplitFileName(exe);
 
-  // do we try to run a .py script or a .exe?
+  // do we try to run a .py script, .m script or an .exe?
   bool isPython = (split[2] == ".py" || split[2] == ".PY");
+  bool isOctave = (split[2] == ".m" || split[2] == ".M");
   bool isExe = (split[2] == ".exe" || split[2] == ".EXE");
 
-  if(isPython || isExe){
+  if(isPython || isOctave || isExe){
     if(StatFile(exe)){
       Msg::Error("Unable to open file '%s'", exe.c_str());
       return 1;
@@ -406,7 +408,7 @@ int SystemCall(const std::string &command, bool blocking)
   }
 
 #if defined(WIN32) && !defined(__CYGWIN__)
-  if(isPython){
+  if(isPython || isOctave){
     Msg::Info("Shell opening '%s' with arguments '%s'", exe.c_str(),
               args.c_str());
     setwbuf(0, "open");
@@ -441,12 +443,17 @@ int SystemCall(const std::string &command, bool blocking)
   }
 #else
   std::string cmd(command);
-  if(isPython || isExe){
+  if(isPython || isOctave || isExe){
     if(access(exe.c_str(), X_OK)){
       if(isPython){
-        Msg::Info("Script '%s' is not executable: running with python",
-		  exe.c_str());
-        cmd = "python " + cmd;
+        Msg::Info("Script '%s' is not executable: running with `%s'",
+		  exe.c_str(), CTX::instance()->solver.pythonInterpreter.c_str());
+        cmd = CTX::instance()->solver.pythonInterpreter + " " + cmd;
+      }
+      else if(isOctave){
+        Msg::Info("Script '%s' is not executable: running with `%s'",
+		  exe.c_str(), CTX::instance()->solver.octaveInterpreter.c_str());
+        cmd = CTX::instance()->solver.octaveInterpreter + " " + cmd;
       }
       else
         Msg::Warning("File '%s' is not executable", exe.c_str());
diff --git a/Common/OpenFile.cpp b/Common/OpenFile.cpp
index 0da2124a3f..80c25cd60c 100644
--- a/Common/OpenFile.cpp
+++ b/Common/OpenFile.cpp
@@ -429,6 +429,7 @@ int MergeFile(const std::string &fileName, bool warnIfMissing, bool setWindowTit
     return 1;
   }
   else if(ext == ".py" || ext == ".PY" ||
+          ext == ".m" || ext == ".M" ||
           ext == ".exe" || ext == ".EXE"){
     int num = defineSolver(split[1]);
     opt_solver_executable(num, GMSH_SET, fileName);
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 552de153ac..517f3037c6 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1466,6 +1466,30 @@ std::string opt_solver_remote_login9(OPT_ARGS_STR)
   return opt_solver_remote_login(9, action, val);
 }
 
+std::string opt_solver_python_interpreter(OPT_ARGS_STR)
+{
+  if(action & GMSH_SET)
+    CTX::instance()->solver.pythonInterpreter = val;
+#if defined(HAVE_FLTK)
+  if(FlGui::available() && (action & GMSH_GUI))
+    FlGui::instance()->options->solver.input[1]->value
+      (CTX::instance()->solver.pythonInterpreter.c_str());
+#endif
+  return CTX::instance()->solver.pythonInterpreter;
+}
+
+std::string opt_solver_octave_interpreter(OPT_ARGS_STR)
+{
+  if(action & GMSH_SET)
+    CTX::instance()->solver.octaveInterpreter = val;
+#if defined(HAVE_FLTK)
+  if(FlGui::available() && (action & GMSH_GUI))
+    FlGui::instance()->options->solver.input[2]->value
+      (CTX::instance()->solver.octaveInterpreter.c_str());
+#endif
+  return CTX::instance()->solver.octaveInterpreter;
+}
+
 #if defined(HAVE_FLTK)
 int _gui_action_valid(int action, int num)
 {
diff --git a/Common/Options.h b/Common/Options.h
index 5712018018..13825736a9 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -86,6 +86,8 @@ std::string opt_solver_remote_login6(OPT_ARGS_STR);
 std::string opt_solver_remote_login7(OPT_ARGS_STR);
 std::string opt_solver_remote_login8(OPT_ARGS_STR);
 std::string opt_solver_remote_login9(OPT_ARGS_STR);
+std::string opt_solver_octave_interpreter(OPT_ARGS_STR);
+std::string opt_solver_python_interpreter(OPT_ARGS_STR);
 std::string opt_view_name(OPT_ARGS_STR);
 std::string opt_view_format(OPT_ARGS_STR);
 std::string opt_view_filename(OPT_ARGS_STR);
diff --git a/Fltk/optionWindow.cpp b/Fltk/optionWindow.cpp
index a4deb5da85..3db05f54ad 100644
--- a/Fltk/optionWindow.cpp
+++ b/Fltk/optionWindow.cpp
@@ -584,6 +584,8 @@ static void solver_options_ok_cb(Fl_Widget *w, void *data)
 
   opt_solver_socket_name(0, GMSH_SET, o->solver.input[0]->value());
   opt_solver_timeout(0, GMSH_SET, o->solver.value[0]->value());
+  opt_solver_python_interpreter(0, GMSH_SET, o->solver.input[1]->value());
+  opt_solver_octave_interpreter(0, GMSH_SET, o->solver.input[2]->value());
 
   if(CTX::instance()->fastRedraw)
     CTX::instance()->post.draw = CTX::instance()->mesh.draw = 0;
@@ -2699,6 +2701,16 @@ optionWindow::optionWindow(int deltaFontSize)
         solver.butt[0]->type(FL_TOGGLE_BUTTON);
         solver.butt[0]->callback(solver_options_ok_cb);
 
+        solver.input[1] = new Fl_Input
+          (L + 2 * WB, 2 * WB + 4 * BH, IW, BH, "Python interpreter");
+        solver.input[1]->align(FL_ALIGN_RIGHT);
+        solver.input[1]->callback(solver_options_ok_cb);
+
+        solver.input[2] = new Fl_Input
+          (L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Octave interpreter");
+        solver.input[2]->align(FL_ALIGN_RIGHT);
+        solver.input[2]->callback(solver_options_ok_cb);
+
         o->end();
       }
     }
diff --git a/utils/misc/gmsh_app.plist b/utils/misc/gmsh_app.plist
index 6bd3849576..b2d6da8b2b 100644
--- a/utils/misc/gmsh_app.plist
+++ b/utils/misc/gmsh_app.plist
@@ -9,7 +9,7 @@
     <key>CFBundleShortVersionString</key><string>GMSH_VERSION</string>
     <key>CFBundleIconFile</key><string>Gmsh.icns</string>
     <key>CFBundleSignature</key><string>GMSH</string>
-    <key>CFBundleGetInfoString</key><string>Gmsh GMSH_VERSION, Copyright 1997-2013 C. Geuzaine and J.-F. Remacle</string>
+    <key>CFBundleGetInfoString</key><string>Gmsh GMSH_VERSION, Copyright 1997-2014 C. Geuzaine and J.-F. Remacle</string>
     <key>CFBundleIdentifier</key><string>org.geuz.Gmsh</string>
     <key>NSHighResolutionCapable</key><true/>
     <key>CFBundleDocumentTypes</key>
diff --git a/utils/misc/package_gmsh_getdp.sh b/utils/misc/package_gmsh_getdp.sh
index 44c3950a34..4e6c6ee127 100755
--- a/utils/misc/package_gmsh_getdp.sh
+++ b/utils/misc/package_gmsh_getdp.sh
@@ -14,8 +14,8 @@ up-to-date versions, documentation and examples." > /tmp/README.txt
 GMSH=svn
 GETDP=svn
 
-#GMSH=2.8.4
-#GETDP=2.4.3
+GMSH=2.8.5
+GETDP=2.4.4
 
 rm -rf gmsh-getdp-Windows64
 mkdir gmsh-getdp-Windows64
-- 
GitLab