ecere: Added ChangeChars(); eda/ers: ; Avoiding bad filenames
[sdk] / ecere / src / com / String.ec
index df057b4..d7b7258 100644 (file)
@@ -1,6 +1,8 @@
 namespace sys;
 
+#define set _set
 #define uint _uint
+#define strlen _strlen
 
 default:
 
@@ -9,13 +11,17 @@ default:
 #if !defined(ECERE_BOOTSTRAP) // quick fix for now
 #if defined(__WIN32__)
 #define WIN32_LEAN_AND_MEAN
+#define String _String
 #include <windows.h>
+#undef String
 #else
 #include <unistd.h>
 #endif
 #endif
 
 #undef uint
+#undef set
+#undef strlen
 private:
 
 import "instance"
@@ -24,10 +30,10 @@ default extern Platform runtimePlatform;
 
 #define IS_ALUNDER(ch) ((ch) == '_' || isalnum((ch)))
 
-public define DIR_SEP   = (GetRuntimePlatform() == win32) ? '\\' : '/';
-public define DIR_SEPS  = (GetRuntimePlatform() == win32) ? "\\" : "/";
+public define DIR_SEP   = (__runtimePlatform == win32) ? '\\' : '/';
+public define DIR_SEPS  = (__runtimePlatform == win32) ? "\\" : "/";
 
-// Maximum length for a vsprintf string
+// Maximum length for a vsnprintf string
 public define MAX_F_STRING = 1025;
 
 // Maximum length for a directories and filenames strings
@@ -37,7 +43,7 @@ public define MAX_DIRECTORY = 534; // 8 levels + 8 separators + \0
 public define MAX_LOCATION = 797; // directory + filename + separator + \0
 
 // --- File related String functions ---
-public char * GetExtension(char * string, char * output)
+public char * GetExtension(const char * string, char * output)
 {
    int c;
    int len = strlen(string);
@@ -57,7 +63,7 @@ public char * GetExtension(char * string, char * output)
    return output;
 }
 
