- 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.
endif
export CPPFLAGS
-CPPFLAGS += -DDEB_HOST_MULTIARCH=\"$(PREFIXLIBDIR)\"
+CPPFLAGS += -DDEB_HOST_MULTIARCH=\"$(call escspace,$(PREFIXLIBDIR))\"
DESTLIBDIR := $(DESTDIR)$(PREFIXLIBDIR)
ifdef SLIBDIR
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
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
{
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"))
{
{
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;
{
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"))
{
{
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;
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;
# 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
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
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))
# 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)))
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
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"
include $(_CF_DIR)default.cf
ifdef PREFIXLIBDIR
-CFLAGS += -DDEB_HOST_MULTIARCH=\"$(PREFIXLIBDIR)\"
+CFLAGS += -DDEB_HOST_MULTIARCH=\"$(call escspace,$(PREFIXLIBDIR))\"
endif
# POST-INCLUDES VARIABLES
include $(_CF_DIR)default.cf
ifdef PREFIXLIBDIR
-CFLAGS += -DDEB_HOST_MULTIARCH=\"$(PREFIXLIBDIR)\"
+CFLAGS += -DDEB_HOST_MULTIARCH=\"$(call escspace,$(PREFIXLIBDIR))\"
endif
# POST-INCLUDES VARIABLES
include $(_CF_DIR)default.cf
ifdef PREFIXLIBDIR
-CFLAGS += -DDEB_HOST_MULTIARCH=\"$(PREFIXLIBDIR)\"
+CFLAGS += -DDEB_HOST_MULTIARCH=\"$(call escspace,$(PREFIXLIBDIR))\"
endif
# POST-INCLUDES VARIABLES
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)
{
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);
#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;
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);
+#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"
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)
{
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];
}
}
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;
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;
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)
{
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)
f.Puts(" \\\n\t$(call _L,");
usedFunction = true;
}
- OutputNoSpace(f, s);
+ EscapeForMakeToFile(f, s, false, false, false);
if(usedFunction)
f.Puts(")");
}
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);
}
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);
}
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)
{
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)
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");
{
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");
}
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");
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));
}
!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));
}
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++;
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++;
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;
strcpy(tempPath, child.path);
PathCatSlash(tempPath, child.name);
}
- ReplaceUnwantedMakeChars(resPath, tempPath);
+ EscapeForMake(resPath, tempPath, true, true, false);
if(strchr(tempPath, ' '))
quotes = "\"";
else
}
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)
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)
{
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;
}
{
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);
}
}
}