From d71d2045c0c809935b1536ba6af8357de7c86a84 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Sat, 4 May 2013 09:32:06 +0000
Subject: [PATCH] try to find client executable in same directory as argv0 this
 amkes it easier to ship bundles (e.g. gmsh+getdp)

---
 Common/CommandLine.cpp |  1 +
 Common/Context.h       |  1 +
 Fltk/onelabGroup.cpp   | 56 +++++++++++++++++++++++++++++++-----------
 3 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp
index c13ac7d76a..f6fcdbb4bc 100644
--- a/Common/CommandLine.cpp
+++ b/Common/CommandLine.cpp
@@ -268,6 +268,7 @@ void GetOptions(int argc, char *argv[])
 
 #if defined(HAVE_PARSER)
   if(argc && argv){
+    CTX::instance()->argv0 = std::string(argv[0]);
     // parse session and option file (if argc/argv is not provided skip this
     // step: this is usually what is expected when using Gmsh as a library)
     ParseFile(CTX::instance()->homeDir + CTX::instance()->sessionFileName, true);
diff --git a/Common/Context.h b/Common/Context.h
index 04ca41b24a..9eac33fda6 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -79,6 +79,7 @@ class CTX {
   std::string bgmFileName, outputFileName, defaultFileName, tmpFileName;
   std::string sessionFileName, optionsFileName, errorFileName;
   std::string meshStatReportFileName;
+  std::string argv0;
   // the home directory
   std::string homeDir;
   // file history
diff --git a/Fltk/onelabGroup.cpp b/Fltk/onelabGroup.cpp
index 6b62f554a0..44fd93a77e 100644
--- a/Fltk/onelabGroup.cpp
+++ b/Fltk/onelabGroup.cpp
@@ -11,6 +11,7 @@
 typedef unsigned long intptr_t;
 #endif
 
+#include <ctype.h>
 #include "GmshMessage.h"
 #include "onelab.h"
 #include "gmshLocalNetworkClient.h"
@@ -232,7 +233,7 @@ bool gmshLocalNetworkClient::receiveMessage(gmshLocalNetworkClient *master)
         std::vector<onelab::number> par; get(par, name);
         if(par.size() == 1) {
 	  p = par[0];
-	  onelab::number y; y.fromChar(message); 
+	  onelab::number y; y.fromChar(message);
 	  onelabUtils::updateNumber(p,y);
 	}
 	else
@@ -244,11 +245,11 @@ bool gmshLocalNetworkClient::receiveMessage(gmshLocalNetworkClient *master)
                                            p.getMin(), p.getMax());
       }
       else if(type == "string"){
-        onelab::string p; 
+        onelab::string p;
 	std::vector<onelab::string> par; get(par, name);
         if(par.size() == 1){
 	  p = par[0];
-	  onelab::string y; y.fromChar(message); 
+	  onelab::string y; y.fromChar(message);
 	  onelabUtils::updateString(p,y);
 	}
 	else
@@ -864,20 +865,47 @@ static void onelab_choose_executable_cb(Fl_Widget *w, void *data)
 #if defined(WIN32)
   pattern += ".exe";
 #endif
-  const char *old = 0;
-  if(!c->getExecutable().empty()) old = c->getExecutable().c_str();
 
-  if(!w){
-    const char *old = fl_close;
-    fl_close = "OK";
-    fl_message("This appears to be the first time you are trying to run %s.\n\n"
-               "Please select the path to the executable.", c->getName().c_str());
-    fl_close = old;
+  std::string exe = "";
+
+  if(!w){ // we entered here automatically because no executable is given
+
+    // try to find an executable automatically (this is really useful for
+    // beginners)
+    if(CTX::instance()->argv0.size()){
+      std::vector<std::string> split = SplitFileName(CTX::instance()->argv0);
+      std::string name = c->getName();
+      for(unsigned int i = 0; i < name.size(); i++)
+        name[i] = tolower(name[i]);
+      std::string path = split[0] + name;
+#if defined(WIN32)
+      path += ".exe";
+#endif
+      if(!StatFile(path)){
+        exe = path;
+        Msg::Info("Automatically found %s executable: %s", c->getName().c_str(),
+                  exe.c_str());
+      }
+    }
+
+    if(exe.empty()){
+      const char *o = fl_close;
+      fl_close = "OK";
+      fl_message("This appears to be the first time you are trying to run %s.\n\n"
+                 "Please select the path to the executable.", c->getName().c_str());
+      fl_close = o;
+    }
+  }
+
+  if(exe.empty()){
+    const char *old = 0;
+    if(c->getExecutable().size()) old = c->getExecutable().c_str();
+    std::string title = "Choose location of " + c->getName() + " executable";
+    if(fileChooser(FILE_CHOOSER_SINGLE, title.c_str(), pattern.c_str(), old))
+      exe = fileChooserGetName(1);
   }
 
-  std::string title = "Choose location of " + c->getName() + " executable";
-  if(fileChooser(FILE_CHOOSER_SINGLE, title.c_str(), pattern.c_str(), old)){
-    std::string exe = fileChooserGetName(1);
+  if(exe.size()){
     c->setExecutable(exe);
     if(c->getIndex() >= 0 && c->getIndex() < 5)
       opt_solver_executable(c->getIndex(), GMSH_SET, exe);
-- 
GitLab