-public char * StripLastDirectory(char * string, char * output)
+public char * StripLastDirectory(const char * string, char * output)
 {
    int c;
    if(runtimePlatform == win32 && !strcmp(string, "\\\\"))
@@ -79,7 +85,7 @@ public char * StripLastDirectory(char * string, char * output)
 
       if((runtimePlatform == win32) ? (c >= 0) : (c > 0))
       {
-         strncpy(output, string, c);
+         memmove(output, string, c);
          if(c > 0)
          {
             if(runtimePlatform == win32 && c == 1 && output[0] == '\\' && output[1] == '\\')
@@ -122,14 +128,14 @@ public char * SplitDirectory(const char * string, char * part, char * rest)
       for(;(ch = string[c]) && (ch != '/' && ch != '\\'); c++)
       {
          if(len < MAX_FILENAME)
-            part[len++] = ch;  
+            part[len++] = ch;
       }
    }
 
    for(;(ch = string[c]) && (ch == '/' || ch == '\\'); c++);
-   strcpy(rest, string + c);
+   memmove(rest, string + c, strlen(string + c) + 1);
    for(c = strlen(rest); c >= 0; c--)
-      if(ch != '/' && ch != '\\') 
+      if(ch != '/' && ch != '\\')
          break;
    if(c > 0)
       rest[c] = '\0';
@@ -138,7 +144,7 @@ public char * SplitDirectory(const char * string, char * part, char * rest)
    return rest;
 }
 
-public char * GetLastDirectory(char * string, char * output)
+public char * GetLastDirectory(const char * string, char * output)
 {
    int c;
    int len = string ? strlen(string) : 0;
@@ -148,17 +154,17 @@ public char * GetLastDirectory(char * string, char * output)
 
    c++;
    if(c >= 0)
-      strcpy(output, string+c);
+      memmove(output, string+c, strlen(string+c)+1);
    else
       output[0] = '\0';
 
    len = strlen(output);
    if(len > 1 && (output[len-1] == '\\' || output[len-1] == '/'))
-      output[len-1] = '\0';   
+      output[len-1] = '\0';
    return output;
 }
 
-public bool SplitArchivePath(char * fileName, char * archiveName, char ** archiveFile)
+public bool SplitArchivePath(const char * fileName, char * archiveName, const char * * archiveFile)
 {
    // Support Archives
    if(fileName[0] == '<')
@@ -182,39 +188,45 @@ public bool SplitArchivePath(char * fileName, char * archiveName, char ** archiv
    return false;
 }
 
-public char * PathCatSlash(char * string, char * addedPath)
+public char * PathCatSlash(char * string, const char * addedPath)
 {
    bool modified = false;
    if(addedPath)
    {
-      char fileName[MAX_LOCATION] = "", archiveName[MAX_LOCATION] = "", * file;
+      char fileName[MAX_LOCATION] = "", archiveName[MAX_LOCATION] = "";
+      const char * file = null;
       int c = 0;
       bool isURL = false;
-      char * urlFileName;
+      bool isArchive = SplitArchivePath(string, archiveName, &file);
+      char * urlFileName = null;
+      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)
+      else if(__runtimePlatform == win32)
       {
          if(addedPath[0] && addedPath[1] == ':' && addedPath[0] != '<')
          {
@@ -245,7 +257,7 @@ public char * PathCatSlash(char * string, char * addedPath)
       }
       else if(!modified && (addedPath[0] == '\\' || addedPath[0] == '/'))
       {
-         if(GetRuntimePlatform() == win32)
+         if(__runtimePlatform == win32)
          {
             // Entire Computer
             if(addedPath[0] == '/' && !addedPath[1])
@@ -285,7 +297,7 @@ public char * PathCatSlash(char * string, char * addedPath)
          int len = 0;
          char ch;
          int count;
-      
+
          for(;(ch = addedPath[c]) && (ch == '/' || ch == '\\'); c++);
          for(;(ch = addedPath[c]) && (ch != '/' && ch != '\\'); c++)
          {
@@ -294,7 +306,7 @@ public char * PathCatSlash(char * string, char * addedPath)
                break;
             }
             if(len < MAX_FILENAME)
-               directory[len++] = ch;  
+               directory[len++] = ch;
          }
          directory[len] = '\0';
 
@@ -314,9 +326,9 @@ public char * PathCatSlash(char * string, char * addedPath)
                if(strLen > -1)
                {
                   // Go back one directory
-                  for(;(ch = fileName[strLen]) && strLen > -1 && (ch == '/' || ch == '\\'); strLen--);
-                  for(;(ch = fileName[strLen]) && strLen > -1 && (ch != '/' && ch != '\\' && ch != ':'); strLen--);
-                  for(;(ch = fileName[strLen]) && strLen > -1 && (ch == '/' || ch == '\\'); strLen--);
+                  for(;strLen > -1 && (ch = fileName[strLen]) && (ch == '/' || ch == '\\'); strLen--);
+                  for(;strLen > -1 && (ch = fileName[strLen]) && (ch != '/' && ch != '\\' && ch != ':'); strLen--);
+                  for(;strLen > -1 && (ch = fileName[strLen]) && (ch == '/' || ch == '\\'); strLen--);
 
                   if(isURL)
                   {
@@ -329,7 +341,7 @@ public char * PathCatSlash(char * string, char * addedPath)
                   }
                   else
                   {
-                     if(GetRuntimePlatform() == win32)
+                     if(__runtimePlatform == win32)
                      {
                         if(!strLen && fileName[0] == '\\' && fileName[1] == '\\')
                         {
@@ -396,37 +408,43 @@ public char * PathCatSlash(char * string, char * addedPath)
    return modified ? string : null;
 }
 
-public char * PathCat(char * string, char * addedPath)
+public char * PathCat(char * string, const char * addedPath)
 {
    bool modified = false;
    if(addedPath)
    {
-      char fileName[MAX_LOCATION] = "", archiveName[MAX_LOCATION] = "", * file;
+      char fileName[MAX_LOCATION] = "", archiveName[MAX_LOCATION] = "";
+      const char * file = null;
       int c = 0;
       bool isURL = false;
-      char * urlFileName;
+      bool isArchive = SplitArchivePath(string, archiveName, &file);
+      char * urlFileName = null;
+      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)
       {
@@ -497,7 +515,7 @@ public char * PathCat(char * string, char * addedPath)
          int len = 0;
          char ch;
          int count;
-      
+
          for(;(ch = addedPath[c]) && (ch == '/' || ch == '\\'); c++);
          for(;(ch = addedPath[c]) && (ch != '/' && ch != '\\'); c++)
          {
@@ -506,7 +524,7 @@ public char * PathCat(char * string, char * addedPath)
                break;
             }
             if(len < MAX_FILENAME)
-               directory[len++] = ch;  
+               directory[len++] = ch;
          }
          directory[len] = '\0';
 
@@ -528,9 +546,9 @@ public char * PathCat(char * string, char * addedPath)
                   bool separator = false;
 
                   // Go back one directory
-                  for(;(ch = fileName[strLen]) && strLen > -1 && (ch == '/' || ch == '\\'); strLen--);
-                  for(;(ch = fileName[strLen]) && strLen > -1 && (ch != '/' && ch != '\\' && ch != ':'); strLen--);
-                  for(;(ch = fileName[strLen]) && strLen > -1 && (ch == '/' || ch == '\\'); strLen--) separator = true;
+                  for(;strLen > -1 && (ch = fileName[strLen]) && (ch == '/' || ch == '\\'); strLen--);
+                  for(;strLen > -1 && (ch = fileName[strLen]) && (ch != '/' && ch != '\\' && ch != ':'); strLen--);
+                  for(;strLen > -1 && (ch = fileName[strLen]) && (ch == '/' || ch == '\\'); strLen--) separator = true;
 
                   if(isURL)
                   {
@@ -615,11 +633,12 @@ public char * PathCat(char * string, char * addedPath)
    return modified ? string : null;
 }
 
-public char * MakePathRelative(char * path, char * to, char * destination)
+public char * MakePathRelative(const char * path, const char * to, char * destination)
 {
+   int len;
    // Don't process empty paths
    if(!path[0])
-      strcpy(destination, path);
+      memmove(destination, path, strlen(path)+1);
    else
    {
       // TOFIX: DANGER OF OVERFLOW HERE
@@ -633,7 +652,7 @@ public char * MakePathRelative(char * path, char * to, char * destination)
       destination[0] = '\0';
       for(;toRest[0];)
       {
-         SplitDirectory(toRest, toPart, toRest);      
+         SplitDirectory(toRest, toPart, toRest);
          if(!different)
             SplitDirectory(pathRest, pathPart, pathRest);
 
@@ -653,6 +672,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;
 }
 
@@ -670,9 +692,10 @@ public bool StripExtension(char * string)
    return false;
 }
 
-public char * ChangeExtension(char * string, char * ext, char * output)
+public char * ChangeExtension(const char * string, const char * ext, char * output)
 {
-   strcpy(output, string);
+   if(string != output)
+      strcpy(output, string);
    StripExtension(output);
    if(ext[0])
       strcat(output, ".");
@@ -738,15 +761,15 @@ public void PrintBigSize(char * string, double size, int prec)
       sprintf(string, "%.0f B", size);
 }
 
-public char * SearchString(char * buffer, int start, char * subStr, bool matchCase, bool matchWord)
+public char * SearchString(const char * buffer, int start, const char * subStr, bool matchCase, bool matchWord)
 {
    if(buffer && subStr)
    {
-      char * ptr;
-      char * strBuffer = buffer + start;
+      const char * ptr;
+      const char * strBuffer = buffer + start;
       int subLen = strlen(subStr);
       char beforeChar = start ? *(strBuffer-1) : 0;
-      int (*strcompare)(const char *, const char *, unsigned int) = matchCase ? strncmp : strnicmp;
+      int (*strcompare)(const char *, const char *, uintsize) = matchCase ? strncmp : strnicmp;
 
       for(ptr = strBuffer; *ptr; ptr++)
       {
@@ -754,52 +777,52 @@ public char * SearchString(char * buffer, int start, char * subStr, bool matchCa
          {
             if(matchWord)
             {
-               if(!strcompare(ptr,subStr,subLen) && 
+               if(!strcompare(ptr,subStr,subLen) &&
                   /*
-                  !IS_ALUNDER(ptr[subLen]) && 
+                  !IS_ALUNDER(ptr[subLen]) &&
                   !IS_ALUNDER(beforeChar))
                   */
-                  (!IS_ALUNDER(subStr[subLen-1]) || !IS_ALUNDER(ptr[subLen])) && 
+                  (!IS_ALUNDER(subStr[subLen-1]) || !IS_ALUNDER(ptr[subLen])) &&
                   (!IS_ALUNDER(subStr[0]) || !IS_ALUNDER(beforeChar)))
-                  return ptr;
+                  return (char *)ptr;
             }
             else
             {
                if(!strcompare(ptr,subStr,subLen))
-                  return ptr;
+                  return (char *)ptr;
             }
          }
-         beforeChar = ptr[0];  
+         beforeChar = ptr[0];
       }
    }
    return null;
 }
 
-public char * RSearchString(char * buffer, char * subStr, int maxLen, bool matchCase, bool matchWord)
+public char * RSearchString(const char * buffer, const char * subStr, int maxLen, bool matchCase, bool matchWord)
 {
    if(buffer && subStr)
    {
       int subLen = strlen(subStr);
-      char * ptr1 = buffer + maxLen - subLen;
-      char * ptr2 = buffer + maxLen - subLen - 1;
-      int (*strcompare)(const char *, const char *, unsigned int) = matchCase ? strncmp : strnicmp;
+      const char * ptr1 = buffer + maxLen - subLen;
+      const char * ptr2 = buffer + maxLen - subLen - 1;
+      int (*strcompare)(const char *, const char *, uintsize) = matchCase ? strncmp : strnicmp;
       for(; ptr1 >=buffer; ptr1--, ptr2--)
       {
          if(tolower(*subStr) == tolower(*ptr1))
          {
             if(matchWord)
             {
-               if(!strcompare(ptr1,subStr,subLen) && 
+               if(!strcompare(ptr1,subStr,subLen) &&
                   //!IS_ALUNDER(ptr1[subLen]) && !IS_ALUNDER(*ptr2))
-                  (!IS_ALUNDER(subStr[subLen-1]) || !IS_ALUNDER(ptr1[subLen])) && 
+                  (!IS_ALUNDER(subStr[subLen-1]) || !IS_ALUNDER(ptr1[subLen])) &&
                   (!IS_ALUNDER(subStr[0]) || !IS_ALUNDER(*ptr2)))
 
-                 return ptr1;
+                 return (char *)ptr1;
             }
             else
             {
                if(!strcompare(ptr1,subStr,subLen))
-                  return ptr1;
+                  return (char *)ptr1;
             }
          }
       }
@@ -807,65 +830,71 @@ 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)
 {
+   const char * escChars, * escCharsQuoted;
    int count = 0;
-   bool quoted = false;
-   byte * start = null;
-   bool escaped = false;
-   char * output = string;
+   bool quoted = false, escaped = false;
+   char * start = null, * output = string;
+   char ch;
+   if(__runtimePlatform == win32)
+   {
+//define windowsFileNameCharsNeedEscaping = " !%&'()+,;=[]^`{}~"; // "#$-.@_" are ok
+      escChars = " !\"%&'()+,;=[]^`{}~"; // windowsFileNameCharsNeedEscaping;
+      escCharsQuoted = "\"";
+   }
+   else
+   {
+//define linuxFileNameCharsNeedEscaping = " !\"$&'()*:;<=>?[\\`{|"; // "#%+,-.@]^_}~" are ok
+      escChars = " !\"$&'()*:;<=>?[\\`{|"; // linuxFileNameCharsNeedEscaping;
+      escCharsQuoted = "\"()$";
+   }
 
-   for(; *string && count < maxTokens; string++, output++)
+   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)
    {
@@ -875,11 +904,11 @@ public int Tokenize(char * string, int maxTokens, char* tokens[], bool escapeBac
    return count;
 }
 
-public int TokenizeWith(char * string, int maxTokens, char* tokens[], char * tokenizers, bool escapeBackSlashes)
+public int TokenizeWith(char * string, int maxTokens, char* tokens[], const char * tokenizers, bool escapeBackSlashes)
 {
    int count = 0;
    bool quoted = false;
-   byte * start = null;
+   char * start = null;
    bool escaped = false;
    char * output = string;
    bool quotedFromStart = false;
@@ -945,15 +974,15 @@ public int TokenizeWith(char * string, int maxTokens, char* tokens[], char * tok
    return count;
 }
 
-public char * TrimLSpaces(char * string, char * output)
+public char * TrimLSpaces(const char * string, char * output)
 {
    int c;
    for(c = 0; string[c] && string[c] == ' '; c++);
-   strcpy(output, string + c);
+   memmove(output, string + c, strlen(string+c)+1);
    return output;
 }
 
-public char * TrimRSpaces(char * string, char * output)
+public char * TrimRSpaces(const char * string, char * output)
 {
    int c;
    for(c = strlen(string)-1; c >= 0 && string[c] == ' '; c--);
@@ -974,6 +1003,13 @@ public void ChangeCh(char * string, char ch1, char ch2)
       if(string[c] == ch1) string[c] = ch2;
 }
 
+public void ChangeChars(char * string, const char * chars, char alt)
+{
+   int c;
+   for(c=0; string[c]; c++)
+      if(strchr(chars, string[c])) string[c] = alt;
+}
+
 public void RepeatCh(char * string, int count, char ch)
 {
    int c;
@@ -982,7 +1018,7 @@ public void RepeatCh(char * string, int count, char ch)
    string[c] = 0;
 }
 
-public char * CopyString(char * string)
+public char * CopyString(const char * string)
 {
    if(string)
    {
@@ -1033,7 +1069,7 @@ public bool GetString(char ** buffer, char * string, int max)
          {
             c++;
             //result = false;
-            break;            
+            break;
          }
          (*buffer)++;
       }
@@ -1053,21 +1089,21 @@ public uint GetHexValue(char ** buffer)
 {
    char string[20];
    GetString(buffer,string,20);
-   return strtoul(string, null, 16);
+   return (uint)strtoul(string, null, 16);
 }
 
-public char * StripQuotes(char * string, char * output)
+public char * StripQuotes(const char * string, char * output)
 {
    int len;
-
-   strcpy(output,(string[0] == '\"') ? (string+1) : string);
+   const char * src = (string[0] == '\"') ? (string+1) : string;
+   memmove(output, src, strlen(src)+1);
    len = strlen(output);
    if(len && output[len-1] == '\"')
       output[len-1] = '\0';
    return output;
 }
 
-public double FloatFromString(char * string)
+public double FloatFromString(const char * string)
 {
    int c, dig;
    float dec = 0,res = 0;
@@ -1101,39 +1137,27 @@ public double FloatFromString(char * string)
    return neg * res;
 }
 
-public bool GetAlNum(char ** buffer, char * string, int max)
+public bool IsPathInsideOf(const char * path, const char * of)
 {
-   int c;
-   char ch;
-   bool result = true;
-   if(!**buffer) { string[0]=0; return false; }
-
-   for(;;)
-   {
-      if(!(ch = *((*buffer)++)))
-         result = false;
-      if(isalnum(ch))
-         break;
-      if(!*(*buffer)) break;
-   }
-   if(result)
+   if(!path[0] || !of[0])
+      return false;  // What to do here? Ever used?
+   else
    {
-      for(c=0; c<max-1; c++)
+      char ofPart[MAX_FILENAME], ofRest[MAX_LOCATION];
+      char pathPart[MAX_FILENAME], pathRest[MAX_LOCATION];
+      strcpy(ofRest, of);
+      strcpy(pathRest, path);
+      for(; ofRest[0] && pathRest[0];)
       {
-         if(!isalnum(ch))
-         {
-            result = true;
-            break;
-         }
-         string[c]=ch;
-         if(!(ch = *(*buffer)))
-         {
-            c++;
-            break;            
-         }
-         (*buffer)++;
+         SplitDirectory(ofRest, ofPart, ofRest);
+         SplitDirectory(pathRest, pathPart, pathRest);
+         if(fstrcmp(pathPart, ofPart))
+            return false;
       }
-      string[c]=0;
+      if(!ofRest[0] && !pathRest[0])  // paths are identical - should return false or true? (changed to false)
+         return false;
+      else if(!pathRest[0])           // not inside of, it's the other way around
+         return false;
+      return true;
    }
-   return result;
 }