#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 vsnprintf string
public define MAX_F_STRING = 1025;
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);
return output;
}
-public char * StripLastDirectory(char * string, char * output)
+public char * StripLastDirectory(const char * string, char * output)
{
int c;
if(runtimePlatform == win32 && !strcmp(string, "\\\\"))
for(;(ch = string[c]) && (ch != '/' && ch != '\\'); c++)
{
if(len < MAX_FILENAME)
- part[len++] = ch;
+ part[len++] = ch;
}
}
for(;(ch = string[c]) && (ch == '/' || ch == '\\'); 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';
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;
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] == '<')
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] != '<')
{
}
else if(!modified && (addedPath[0] == '\\' || addedPath[0] == '/'))
{
- if(GetRuntimePlatform() == win32)
+ if(__runtimePlatform == win32)
{
// Entire Computer
if(addedPath[0] == '/' && !addedPath[1])
int len = 0;
char ch;
int count;
-
+
for(;(ch = addedPath[c]) && (ch == '/' || ch == '\\'); c++);
for(;(ch = addedPath[c]) && (ch != '/' && ch != '\\'); c++)
{
break;
}
if(len < MAX_FILENAME)
- directory[len++] = ch;
+ directory[len++] = ch;
}
directory[len] = '\0';
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)
{
}
else
{
- if(GetRuntimePlatform() == win32)
+ if(__runtimePlatform == win32)
{
if(!strLen && fileName[0] == '\\' && fileName[1] == '\\')
{
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)
{
int len = 0;
char ch;
int count;
-
+
for(;(ch = addedPath[c]) && (ch == '/' || ch == '\\'); c++);
for(;(ch = addedPath[c]) && (ch != '/' && ch != '\\'); c++)
{
break;
}
if(len < MAX_FILENAME)
- directory[len++] = ch;
+ directory[len++] = ch;
}
directory[len] = '\0';
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)
{
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])
memmove(destination, path, strlen(path)+1);
destination[0] = '\0';
for(;toRest[0];)
{
- SplitDirectory(toRest, toPart, toRest);
+ SplitDirectory(toRest, toPart, toRest);
if(!different)
SplitDirectory(pathRest, pathPart, pathRest);
PathCat(destination, pathPart);
}
}
+ len = strlen(destination);
+ if(len>1 && (destination[len-1] == '/' || destination[len-1] == '\\'))
+ destination[--len] = '\0';
return destination;
}
return false;
}
-public char * ChangeExtension(char * string, char * ext, char * output)
+public char * ChangeExtension(const char * string, const char * ext, char * output)
{
if(string != output)
strcpy(output, string);
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++)
{
{
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;
}
}
}
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)
{
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;
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++);
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--);
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;
string[c] = 0;
}
-public char * CopyString(char * string)
+public char * CopyString(const char * string)
{
if(string)
{
{
c++;
//result = false;
- break;
+ break;
}
(*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;
- char * src = (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] == '\"')
return output;
}
-public double FloatFromString(char * string)
+public double FloatFromString(const char * string)
{
int c, dig;
float dec = 0,res = 0;
return neg * res;
}
-public bool IsPathInsideOf(char * path, char * of)
+public bool IsPathInsideOf(const char * path, const char * of)
{
if(!path[0] || !of[0])
return false; // What to do here? Ever used?