wip II
[sdk] / ecere / src / com / String.ec
index 0ce03d4..a7314b2 100644 (file)
@@ -193,32 +193,37 @@ public char * PathCatSlash(char * string, char * addedPath)
    bool modified = false;
    if(addedPath)
    {
-      char fileName[MAX_LOCATION] = "", archiveName[MAX_LOCATION] = "", * file;
+      char fileName[MAX_LOCATION] = "", archiveName[MAX_LOCATION] = "", * file = null;
       int c = 0;
       bool isURL = false;
+      bool isArchive = SplitArchivePath(string, archiveName, &file);
       char * urlFileName;
+      char * protocolSymbol;
 
-      if(SplitArchivePath(string, archiveName, &file))
-         strcpy(fileName, file);
-      else
-      {
-         strcpy(fileName, string);
-      }
+      strcpy(fileName, isArchive ? file : string);
 
-      if(strstr(string, "http://") == string)
+      if(!isArchive) // TODO: Support for PathCat'ing .. outside of archive
       {
-         char * slash = strstr(fileName + 7, "/");
-         isURL = true;
-         if(slash)
-            urlFileName = slash;
-         else
-            urlFileName = fileName + strlen(fileName);
+         protocolSymbol = (fileName[0] && fileName[0] != '.' && fileName[0] != '/' && fileName[0] != '\\' && fileName[1] != ':') ? strstr(fileName, "://") : null;
+         if(protocolSymbol)
+         {
+            char * slash = strstr(protocolSymbol + 3, "/");
+            isURL = true;
+            if(slash)
+               urlFileName = slash;
+            else
+               urlFileName = fileName + strlen(fileName);
+         }
       }
-      if(strstr(addedPath, "http://") == addedPath)
+
+      protocolSymbol = (addedPath[0] && addedPath[0] != '.' && addedPath[0] != '/' && addedPath[0] != '\\' && addedPath[1] != ':') ? strstr(addedPath, "://") : null;
+      if(protocolSymbol)
       {
-         strcpy(fileName, "http://");
+         int len = protocolSymbol - addedPath + 3;
+         memcpy(fileName, addedPath, len);
+         fileName[len] = 0;
          isURL = true;
-         c = 7;
+         c = len;
       }
       else if(GetRuntimePlatform() == win32)
       {
@@ -407,32 +412,37 @@ public char * PathCat(char * string, char * addedPath)
    bool modified = false;
    if(addedPath)
    {
-      char fileName[MAX_LOCATION] = "", archiveName[MAX_LOCATION] = "", * file;
+      char fileName[MAX_LOCATION] = "", archiveName[MAX_LOCATION] = "", * file = null;
       int c = 0;
       bool isURL = false;
+      bool isArchive = SplitArchivePath(string, archiveName, &file);
       char * urlFileName;
+      char * protocolSymbol;
 
-      if(SplitArchivePath(string, archiveName, &file))
-         strcpy(fileName, file);
-      else
-      {
-         strcpy(fileName, string);
-      }
+      strcpy(fileName, isArchive ? file : string);
 
-      if(strstr(string, "http://") == string)
+      if(!isArchive) // TODO: Support for PathCat'ing .. outside of archive
       {
-         char * slash = strstr(fileName + 7, "/");
-         isURL = true;
-         if(slash)
-            urlFileName = slash;
-         else
-            urlFileName = fileName + strlen(fileName);
+         protocolSymbol = (fileName[0] && fileName[0] != '.' && fileName[0] != '/' && fileName[0] != '\\' && fileName[1] != ':') ? strstr(fileName, "://") : null;
+         if(protocolSymbol)
+         {
+            char * slash = strstr(protocolSymbol + 3, "/");
+            isURL = true;
+            if(slash)
+               urlFileName = slash;
+            else
+               urlFileName = fileName + strlen(fileName);
+         }
       }
-      if(strstr(addedPath, "http://") == addedPath)
+
+      protocolSymbol = (addedPath[0] && addedPath[0] != '.' && addedPath[0] != '/' && addedPath[0] != '\\' && addedPath[1] != ':') ? strstr(addedPath, "://") : null;
+      if(protocolSymbol)
       {
-         strcpy(fileName, "http://");
+         int len = protocolSymbol - addedPath + 3;
+         memcpy(fileName, addedPath, len);
+         fileName[len] = 0;
          isURL = true;
-         c = 7;
+         c = len;
       }
       else if(runtimePlatform == win32)
       {
@@ -623,6 +633,7 @@ public char * PathCat(char * string, char * addedPath)
 
 public char * MakePathRelative(char * path, char * to, char * destination)
 {
+   int len;
    // Don't process empty paths
    if(!path[0])
       memmove(destination, path, strlen(path)+1);
@@ -659,6 +670,9 @@ public char * MakePathRelative(char * path, char * to, char * destination)
          PathCat(destination, pathPart);
       }
    }
+   len = strlen(destination);
+   if(len>1 && (destination[len-1] == '/' || destination[len-1] == '\\'))
+      destination[--len] = '\0';
    return destination;
 }
 
@@ -814,65 +828,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)
    {