diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp
index 0ad7ecec91537f75db91574466f44b35601c8580..d9b2c643adc9d151b0fe62a7aa550da8c9b8bda9 100644
--- a/Common/CommandLine.cpp
+++ b/Common/CommandLine.cpp
@@ -534,6 +534,7 @@ void GetOptions(int argc, char *argv[])
         i++;
 	if (i + 1 < argc && argv[i][0] != '-' && argv[i + 1][0] != '-') {
           gmsh_yystringsymbols[argv[i]] = argv[i + 1];
+          Msg::GetCommandLineStrings()[argv[i]] = argv[i + 1];
           i += 2;
 	}
         else
@@ -542,8 +543,8 @@ void GetOptions(int argc, char *argv[])
       else if (!strcmp(argv[i]+1, "setnumber")) {
         i++;
 	if (i + 1 < argc && argv[i][0] != '-') {
-          std::vector<double> val(1, atof(argv[i + 1]));
-          gmsh_yysymbols[argv[i]].value = val;
+          gmsh_yysymbols[argv[i]].value = std::vector<double>(1, atof(argv[i + 1]));
+          Msg::GetCommandLineNumbers()[argv[i]] = atof(argv[i + 1]);
           i += 2;
 	}
         else
diff --git a/Common/GmshMessage.cpp b/Common/GmshMessage.cpp
index 4dd3741c00d468d75ef4403cd045156b4f0723b7..bb446163a9f67a6eee78d90a6658b4c812407558 100644
--- a/Common/GmshMessage.cpp
+++ b/Common/GmshMessage.cpp
@@ -51,7 +51,6 @@
 #include "extraDialogs.h"
 #endif
 
-
 int Msg::_commRank = 0;
 int Msg::_commSize = 1;
 int Msg::_verbosity = 5;
@@ -65,6 +64,8 @@ std::string Msg::_firstError;
 GmshMessage *Msg::_callback = 0;
 std::string Msg::_commandLine;
 std::string Msg::_launchDate;
+std::map<std::string, double> Msg::_commandLineNumbers;
+std::map<std::string, std::string> Msg::_commandLineStrings;
 #if !defined(HAVE_ONELAB2)
 GmshClient *Msg::_client = 0;
 #endif
diff --git a/Common/GmshMessage.h b/Common/GmshMessage.h
index 48639eec98892e9af1bb31b229360d31ed03a12b..350aac789142ea943f3cc6580451786f8d5d5d51 100644
--- a/Common/GmshMessage.h
+++ b/Common/GmshMessage.h
@@ -47,6 +47,9 @@ class Msg {
   static GmshMessage *_callback;
   // command-line and startup time
   static std::string _commandLine, _launchDate;
+  // command-line-specified numbers and strings
+  static std::map<std::string, double> _commandLineNumbers;
+  static std::map<std::string, std::string> _commandLineStrings;
 #if !defined(HAVE_ONELAB2)
   // communication with Gmsh when run remotely
   static GmshClient *_client;
@@ -80,6 +83,14 @@ class Msg {
   static int GetVerbosity(){ return _verbosity; }
   static std::string GetLaunchDate(){ return _launchDate; }
   static std::string GetCommandLineArgs(){ return _commandLine; }
+  static std::map<std::string, double> &GetCommandLineNumbers()
+  {
+    return _commandLineNumbers;
+  }
+  static std::map<std::string, std::string> &GetCommandLineStrings()
+  {
+    return _commandLineStrings;
+  }
   static void Fatal(const char *fmt, ...);
   static void Error(const char *fmt, ...);
   static void Warning(const char *fmt, ...);
diff --git a/Common/OpenFile.cpp b/Common/OpenFile.cpp
index 6bfcb20c905ab041bd798a124b53871f1106117c..97fb592a4454cc3c6ed406c8c3e2c482c9a3745a 100644
--- a/Common/OpenFile.cpp
+++ b/Common/OpenFile.cpp
@@ -661,29 +661,26 @@ void OpenProject(const std::string &fileName, bool setWindowTitle)
     // reuse it
     GModel::current()->destroy();
     GModel::current()->getGEOInternals()->destroy();
-    // don't clear the parser variables if we just launched gmsh with the
-    // -string, -setstring or -setnumber command line options
-#if defined(HAVE_PARSER)
-    std::string c = Msg::GetCommandLineArgs();
-    if(c.find("-string") == std::string::npos &&
-       c.find("-setstring") == std::string::npos &&
-       c.find("-setnumber") == std::string::npos){
-      gmsh_yysymbols.clear();
-      gmsh_yystringsymbols.clear();
-    }
-#endif
   }
   else{
-    // if the current model is not empty make it invisible, clear the parser
-    // variables and add a new model
-#if defined(HAVE_PARSER)
-    gmsh_yysymbols.clear();
-    gmsh_yystringsymbols.clear();
-#endif
+    // if the current model is not empty make it invisible and add a new model
     new GModel();
     GModel::current(GModel::list.size() - 1);
   }
 
+  // clear parser variables, but keep -setnumber/-setstrings command line
+  // definitions
+#if defined(HAVE_PARSER)
+  gmsh_yysymbols.clear();
+  gmsh_yystringsymbols.clear();
+  std::map<std::string, double> cln(Msg::GetCommandLineNumbers());
+  for(std::map<std::string, double>::iterator it = cln.begin(); it != cln.end(); it++)
+    gmsh_yysymbols[it->first].value = std::vector<double>(1, it->second);
+  std::map<std::string, std::string> cls(Msg::GetCommandLineStrings());
+  for(std::map<std::string, std::string>::iterator it = cls.begin(); it != cls.end(); it++)
+    gmsh_yystringsymbols[it->first] = it->second;
+#endif
+
   // temporary hack until we fill the current GModel on the fly during parsing
   ResetTemporaryBoundingBox();
 
diff --git a/Common/onelabUtils.cpp b/Common/onelabUtils.cpp
index 308034249086701a4b9d1f8250a76b844cdab534..4ece1c08b12343ffac514f0f55f009ec2979326a 100644
--- a/Common/onelabUtils.cpp
+++ b/Common/onelabUtils.cpp
@@ -124,17 +124,17 @@ namespace onelabUtils {
         args.push_back(" " + checkCommand) ;
       else if(action == "compute")
         args.push_back(" " + computeCommand);
-      // Experimental: propagate -setnumber/-setnumber gmsh option to the
-      // client. Is this a good idea?
-      std::vector<std::string> gmshOptions = onelab::parameter::split
-        (Msg::GetCommandLineArgs(), ' ');
-      for(unsigned int i = 0; i < gmshOptions.size(); i++){
-        if((gmshOptions[i] == "-setnumber" || gmshOptions[i] == "-setstring") &&
-           i < gmshOptions.size() - 2){
-          args.push_back(" " + gmshOptions[i] + " " + gmshOptions[i + 1] +
-                         " " + gmshOptions[i + 2]);
-        }
-      }
+      // Propagate -setnumber/-setnumber gmsh option to the client. (Is this a
+      // good idea?)
+      std::ostringstream sstream;
+      sstream.precision(16);
+      std::map<std::string, double> cln(Msg::GetCommandLineNumbers());
+      for(std::map<std::string, double>::iterator it = cln.begin(); it != cln.end(); it++)
+        sstream << " -setnumber " << it->first << " " << it->second;
+      std::map<std::string, std::string> cls(Msg::GetCommandLineStrings());
+      for(std::map<std::string, std::string>::iterator it = cls.begin(); it != cls.end(); it++)
+        sstream << " -setstring " << it->first << " " << it->second;
+      args.push_back(sstream.str());
     }
     return args;
   }