ecere, ide; Instance_COM_Initialize, Tokenize, _DualPipeOpen; multiple fixes. finally...
authorRejean Loyer <rejean.loyer@gmail.com>
Wed, 12 Jun 2013 19:59:31 +0000 (15:59 -0400)
committerRejean Loyer <rejean.loyer@gmail.com>
Thu, 13 Jun 2013 10:32:43 +0000 (06:32 -0400)
 - affects all command line tools.
 - fixed windows arguments parsing to respect spaces and double quotes that are escaped.
 - adjusted toolchaing debugging tools to not alter the way args are passed to the debugging ide now that win args parsing is fixed.
 - fixed preprocessor definitions when defining MY_STR_DEF="string" on windows by escaping quotes.

18 files changed:
Makefile
compiler/Makefile
compiler/ecc/ecc.ec
compiler/ecp/ecp.ec
compiler/libec/src/ecdefs.ec
crossplatform.mk
default.cf
ear/extract/Makefile
ecere/Makefile
ecere/Makefile.ecereCOM
ecere/Makefile.vanilla
ecere/src/com/String.ec
ecere/src/com/instance.c
ecere/src/sys/DualPipe.c
ide/src/debugger/Debugger.ec
ide/src/ide.ec
ide/src/project/Project.ec
ide/src/project/ProjectNode.ec

index 8c6c755..596ed56 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -126,7 +126,7 @@ else
 endif
 
 export CPPFLAGS
-CPPFLAGS += -DDEB_HOST_MULTIARCH=\"$(PREFIXLIBDIR)\"
+CPPFLAGS += -DDEB_HOST_MULTIARCH=\"$(call escspace,$(PREFIXLIBDIR))\"
 
 DESTLIBDIR := $(DESTDIR)$(PREFIXLIBDIR)
 ifdef SLIBDIR
index c5418b2..fb9e957 100644 (file)
@@ -54,7 +54,7 @@ clean:
 realclean:
        cd bootstrap && $(MAKE) realclean
        cd libec && $(MAKE) realclean
-       cd libec && $(MAKE) fixprecompile
+       cd libec && $(MAKE) silentfixprecompile
        cd ecp && $(MAKE) realclean
        cd ecc && $(MAKE) realclean
        cd ecs && $(MAKE) realclean
@@ -62,7 +62,7 @@ realclean:
 distclean:
        cd bootstrap && $(MAKE) distclean
        cd libec && $(MAKE) distclean
-       cd libec && $(MAKE) fixprecompile
+       cd libec && $(MAKE) silentfixprecompile
        cd ecp && $(MAKE) distclean
        cd ecc && $(MAKE) distclean
        cd ecs && $(MAKE) distclean
index 4969d56..7b680d7 100644 (file)
@@ -296,42 +296,31 @@ class CompilerApp : Application
          {
             if(!strcmp(arg + 1, "m32") || !strcmp(arg + 1, "m64"))
             {
-               int argLen = strlen(arg);
-               int newLen = cppOptionsLen + 1 + argLen;
+               int newLen = cppOptionsLen + 1 + strlen(arg);
                cppOptions = renew cppOptions char[newLen + 1];
                cppOptions[cppOptionsLen] = ' ';
                strcpy(cppOptions + cppOptionsLen + 1, arg);
                cppOptionsLen = newLen;
                targetBits = !strcmp(arg + 1, "m32") ? 32 : 64;
             }
-            else if(arg[1] == 'D')
+            else if(arg[1] == 'D' || arg[1] == 'I')
             {
-               int argLen = strlen(arg);
-               int newLen = cppOptionsLen + 1 + argLen;
-               cppOptions = renew cppOptions char[newLen + 1];
-               cppOptions[cppOptionsLen] = ' ';
-               strcpy(cppOptions + cppOptionsLen + 1, arg); 
-               cppOptionsLen = newLen;
-               if(!strcmp(arg, "-DBUILDING_ECERE_COM"))
-                  SetBuildingEcereCom(true);
-               else if(!strcmp(arg, "-DECERE_COM_MODULE"))
-                  SetBuildingEcereComModule(true);
-               else if(!strcmp(arg, "-DECERE_BOOTSTRAP"))
-                  buildingBootStrap = true;
-            }
-            else if(arg[1] == 'I')
-            {
-               int argLen = strlen(arg);
-               int newLen = cppOptionsLen + argLen + 3;
-               cppOptions = renew cppOptions char[newLen + 1];
-               cppOptions[cppOptionsLen] = ' ';
-               cppOptions[cppOptionsLen+1] = '-';
-               cppOptions[cppOptionsLen+2] = 'I';
-               cppOptions[cppOptionsLen+3] = '"';
-               strcpy(cppOptions + cppOptionsLen + 4, arg+2); 
-               cppOptions[newLen-1] = '\"';
-               cppOptions[newLen] = '\0';
-               cppOptionsLen = newLen;
+               char * buf;
+               int size = cppOptionsLen + 1 + strlen(arg) * 2 + 1;
+               cppOptions = renew cppOptions char[size];
+               buf = cppOptions + cppOptionsLen;
+               *buf++ = ' ';
+               PassArg(buf, arg);
+               cppOptionsLen = cppOptionsLen + 1 + strlen(buf);
+               if(arg[1] == 'D')
+               {
+                  if(!strcmp(arg, "-DBUILDING_ECERE_COM"))
+                     SetBuildingEcereCom(true);
+                  else if(!strcmp(arg, "-DECERE_COM_MODULE"))
+                     SetBuildingEcereComModule(true);
+                  else if(!strcmp(arg, "-DECERE_BOOTSTRAP"))
+                     buildingBootStrap = true;
+               }
             }
             else if(!strcmp(arg+1, "t"))
             {
@@ -371,19 +360,16 @@ class CompilerApp : Application
             {
                if(c + 1 < argc)
                {
-                  int argLen = strlen(arg);
-                  int arg1Len = strlen(argv[c+1]);
-                  int newLen = cppOptionsLen + argLen + arg1Len + 4;
-                  cppOptions = renew cppOptions char[newLen + 1];
-                  cppOptions[cppOptionsLen] = ' ';
-                  strcpy(cppOptions + cppOptionsLen + 1, arg); 
-                  cppOptions[cppOptionsLen+argLen+1] = ' ';
-                  cppOptions[cppOptionsLen+argLen+2] = '"';
-                  arg = argv[++c];
-                  strcpy(cppOptions + cppOptionsLen + argLen + 3, arg); 
-                  cppOptions[newLen-1] = '\"';
-                  cppOptions[newLen] = '\0';
-                  cppOptionsLen = newLen;
+                  char * buf;
+                  char * arg1 = argv[++c];
+                  int size = cppOptionsLen + 1 + strlen(arg) * 2 + strlen(arg1) * 2 + 1;
+                  cppOptions = renew cppOptions char[size];
+                  buf = cppOptions + cppOptionsLen;
+                  *buf++ = ' ';
+                  buf = PassArg(buf, arg);
+                  *buf++ = ' ';
+                  buf = PassArg(buf, arg1);
+                  cppOptionsLen = buf - cppOptions;
                }
                else
                   valid = false;
index 6d60e3c..38e399b 100644 (file)
@@ -1337,36 +1337,22 @@ class PrecompApp : Application
          {
             if(!strcmp(arg + 1, "m32") || !strcmp(arg + 1, "m64"))
             {
-               int argLen = strlen(arg);
-               int newLen = cppOptionsLen + 1 + argLen;
+               int newLen = cppOptionsLen + 1 + strlen(arg);
                cppOptions = renew cppOptions char[newLen + 1];
                cppOptions[cppOptionsLen] = ' ';
                strcpy(cppOptions + cppOptionsLen + 1, arg);
                cppOptionsLen = newLen;
                targetBits = !strcmp(arg + 1, "m32") ? 32 : 64;
             }
-            else if(arg[1] == 'D')
+            else if(arg[1] == 'D' || arg[1] == 'I')
             {
-               int argLen = strlen(arg);
-               int newLen = cppOptionsLen + 1 + argLen;
-               cppOptions = renew cppOptions char[newLen + 1];
-               cppOptions[cppOptionsLen] = ' ';
-               strcpy(cppOptions + cppOptionsLen + 1, arg); 
-               cppOptionsLen = newLen;
-            }
-            else if(arg[1] == 'I')
-            {
-               int argLen = strlen(arg);
-               int newLen = cppOptionsLen + argLen + 3;
-               cppOptions = renew cppOptions char[newLen + 1];
-               cppOptions[cppOptionsLen] = ' ';
-               cppOptions[cppOptionsLen+1] = '-';
-               cppOptions[cppOptionsLen+2] = 'I';
-               cppOptions[cppOptionsLen+3] = '"';
-               strcpy(cppOptions + cppOptionsLen + 4, arg+2); 
-               cppOptions[newLen-1] = '\"';
-               cppOptions[newLen] = '\0';
-               cppOptionsLen = newLen;
+               char * buf;
+               int size = cppOptionsLen + 1 + strlen(arg) * 2 + 1;
+               cppOptions = renew cppOptions char[size];
+               buf = cppOptions + cppOptionsLen;
+               *buf++ = ' ';
+               PassArg(buf, arg);
+               cppOptionsLen = cppOptionsLen + 1 + strlen(buf);
             }
             else if(!strcmp(arg+1, "t"))
             {
@@ -1406,19 +1392,16 @@ class PrecompApp : Application
             {
                if(c + 1 < argc)
                {
-                  int argLen = strlen(arg);
-                  int arg1Len = strlen(argv[c+1]);
-                  int newLen = cppOptionsLen + argLen + arg1Len + 4;
-                  cppOptions = renew cppOptions char[newLen + 1];
-                  cppOptions[cppOptionsLen] = ' ';
-                  strcpy(cppOptions + cppOptionsLen + 1, arg); 
-                  cppOptions[cppOptionsLen+argLen+1] = ' ';
-                  cppOptions[cppOptionsLen+argLen+2] = '"';
-                  arg = argv[++c];
-                  strcpy(cppOptions + cppOptionsLen + argLen + 3, arg); 
-                  cppOptions[newLen-1] = '\"';
-                  cppOptions[newLen] = '\0';
-                  cppOptionsLen = newLen;
+                  char * buf;
+                  char * arg1 = argv[++c];
+                  int size = cppOptionsLen + 1 + strlen(arg) * 2 + strlen(arg1) * 2 + 1;
+                  cppOptions = renew cppOptions char[size];
+                  buf = cppOptions + cppOptionsLen;
+                  *buf++ = ' ';
+                  buf = PassArg(buf, arg);
+                  *buf++ = ' ';
+                  buf = PassArg(buf, arg1);
+                  cppOptionsLen = buf - cppOptions;
                }
                else
                   valid = false;
index e316105..e2fea0e 100644 (file)
@@ -101,6 +101,45 @@ public void FixModuleName(char *moduleName)
    ChangeCh(moduleName, '&', '_');
 }
 
+// todo support %var% variables for windows and $var for linux?
+public char * PassArg(char * output, const char * input)
+{
+#ifdef __WIN32__
+//define windowsFileNameCharsNeedEscaping = " !%&'()+,;=[]^`{}~"; // "#$-.@_" are ok
+   const char * escChars = " !\"%&'()+,;=[]^`{}~"; // windowsFileNameCharsNeedEscaping;
+   const char * escCharsQuoted = "\"";
+#else
+//define linuxFileNameCharsNeedEscaping = " !\"$&'()*:;<=>?[\\`{|"; // "#%+,-.@]^_}~" are ok
+   const char * escChars = " !\"$&'()*:;<=>?[\\`{|"; // linuxFileNameCharsNeedEscaping;
+   const char * escCharsQuoted = "\"()$";
+#endif
+   bool quoting = false;
+   char *o = output, *i = input, *l = input;
+#ifdef __WIN32__
+   while(*l && !strchr(escChars, *l)) l++;
+   if(*l) quoting = true;
+#else
+   if(*i == '-')
+   {
+      l++;
+      while(*l && !strchr(escChars, *l)) l++;
+      if(*l) quoting = true;
+      *o++ = *i++;
+   }
+#endif
+   if(quoting)
+      *o++ = '\"';
+   while(*i)
+   {
+      if(strchr(quoting ? escCharsQuoted : escChars, *i))
+         *o++ = '\\';
+      *o++ = *i++;
+   }
+   if(quoting)
+      *o++ = '\"';
+   *o = '\0';
+   return o;
+}
 /*public Module GetPrivateModule()
 {
    return privateModule;
index c19098b..b3b90c0 100644 (file)
@@ -150,11 +150,15 @@ endif
 
 # MISC STRING TOOLS
 empty :=
+esc := $(empty)\7f$(empty)
 space := $(empty) $(empty)
 comma := ,
-escspace = $(subst $(space),\$(space),$(subst \$(space),$(space),$1))
-hidspace = $(subst $(space),\7f,$(subst \$(space),\7f,$1))
-shwspace = $(subst \7f,\$(space),$1)
+slash := $(empty)/$(empty)
+backslash := $(empty)\$(empty)
+escspace = $(subst $(space),$(backslash)$(space),$(subst $(backslash)$(space),$(space),$(1)))
+hidspace = $(subst $(space),$(esc),$(subst $(backslash)$(space),$(esc),$(1)))
+shwspace = $(subst $(esc),$(backslash)$(space),$(1))
+unescp_all = $(subst $(esc),$(backslash),$(subst $(backslash),,$(subst $(backslash)$(backslash),$(esc),$(1))))
 
 # PATH SEPARATOR STRING TOOLS
 ifdef WINDOWS_HOST
@@ -163,13 +167,15 @@ ifndef MSYSCON
 endif
 endif
 ifdef WIN_PS_TOOLS
-   fixps = $(subst \,/,$(1))
-   psep = $(subst \\,/,$(subst /,\,$(1)))
-   PS := $(strip \)
+   psep := $(backslash)
+   slash_path = $(subst $(backslash),$(slash),$(1))
+   sys_path = $(subst $(backslash)$(backslash),$(slash),$(subst $(slash),$(backslash),$(1)))
+   quote_path = "$(call sys_path,$(call unescp_all,$(1)))"
 else
-   fixps = $(1)
-   PS := $(strip /)
-   psep = $(1)
+   psep := $(slash)
+   slash_path = $(1)
+   sys_path = $(1)
+   quote_path = $(1)
 endif
 
 # PREFIXES AND EXTENSIONS
@@ -215,12 +221,12 @@ endif
 endif
 ifdef WIN_SHELL_COMMANDS
    echo = $(if $(1),echo $(1))
-   touch = $(if $(1),@cmd /c "for %%a in ($(call psep,$(1))) do @(cd %%~pa && type nul >> %%~nxa && copy /by %%~nxa+,, >nul 2>&1 && cd %%cd%%)")
-   cpq = $(if $(1),@cmd /c "for %%a in ($(call psep,$(1))) do copy /by %%a $(call psep,$(2))" >nul 2>&1)
-   rmq = $(if $(1),-del /f /q $(call psep,$(1)) > nul 2>&1)
-   rmrq = $(if $(1),-rmdir /q /s $(call psep,$(1)) > nul 2>&1)
-   mkdirq = $(if $(1),-mkdir $(call psep,$(1)) > nul 2>&1)
-   rmdirq = $(if $(1),-rmdir /q $(call psep,$(1)) > nul 2>&1)
+   touch = $(if $(1),@cmd /c "for %%I in ($(call sys_path,$(1))) do @(cd %%~pI && type nul >> %%~nxI && copy /by %%~nxI+,, > nul 2>&1 && cd %%cd%%)")
+   cpq = $(if $(1),@cmd /c "for %%I in ($(call sys_path,$(1))) do copy /by %%I $(call sys_path,$(2))" > nul 2>&1)
+   rmq = $(if $(1),-del /f /q $(call sys_path,$(1)) > nul 2>&1)
+   rmrq = $(if $(1),-rmdir /q /s $(call sys_path,$(1)) > nul 2>&1)
+   mkdirq = $(if $(1),-mkdir $(call sys_path,$(1)) > nul 2>&1)
+   rmdirq = $(if $(1),-rmdir /q $(call sys_path,$(1)) > nul 2>&1)
 else
    echo = $(if $(1),echo "$(1)")
    touch = $(if $(1),touch $(1))
@@ -260,7 +266,7 @@ endif
 # COMMON LIBRARIES DETECTION
 ifdef WINDOWS_TARGET
  ifdef OPENSSL_CONF
-  _OPENSSL_CONF = $(call hidspace,$(call fixps,$(OPENSSL_CONF)))
+  _OPENSSL_CONF = $(call hidspace,$(call slash_path,$(OPENSSL_CONF)))
   OPENSSL_INCLUDE_DIR = $(call shwspace,$(subst /bin/openssl.cfg,/include,$(_OPENSSL_CONF)))
   OPENSSL_LIB_DIR = $(call shwspace,$(subst /bin/openssl.cfg,/lib,$(_OPENSSL_CONF)))
   OPENSSL_BIN_DIR = $(call shwspace,$(subst /bin/openssl.cfg,/bin,$(_OPENSSL_CONF)))
index 513a1cb..a4a2058 100644 (file)
@@ -14,10 +14,10 @@ export AS      = $(GCC_PREFIX)as
 export LD      = $(GCC_PREFIX)ld
 export AR      = $(GCC_PREFIX)ar
 export STRIP   = $(GCC_PREFIX)strip
-export ECP := $(call psep,$(EC_BINS)ecp$(HOST_E))
-export ECC := $(call psep,$(EC_BINS)ecc$(HOST_E))$(if $(CROSS_TARGET), -t $(TARGET_PLATFORM),)
-export ECS := $(call psep,$(EC_BINS)ecs$(HOST_E))$(if $(CROSS_TARGET), -t $(TARGET_PLATFORM),)$(if $(OUTPUT_POT), -outputpot,)
-export EAR := $(call psep,$(_CF_DIR)obj/$(HOST_PLATFORM)$(COMPILER_SUFFIX)$(DEBUG_SUFFIX)/bin/ear$(HOST_E))
+export ECP := $(call sys_path,$(EC_BINS)ecp$(HOST_E))
+export ECC := $(call sys_path,$(EC_BINS)ecc$(HOST_E))$(if $(CROSS_TARGET), -t $(TARGET_PLATFORM),)
+export ECS := $(call sys_path,$(EC_BINS)ecs$(HOST_E))$(if $(CROSS_TARGET), -t $(TARGET_PLATFORM),)$(if $(OUTPUT_POT), -outputpot,)
+export EAR := $(call sys_path,$(_CF_DIR)obj/$(HOST_PLATFORM)$(COMPILER_SUFFIX)$(DEBUG_SUFFIX)/bin/ear$(HOST_E))
 ifdef WINDOWS_TARGET
 WINDRES := $(GCC_PREFIX)windres
  ifdef ARCH
index 4300cc0..aeb287a 100644 (file)
@@ -198,10 +198,10 @@ ifndef NOSTRIP
 endif
 ifndef WINDOWS_TARGET
 ifdef EXECUTABLE_TARGET
-       @-$(call psep,$(UPX) $(UPXFLAGS) $(TARGET)) || $(call echo,upx not installed; not compressing.)
+       @-$(call sys_path,$(UPX) $(UPXFLAGS) $(TARGET)) || $(call echo,upx not installed; not compressing.)
 endif
 else
-       @-$(call psep,$(UPX) $(UPXFLAGS) $(TARGET)) || $(call echo,upx not installed; not compressing.)
+       @-$(call sys_path,$(UPX) $(UPXFLAGS) $(TARGET)) || $(call echo,upx not installed; not compressing.)
 endif
        $(EAR) aw$(EARFLAGS) $(TARGET) ../../ecere/res/vanilla/ecere/actions/folderNew.png ../../ecere/res/vanilla/ecere/actions/goUp.png "ecere/actions"
        $(EAR) aw$(EARFLAGS) $(TARGET) ../../ecere/res/vanilla/ecere/devices/computer.png ../../ecere/res/vanilla/ecere/devices/driveHardDisk.png ../../ecere/res/vanilla/ecere/devices/driveRemovableMedia.png ../../ecere/res/vanilla/ecere/devices/mediaFloppy.png ../../ecere/res/vanilla/ecere/devices/mediaOptical.png "ecere/devices"
index f7880ef..dfdd089 100644 (file)
@@ -38,7 +38,7 @@ include $(_CF_DIR)crossplatform.mk
 include $(_CF_DIR)default.cf
 
 ifdef PREFIXLIBDIR
-CFLAGS += -DDEB_HOST_MULTIARCH=\"$(PREFIXLIBDIR)\"
+CFLAGS += -DDEB_HOST_MULTIARCH=\"$(call escspace,$(PREFIXLIBDIR))\"
 endif
 
 # POST-INCLUDES VARIABLES
index 5335a33..14ce21c 100644 (file)
@@ -38,7 +38,7 @@ include $(_CF_DIR)crossplatform.mk
 include $(_CF_DIR)default.cf
 
 ifdef PREFIXLIBDIR
-CFLAGS += -DDEB_HOST_MULTIARCH=\"$(PREFIXLIBDIR)\"
+CFLAGS += -DDEB_HOST_MULTIARCH=\"$(call escspace,$(PREFIXLIBDIR))\"
 endif
 
 # POST-INCLUDES VARIABLES
index 1fcc1b9..1d8b776 100644 (file)
@@ -38,7 +38,7 @@ include $(_CF_DIR)crossplatform.mk
 include $(_CF_DIR)default.cf
 
 ifdef PREFIXLIBDIR
-CFLAGS += -DDEB_HOST_MULTIARCH=\"$(PREFIXLIBDIR)\"
+CFLAGS += -DDEB_HOST_MULTIARCH=\"$(call escspace,$(PREFIXLIBDIR))\"
 endif
 
 # POST-INCLUDES VARIABLES
index addfbab..fcd0c01 100644 (file)
@@ -818,65 +818,66 @@ public char * RSearchString(char * buffer, char * subStr, int maxLen, bool match
    return null;
 }
 
-public int Tokenize(char * string, int maxTokens, char* tokens[], bool escapeBackSlashes)
+//public define gnuMakeCharsNeedEscaping = "$%";
+//public define windowsFileNameCharsNotAllowed = "*/:<>?\\\"|";
+//public define linuxFileNameCharsNotAllowed = "/";
+//public define windowsFileNameCharsNeedEscaping = " !%&'()+,;=[]^`{}~"; // "#$-.@_" are ok
+//public define linuxFileNameCharsNeedEscaping = " !\"$&'()*:;<=>?[\\`{|"; // "#%+,-.@]^_}~" are ok
+
+// fix #139 to remove " = 2" and warnings for backward compatible calls to Tokenize using 'true' for the 'esc' argument;
+public enum BackSlashEscaping : bool { forArgsPassing = 2 };
+public int Tokenize(char * string, int maxTokens, char* tokens[], BackSlashEscaping esc)
 {
+#ifdef __WIN32__
+//define windowsFileNameCharsNeedEscaping = " !%&'()+,;=[]^`{}~"; // "#$-.@_" are ok
+   const char * escChars = " !\"%&'()+,;=[]^`{}~"; // windowsFileNameCharsNeedEscaping;
+   const char * escCharsQuoted = "\"";
+#else
+//define linuxFileNameCharsNeedEscaping = " !\"$&'()*:;<=>?[\\`{|"; // "#%+,-.@]^_}~" are ok
+   const char * escChars = " !\"$&'()*:;<=>?[\\`{|"; // linuxFileNameCharsNeedEscaping;
+   const char * escCharsQuoted = "\"()$";
+#endif
    int count = 0;
-   bool quoted = false;
-   byte * start = null;
-   bool escaped = false;
-   char * output = string;
-
-   for(; *string && count < maxTokens; string++, output++)
+   bool quoted = false, escaped = false;
+   char * start = null, * output = string;
+   char ch;
+   for(; (ch = *string) && count<maxTokens; string++, output++)
    {
+      bool wasEscaped = escaped;
       if(output != string)
-         *output = *string;
+         *output = ch;
       if(start)
       {
          if(escaped)
          {
             escaped = false;
             output--;
-
-            // ADDED THIS HERE...
-            if(output != string)
-               *output = *string;
+            *output = ch;
          }
-         else if(escapeBackSlashes && *string == '\\')
-            escaped = true;
-         else if(*string == '\"')
+         else if(ch == '\"')
          {
-            if(quoted)
-            {
-               *output = '\0';
-               quoted = false;
-            }
-            else
-            {
-               memmove(start + 1, start, string - (char *)start);
-               start++;
-            }
+            quoted ^= true;
+            output--;
          }
-         else if(*string == ' ' && !quoted)
+         else if(ch == ' ' && !quoted)
          {
             tokens[count++] = start;
             *output = '\0';
             start = null;
          }
       }
-      else if(*string != ' ')
+      else if(ch != ' ')
       {
-         if(*string == '\"')
+         if(ch == '\"')
          {
             quoted = true;
-            start = output + 1;
+            start = output+1;
          }
          else
-         {
             start = output;
-            if(*string == '\\' && escapeBackSlashes)
-               escaped = true;
-         }
       }
+      if(!wasEscaped && ch == '\\' && ( esc == true || (esc == forArgsPassing && strchr(quoted ? escCharsQuoted : escChars, *(string+1))) ))
+         escaped = true;
    }
    if(start && count < maxTokens)
    {
index f982fd9..2b1cd9c 100644 (file)
@@ -76,7 +76,8 @@ char * __ecereNameSpace__ecere__sys__UTF16toUTF8Buffer(uint16 * source, byte * d
 static char exeLocation[MAX_LOCATION];
 #endif
 
-int __ecereNameSpace__ecere__sys__Tokenize(char * string, int maxTokens, char* tokens[], bool escapeBackSlashes);
+#define forArgsPassing 2
+int __ecereNameSpace__ecere__sys__Tokenize(char * string, int maxTokens, char* tokens[], int esc);
 char * __ecereNameSpace__ecere__sys__RSearchString(char * buffer, char * subStr, int maxLen, bool matchCase, bool matchWord);
 char * __ecereNameSpace__ecere__sys__GetLastDirectory(char * string, char * output);
 char * __ecereNameSpace__ecere__sys__PathCat(char * string, char * addedPath);
@@ -366,7 +367,7 @@ void Instance_COM_Initialize(int argc, char ** argv, char ** parsedCommand, int
 #if defined(__WIN32__)
    *parsedCommand = UTF16toUTF8(GetCommandLineW());
    *argvPtr = eSystem_New0(sizeof(char *) * 512);
-   *argcPtr = Tokenize(*parsedCommand, 512,(void*)(char **)(*argvPtr), false);
+   *argcPtr = Tokenize(*parsedCommand, 512,(void*)(char **)(*argvPtr), forArgsPassing);
 #else
    *argcPtr = argc;
    *argvPtr = argv;
index 0efc24d..4cd1e8b 100644 (file)
@@ -37,7 +37,8 @@ typedef unsigned short uint16;
 typedef unsigned int uint;
 typedef int bool;
 
-int __ecereNameSpace__ecere__sys__Tokenize(char * string, int maxTokens, char * tokens[], unsigned int escapeBackSlashes);
+#define forArgsPassing 2
+int __ecereNameSpace__ecere__sys__Tokenize(char * string, int maxTokens, char * tokens[], unsigned int esc);
 char * __ecereNameSpace__ecere__sys__CopyString(char * string);
 void __ecereNameSpace__ecere__com__eSystem_Delete(void * memory);
 unsigned short * __ecereNameSpace__ecere__sys__UTF8toUTF16(char * source, int * wordCount);
index 0e9e984..a086733 100644 (file)
@@ -1,3 +1,11 @@
+#ifdef ECERE_STATIC
+public import static "ecere"
+public import static "ec"
+#else
+public import "ecere"
+public import "ec"
+#endif
+
 import "ide"
 import "process"
 import "debugFindCtx"
index 21fb1b2..cc298ba 100644 (file)
@@ -2823,21 +2823,15 @@ class IDEWorkSpace : Window
 
       for(c = 1; c<app.argc; c++)
       {
-         if(!strcmp(app.argv[c], "-t"))
-            openAsText = true;
-         else if(!strcmp(app.argv[c], "-no-parsing"))
-            ide.noParsing = true;
-         else if(!strcmp(app.argv[c], "-debug-start"))
-            debugStart = true;
-         else if(!strcmp(app.argv[c], "-debug-work-dir"))
-            debugWorkDir = true;
-         else if(!passThrough && !strcmp(app.argv[c], "-@"))
-            passThrough = true;
-         else if(passThrough)
+         if(passThrough)
          {
+            char * arg = app.argv[c];
+            char * buf = new char[strlen(arg)*2+1];
             if(ptArg++ > 0)
                passArgs.concat(" ");
-            passArgs.concat(app.argv[c]);
+            PassArg(buf, arg);
+            passArgs.concat(buf);
+            delete buf;
          }
          else if(debugWorkDir)
          {
@@ -2845,6 +2839,16 @@ class IDEWorkSpace : Window
             StripQuotes(passDebugWorkDir, passDebugWorkDir);
             debugWorkDir = false;
          }
+         else if(!strcmp(app.argv[c], "-t"))
+            openAsText = true;
+         else if(!strcmp(app.argv[c], "-no-parsing"))
+            ide.noParsing = true;
+         else if(!strcmp(app.argv[c], "-debug-start"))
+            debugStart = true;
+         else if(!strcmp(app.argv[c], "-debug-work-dir"))
+            debugWorkDir = true;
+         else if(!strcmp(app.argv[c], "-@"))
+            passThrough = true;
          else
          {
             char fullPath[MAX_LOCATION];
@@ -2905,49 +2909,8 @@ class IDEWorkSpace : Window
          }
       }
       if(passThrough && projectView && projectView.project && workspace)
-      {
-         char * fixSpacing = new char[Max(passArgs.size * 1.5, 32)];
-         {
-            int c, d = 0;
-            char j = 0;
-            char k = ' ';
-            char l = 0;
-            bool inQuote = false;
-            for(c=0; c<passArgs.size; c++)
-            {
-               l = passArgs[c];
-               if(inQuote && k != '\\' && l == ' ')
-               {
-                  fixSpacing[d++] = '\"';
-                  fixSpacing[d++] = ' ';
-                  inQuote = false;
-               }
-               else if(inQuote && l == '\0')
-               {
-                  fixSpacing[d++] = '\"';
-                  fixSpacing[d++] = '\0';
-                  inQuote = false;
-               }
-               else if(!inQuote && j != '\\' && k == ' ' && l != '-' && l != ' ')
-               {
-                  fixSpacing[d++] = '\"';
-                  fixSpacing[d++] = l;
-                  inQuote = true;
-               }
-               else if(k == '\\' && l == ' ')
-                  fixSpacing[d++] = ' ';
-               else if(k == '\\' && l == '\\')
-                  fixSpacing[d++] = '\\';
-               else if(l != '\\')
-                  fixSpacing[d++] = l;
-               j = k;
-               k = l;
-            }
-            fixSpacing[d] = '\0';
-         }
-         workspace.commandLineArgs = fixSpacing;
-      }
-      if(passDebugWorkDir)
+         workspace.commandLineArgs = passArgs;
+      if(passDebugWorkDir && projectView && projectView.project && workspace)
       {
          workspace.debugDir = passDebugWorkDir;
          delete passDebugWorkDir;
index 3da4201..ff08f85 100644 (file)
@@ -415,6 +415,7 @@ define stringInFileIncludedFrom = "In file included from ";
 define stringFrom =               "                 from ";
 
 // This function cannot accept same pointer for source and output
+// todo: rename ReplaceSpaces to EscapeSpaceAndSpecialChars or something
 void ReplaceSpaces(char * output, char * source)
 {
    int c, dc;
@@ -437,47 +438,81 @@ void ReplaceSpaces(char * output, char * source)
    output[dc] = '\0';
 }
 
-// This function cannot accept same pointer for source and output
-void ReplaceUnwantedMakeChars(char * output, char * source)
+// chars refused for project name: windowsFileNameCharsNotAllowed + " &,."
+
+//define gnuMakeCharsNeedEscaping = "$%";
+
+//define windowsFileNameCharsNotAllowed = "*/:<>?\\\"|";
+//define linuxFileNameCharsNotAllowed = "/";
+
+//define windowsFileNameCharsNeedEscaping = " !%&'()+,;=[]^`{}~"; // "#$-.@_" are ok
+//define linuxFileNameCharsNeedEscaping = " !\"$&'()*:;<=>?[\\`{|"; // "#%+,-.@]^_}~" are ok
+
+// NOTES: - this function should get only unescaped unix style paths
+//        - paths with literal $(somestring) in them are not supported
+//          my_$(messed_up)_path would likely become my__path
+void EscapeForMake(char * output, char * input, bool hideSpace, bool allowVars, bool allowDblQuote)
 {
-   char ch;
-   char * s = source, * d = output;
+   char ch, *i = input, *o = output;
    bool inVar = false;
-   while((ch = *s++))
+#ifdef _DEBUG
+   int len = strlen(input);
+   if(len && ((input[0] == '"' && input[len-1] == '"') || strchr(input, '\\') || strchr(input, 127) || (!allowDblQuote && strchr(input, '"'))))
+      PrintLn("Invalid input for EscapeForMake! -- ", input);
+#endif
+   while((ch = *i++))
    {
       if(ch == '(')
       {
-         if(s != source && *(s-1) == '$')
+         if(i-1 != input && *(i-2) == '$' && allowVars)
             inVar = true;
          else
-            *d++ = '\\';
+            *o++ = '\\';
       }
       else if(ch == ')')
       {
-         if(inVar == true)
+         if(inVar == true && allowVars)
             inVar = false;
          else
-            *d++ = '\\';
+            *o++ = '\\';
       }
-      else if(ch == '$' && *(s+1) != '(')
-         *d++ = '$';
+      else if(ch == '$' && *i != '(')
+         *o++ = '$';
+      else if(ch == '&')
+         *o++ = '\\';
+      else if(ch == '"')
+         *o++ = '\\';
       if(ch == ' ')
-         *d++ = 127;
+      {
+         if(hideSpace)
+            *o++ = 127;
+         else
+         {
+            *o++ = '\\';
+            *o++ = ch;
+         }
+      }
       else
-         *d++ = ch;
+         *o++ = ch;
    }
-   *d = '\0';
+   *o = '\0';
 }
 
-static void OutputNoSpace(File f, char * source)
+void EscapeForMakeToFile(File output, char * input, bool hideSpace, bool allowVars, bool allowDblQuote)
 {
-   char * output = new char[strlen(source)+1024];
-   ReplaceSpaces(output, source);
-   f.Puts(output);
-   delete output;
+   char * buf = new char[strlen(input)*2+1];
+   EscapeForMake(buf, input, hideSpace, allowVars, allowDblQuote);
+   output.Print(buf);
+   delete buf;
 }
 
-enum ListOutputMethod { inPlace, newLine, lineEach };
+void EscapeForMakeToDynString(DynamicString output, char * input, bool hideSpace, bool allowVars, bool allowDblQuote)
+{
+   char * buf = new char[strlen(input)*2+1];
+   EscapeForMake(buf, input, hideSpace, allowVars, allowDblQuote);
+   output.concat(buf);
+   delete buf;
+}
 
 int OutputFileList(File f, char * name, Array<String> list, Map<String, int> varStringLenDiffs, char * prefix)
 {
@@ -593,33 +628,35 @@ void OutputCleanActions(File f, char * name, int parts)
       f.Printf("\t$(call rmq,$(%s))\n", name);
 }
 
-void OutputListOption(File f, char * option, Array<String> list, ListOutputMethod method, bool noSpace, bool noDash)
+enum LineOutputMethod { inPlace, newLine, lineEach };
+enum StringOutputMethod { asIs, escape, escapePath};
+
+enum ToolchainFlag { any, _D, _I, _isystem, _Wl, _L/*, _Wl-rpath*/ };
+String flagNames[ToolchainFlag] = { "", "-D", "-I", "-isystem ", "-Wl,", "-Wl,--library-path="/*, "-Wl,-rpath "*/ };
+void OutputFlags(File f, ToolchainFlag flag, Array<String> list, LineOutputMethod lineMethod)
 {
    if(list.count)
    {
-      if(method == newLine)
+      if(lineMethod == newLine)
          f.Puts(" \\\n\t");
       for(item : list)
       {
-         if(method == lineEach)
+         if(lineMethod == lineEach)
             f.Puts(" \\\n\t");
-         f.Printf(" %s%s", noDash ? "" : "-", option);
-         if(noSpace)
-            OutputNoSpace(f, item);
+         f.Printf(" %s", flagNames[flag]);
+         if(flag != _D && flag != _Wl && flag != any)
+         {
+            char * tmp = new char[strlen(item)*2+1];
+            EscapeForMake(tmp, item, false, true, false);
+            f.Printf("$(call quote_path,%s)", tmp);
+            delete tmp;
+         }
          else
-            f.Printf("%s", item);
+            EscapeForMakeToFile(f, item, false, true, true);
       }
    }
 }
 
-void StringNoSpaceToDynamicString(DynamicString s, char * path)
-{
-   char * output = new char[strlen(path)+1024];
-   ReplaceSpaces(output, path);
-   s.concat(output);
-   delete output;
-}
-
 static void OutputLibraries(File f, Array<String> libraries)
 {
    for(item : libraries)
@@ -645,7 +682,7 @@ static void OutputLibraries(File f, Array<String> libraries)
          f.Puts(" \\\n\t$(call _L,");
          usedFunction = true;
       }
-      OutputNoSpace(f, s);
+      EscapeForMakeToFile(f, s, false, false, false);
       if(usedFunction)
          f.Puts(")");
    }
@@ -1630,7 +1667,7 @@ private:
                         precompiling = true;
                      }
                      // Changed escapeBackSlashes here to handle paths with spaces
-                     Tokenize(module, 1, tokens, true); // false);
+                     Tokenize(module, 1, tokens, (BackSlashEscaping)true); // fix #139
                      GetLastDirectory(module, moduleName);
                      ide.outputView.buildBox.Logf("%s\n", moduleName);
                   }
@@ -1660,7 +1697,7 @@ private:
                   if(module)
                   {
                      byte * tokens[1];
-                     Tokenize(module, 1, tokens, true);
+                     Tokenize(module, 1, tokens, (BackSlashEscaping)true); // fix #139
                      GetLastDirectory(module, moduleName);
                      ide.outputView.buildBox.Logf("%s\n", moduleName);
                   }
@@ -2297,8 +2334,6 @@ private:
       fileName[0] = '\0';
       if(targetType == staticLibrary || targetType == sharedLibrary)
          strcat(fileName, "$(LP)");
-      // !!! ReplaceSpaces must be done after all PathCat calls !!!
-      // ReplaceSpaces(s, GetTargetFileName(config));
       strcat(fileName, GetTargetFileName(config));
       switch(targetType)
       {
@@ -2483,21 +2518,21 @@ private:
             if(compiler.includeDirs && compiler.includeDirs.count)
             {
                f.Puts("\nCFLAGS +=");
-               OutputListOption(f, gccCompiler ? "isystem " : "I", compiler.includeDirs, lineEach, true, false);
+               OutputFlags(f, gccCompiler ? _isystem : _I, compiler.includeDirs, lineEach);
                f.Puts("\n");
             }
             if(compiler.prepDirectives && compiler.prepDirectives.count)
             {
                f.Puts("\nCFLAGS +=");
-               OutputListOption(f, "D", compiler.prepDirectives, inPlace, true, false);
+               OutputFlags(f, _D, compiler.prepDirectives, inPlace);
                f.Puts("\n");
             }
             if(compiler.libraryDirs && compiler.libraryDirs.count)
             {
                f.Puts("\nLDFLAGS +=");
-               OutputListOption(f, "L", compiler.libraryDirs, lineEach, true, false);
+               OutputFlags(f, _L, compiler.libraryDirs, lineEach);
                // We would need a bool option to know whether we want to add to rpath as well...
-               // OutputListOption(f, "Wl,-rpath ", compiler.libraryDirs, lineEach, true, false);
+               // OutputFlags(f, _Wl-rpath, compiler.libraryDirs, lineEach);
                f.Puts("\n");
             }
             if(compiler.excludeLibs && compiler.excludeLibs.count)
@@ -2512,13 +2547,13 @@ private:
             if(compiler.compilerFlags && compiler.compilerFlags.count)
             {
                f.Puts("\nCFLAGS +=");
-               OutputListOption(f, "", compiler.compilerFlags, inPlace, true, true);
+               OutputFlags(f, any, compiler.compilerFlags, inPlace);
                f.Puts("\n");
             }
             if(compiler.linkerFlags && compiler.linkerFlags.count)
             {
                f.Puts("\nLDFLAGS +=");
-               OutputListOption(f, "Wl,", compiler.linkerFlags, inPlace, true, false);
+               OutputFlags(f, _Wl, compiler.linkerFlags, inPlace);
                f.Puts("\n");
             }
             f.Puts("\n");
@@ -2979,9 +3014,9 @@ private:
                      {
                         f.Puts("OFLAGS +=");
                         if(configPlatformOptions && configPlatformOptions.options.libraryDirs)
-                           OutputListOption(f, "L", configPlatformOptions.options.libraryDirs, lineEach, true, false);
+                           OutputFlags(f, _L, configPlatformOptions.options.libraryDirs, lineEach);
                         if(projectPlatformOptions && projectPlatformOptions.options.libraryDirs)
-                           OutputListOption(f, "L", projectPlatformOptions.options.libraryDirs, lineEach, true, false);
+                           OutputFlags(f, _L, projectPlatformOptions.options.libraryDirs, lineEach);
                         f.Puts("\n");
                      }
 
@@ -3094,9 +3129,9 @@ private:
             f.Puts("ifndef STATIC_LIBRARY_TARGET\n");
             f.Puts("OFLAGS +=");
             if(config && config.options && config.options.libraryDirs)
-               OutputListOption(f, "L", config.options.libraryDirs, lineEach, true, false);
+               OutputFlags(f, _L, config.options.libraryDirs, lineEach);
             if(options && options.libraryDirs)
-               OutputListOption(f, "L", options.libraryDirs, lineEach, true, false);
+               OutputFlags(f, _L, options.libraryDirs, lineEach);
             f.Puts("\n");
             f.Puts("endif\n");
             f.Puts("\n");
index 7d86f8f..7009792 100644 (file)
@@ -1452,7 +1452,7 @@ private:
                strcpy(tempPath, path);
                PathCatSlash(tempPath, name);
             }
-            ReplaceUnwantedMakeChars(modulePath, tempPath);
+            EscapeForMake(modulePath, tempPath, true, true, false);
             sprintf(s, "%s%s%s%s", ts.a, useRes ? "$(RES)" : "", modulePath, ts.b);
             items.Add(CopyString(s));
          }
@@ -1463,8 +1463,8 @@ private:
                   !strcmpi(extension, "m") || !strcmpi(extension, "mm"))
             {
                char modulePath[MAX_LOCATION];
-               ReplaceUnwantedMakeChars(modulePath, path);
-               ReplaceUnwantedMakeChars(moduleName, name);
+               EscapeForMake(modulePath, path, true, true, false);
+               EscapeForMake(moduleName, name, true, true, false);
                sprintf(s, "%s%s%s%s%s", ts.a, modulePath, path[0] ? SEPS : "", moduleName, ts.b);
                items.Add(CopyString(s));
             }
@@ -1474,8 +1474,8 @@ private:
             if(!strcmpi(extension, "ec"))
             {
                char modulePath[MAX_LOCATION];
-               ReplaceUnwantedMakeChars(modulePath, path);
-               ReplaceUnwantedMakeChars(moduleName, name);
+               EscapeForMake(modulePath, path, true, true, false);
+               EscapeForMake(moduleName, name, true, true, false);
                sprintf(s, "%s%s%s%s%s", ts.a, modulePath, path[0] ? SEPS : "", moduleName, ts.b);
                items.Add(CopyString(s));
                count++;
@@ -1486,8 +1486,8 @@ private:
             if(!strcmpi(extension, "rc"))
             {
                char modulePath[MAX_LOCATION];
-               ReplaceUnwantedMakeChars(modulePath, path);
-               ReplaceUnwantedMakeChars(moduleName, name);
+               EscapeForMake(modulePath, path, true, true, false);
+               EscapeForMake(moduleName, name, true, true, false);
                sprintf(s, "%s%s%s%s%s", ts.a, modulePath, path[0] ? SEPS : "", moduleName, ts.b);
                items.Add(CopyString(s));
                count++;
@@ -1502,7 +1502,7 @@ private:
                bool collision;
                NameCollisionInfo info;
                count++;
-               ReplaceUnwantedMakeChars(moduleName, name);
+               EscapeForMake(moduleName, name, true, true, false);
                StripExtension(moduleName);
                info = namesInfo[moduleName];
                collision = info ? info.IsExtensionColliding(extension) : false;
@@ -2129,7 +2129,7 @@ private:
                   strcpy(tempPath, child.path);
                   PathCatSlash(tempPath, child.name);
                }
-               ReplaceUnwantedMakeChars(resPath, tempPath);
+               EscapeForMake(resPath, tempPath, true, true, false);
                if(strchr(tempPath, ' '))
                   quotes = "\"";
                else
@@ -3093,9 +3093,9 @@ static void GenCFlagsFromProjectOptions(ProjectOptions options, bool prjWithEcFi
    }
 
    if(options && options.preprocessorDefinitions)
-      ListOptionToDynamicString("D", options.preprocessorDefinitions, false, lineEach, "\t\t\t", false, s);
+      ListOptionToDynamicString(s, _D, options.preprocessorDefinitions, false, lineEach, "\t\t\t");
    if(options && options.includeDirs)
-      ListOptionToDynamicString("I", options.includeDirs, true, lineEach, "\t\t\t", true, s);
+      ListOptionToDynamicString(s, _I, options.includeDirs, true, lineEach, "\t\t\t");
 }
 
 static void GenECFlagsFromProjectOptions(ProjectOptions options, bool prjWithEcFiles, DynamicString s)
@@ -3110,15 +3110,15 @@ static void GenECFlagsFromProjectOptions(ProjectOptions options, bool prjWithEcF
       s.concatf(" -defaultns %s", options.defaultNameSpace);
 }
 
-static void ListOptionToDynamicString(char * option, Array<String> list, bool prioritize,
-      ListOutputMethod method, String newLineStart, bool noSpace, DynamicString s)
+static void ListOptionToDynamicString(DynamicString output, ToolchainFlag flag, Array<String> list, bool prioritize,
+      LineOutputMethod lineMethod, String newLineStart)
 {
    if(list.count)
    {
-      if(method == newLine)
+      if(lineMethod == newLine)
       {
-         s.concat(" \\\n");
-         s.concat(newLineStart);
+         output.concat(" \\\n");
+         output.concat(newLineStart);
       }
       if(prioritize)
       {
@@ -3129,17 +3129,14 @@ static void ListOptionToDynamicString(char * option, Array<String> list, bool pr
          for(mn = sortedList.root.minimum; mn; mn = mn.next)
          {
             char * start = strstr(mn.key, "\n");
-            if(method == lineEach)
+            if(lineMethod == lineEach)
             {
-               s.concat(" \\\n");
-               s.concat(newLineStart);
+               output.concat(" \\\n");
+               output.concat(newLineStart);
             }
-            s.concat(" -");
-            s.concat(option);
-            if(noSpace)
-               StringNoSpaceToDynamicString(s, start ? start+1 : mn.key);
-            else
-               s.concat(start ? start+1 : mn.key);
+            output.concat(" ");
+            output.concat(flagNames[flag]);
+            EscapeForMakeToDynString(output, start ? start+1 : mn.key, false, true, flag == _D);
          }
          delete sortedList;
       }
@@ -3147,17 +3144,14 @@ static void ListOptionToDynamicString(char * option, Array<String> list, bool pr
       {
          for(item : list)
          {
-            if(method == lineEach)
+            if(lineMethod == lineEach)
             {
-               s.concat(" \\\n");
-               s.concat(newLineStart);
+               output.concat(" \\\n");
+               output.concat(newLineStart);
             }
-            s.concat(" -");
-            s.concat(option);
-            if(noSpace)
-               StringNoSpaceToDynamicString(s, item);
-            else
-               s.concat(item);
+            output.concat(" ");
+            output.concat(flagNames[flag]);
+            EscapeForMakeToDynString(output, item, false, true, flag == _D);
          }
       }
    }