]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - common.c
added a developer 1000 print for every key event received, attempting to
[xonotic/darkplaces.git] / common.c
index 118e89e715418756d974a6e188b1fb89f62781e3..e0154eec0f759a7c6974aa883e64667c0f05fb6a 100644 (file)
--- a/common.c
+++ b/common.c
@@ -665,12 +665,12 @@ void SZ_HexDumpToConsole(const sizebuf_t *buf)
 
 /*
 ==============
-COM_ParseToken
+COM_ParseToken_Simple
 
 Parse a token out of a string
 ==============
 */
-int COM_ParseToken(const char **datapointer, int returnnewline)
+int COM_ParseToken_Simple(const char **datapointer, int returnnewline)
 {
        int len;
        int c;
@@ -718,94 +718,159 @@ skipwhite:
                data++;
                while (*data && (data[0] != '*' || data[1] != '/'))
                        data++;
-               data += 2;
+               if (*data)
+                       data++;
+               if (*data)
+                       data++;
                goto skipwhite;
        }
        else if (*data == '\"')
        {
                // quoted string
-               for (data++;*data != '\"';data++)
+               for (data++;*data && *data != '\"';data++)
                {
-                       if (!*data || len >= (int)sizeof(com_token) - 1)
-                       {
-                               com_token[0] = 0;
-                               *datapointer = NULL;
-                               return false;
-                       }
                        c = *data;
                        if (*data == '\\')
                        {
-                               if (data[1] == '"')
-                               {
-                                       data++;
-                                       c = *data;
-                               }
-                               else if (data[1] == '\'')
-                               {
-                                       data++;
-                                       c = *data;
-                               }
-                               else if (data[1] == 'n')
-                               {
-                                       data++;
+                               data++;
+                               c = *data;
+                               if (c == 'n')
                                        c = '\n';
-                               }
-                               else if (data[1] == '\\')
-                                       data++;
+                               else if (c == 't')
+                                       c = '\t';
                        }
-                       com_token[len++] = c;
+                       if (len < (int)sizeof(com_token) - 1)
+                               com_token[len++] = c;
                }
                com_token[len] = 0;
-               *datapointer = data+1;
+               if (*data == '\"')
+                       data++;
+               *datapointer = data;
+               return true;
+       }
+       else if (*data == '\r')
+       {
+               // translate Mac line ending to UNIX
+               com_token[len++] = '\n';data++;
+               com_token[len] = 0;
+               *datapointer = data;
+               return true;
+       }
+       else if (*data == '\n')
+       {
+               // single character
+               com_token[len++] = *data++;
+               com_token[len] = 0;
+               *datapointer = data;
+               return true;
+       }
+       else
+       {
+               // regular word
+               for (;*data > ' ';data++)
+                       if (len < (int)sizeof(com_token) - 1)
+                               com_token[len++] = *data;
+               com_token[len] = 0;
+               *datapointer = data;
                return true;
        }
-       else if (*data == '\'')
+}
+
+/*
+==============
+COM_ParseToken_QuakeC
+
+Parse a token out of a string
+==============
+*/
+int COM_ParseToken_QuakeC(const char **datapointer, int returnnewline)
+{
+       int len;
+       int c;
+       const char *data = *datapointer;
+
+       len = 0;
+       com_token[0] = 0;
+
+       if (!data)
+       {
+               *datapointer = NULL;
+               return false;
+       }
+
+// skip whitespace
+skipwhite:
+       // line endings:
+       // UNIX: \n
+       // Mac: \r
+       // Windows: \r\n
+       for (;*data <= ' ' && ((*data != '\n' && *data != '\r') || !returnnewline);data++)
+       {
+               if (*data == 0)
+               {
+                       // end of file
+                       *datapointer = NULL;
+                       return false;
+               }
+       }
+
+       // handle Windows line ending
+       if (data[0] == '\r' && data[1] == '\n')
+               data++;
+
+       if (data[0] == '/' && data[1] == '/')
+       {
+               // comment
+               while (*data && *data != '\n' && *data != '\r')
+                       data++;
+               goto skipwhite;
+       }
+       else if (data[0] == '/' && data[1] == '*')
+       {
+               // comment
+               data++;
+               while (*data && (data[0] != '*' || data[1] != '/'))
+                       data++;
+               if (*data)
+                       data++;
+               if (*data)
+                       data++;
+               goto skipwhite;
+       }
+       else if (*data == '\"' || *data == '\'')
        {
                // quoted string
-               for (data++;*data != '\'';data++)
+               char quote = *data;
+               for (data++;*data && *data != quote;data++)
                {
-                       if (!*data || len >= (int)sizeof(com_token) - 1)
-                       {
-                               com_token[0] = 0;
-                               *datapointer = NULL;
-                               return false;
-                       }
                        c = *data;
                        if (*data == '\\')
                        {
-                               if (data[1] == '"')
-                               {
-                                       data++;
-                                       c = *data;
-                               }
-                               else if (data[1] == '\'')
-                               {
-                                       data++;
-                                       c = *data;
-                               }
-                               else if (data[1] == 'n')
-                               {
-                                       data++;
+                               data++;
+                               c = *data;
+                               if (c == 'n')
                                        c = '\n';
-                               }
-                               else if (data[1] == '\\')
-                                       data++;
+                               else if (c == 't')
+                                       c = '\t';
                        }
-                       com_token[len++] = c;
+                       if (len < (int)sizeof(com_token) - 1)
+                               com_token[len++] = c;
                }
                com_token[len] = 0;
-               *datapointer = data+1;
+               if (*data == quote)
+                       data++;
+               *datapointer = data;
                return true;
        }
        else if (*data == '\r')
        {
                // translate Mac line ending to UNIX
-               com_token[len++] = '\n';
+               com_token[len++] = '\n';data++;
                com_token[len] = 0;
                *datapointer = data;
                return true;
        }
-       else if (*data == '\n' || *data == '{' || *data == '}' || *data == ')' || *data == '(' || *data == ']' || *data == '[' || *data == '\'' || *data == ':' || *data == ',' || *data == ';')
+       else if (*data == '\n' || *data == '{' || *data == '}' || *data == ')' || *data == '(' || *data == ']' || *data == '[' || *data == ':' || *data == ',' || *data == ';')
        {
                // single character
                com_token[len++] = *data++;
@@ -816,38 +881,124 @@ skipwhite:
        else
        {
                // regular word
-               for (;*data > ' ' && *data != '{' && *data != '}' && *data != ')' && *data != '(' && *data != ']' && *data != '[' && *data != '\'' && *data != ':' && *data != ',' && *data != ';' && *data != '\'' && *data != '"';data++)
+               for (;*data > ' ' && *data != '{' && *data != '}' && *data != ')' && *data != '(' && *data != ']' && *data != '[' && *data != ':' && *data != ',' && *data != ';';data++)
+                       if (len < (int)sizeof(com_token) - 1)
+                               com_token[len++] = *data;
+               com_token[len] = 0;
+               *datapointer = data;
+               return true;
+       }
+}
+
+/*
+==============
+COM_ParseToken_VM_Tokenize
+
+Parse a token out of a string
+==============
+*/
+int COM_ParseToken_VM_Tokenize(const char **datapointer, int returnnewline)
+{
+       int len;
+       int c;
+       const char *data = *datapointer;
+
+       len = 0;
+       com_token[0] = 0;
+
+       if (!data)
+       {
+               *datapointer = NULL;
+               return false;
+       }
+
+// skip whitespace
+skipwhite:
+       // line endings:
+       // UNIX: \n
+       // Mac: \r
+       // Windows: \r\n
+       for (;*data <= ' ' && ((*data != '\n' && *data != '\r') || !returnnewline);data++)
+       {
+               if (*data == 0)
+               {
+                       // end of file
+                       *datapointer = NULL;
+                       return false;
+               }
+       }
+
+       // handle Windows line ending
+       if (data[0] == '\r' && data[1] == '\n')
+               data++;
+
+       if (data[0] == '/' && data[1] == '/')
+       {
+               // comment
+               while (*data && *data != '\n' && *data != '\r')
+                       data++;
+               goto skipwhite;
+       }
+       else if (data[0] == '/' && data[1] == '*')
+       {
+               // comment
+               data++;
+               while (*data && (data[0] != '*' || data[1] != '/'))
+                       data++;
+               if (*data)
+                       data++;
+               if (*data)
+                       data++;
+               goto skipwhite;
+       }
+       else if (*data == '\"' || *data == '\'')
+       {
+               char quote = *data;
+               // quoted string
+               for (data++;*data && *data != quote;data++)
                {
-                       if (len >= (int)sizeof(com_token) - 1)
-                       {
-                               com_token[0] = 0;
-                               *datapointer = NULL;
-                               return false;
-                       }
                        c = *data;
                        if (*data == '\\')
                        {
-                               if (data[1] == '"')
-                               {
-                                       data++;
-                                       c = *data;
-                               }
-                               else if (data[1] == '\'')
-                               {
-                                       data++;
-                                       c = *data;
-                               }
-                               else if (data[1] == 'n')
-                               {
-                                       data++;
+                               data++;
+                               c = *data;
+                               if (c == 'n')
                                        c = '\n';
-                               }
-                               else if (data[1] == '\\')
-                                       data++;
+                               else if (c == 't')
+                                       c = '\t';
                        }
-                       com_token[len++] = c;
+                       if (len < (int)sizeof(com_token) - 1)
+                               com_token[len++] = c;
                }
                com_token[len] = 0;
+               if (*data == quote)
+                       data++;
+               *datapointer = data;
+               return true;
+       }
+       else if (*data == '\r')
+       {
+               // translate Mac line ending to UNIX
+               com_token[len++] = '\n';data++;
+               com_token[len] = 0;
+               *datapointer = data;
+               return true;
+       }
+       else if (*data == '\n' || *data == '{' || *data == '}' || *data == ')' || *data == '(' || *data == ']' || *data == '[' || *data == ':' || *data == ',' || *data == ';')
+       {
+               // single character
+               com_token[len++] = *data++;
+               com_token[len] = 0;
+               *datapointer = data;
+               return true;
+       }
+       else
+       {
+               // regular word
+               for (;*data > ' ' && *data != ',' && *data != ';' && *data != '{' && *data != '}' && *data != ')' && *data != '(' && *data != ']' && *data != '[' && *data != ':' && *data != ',' && *data != ';';data++)
+                       if (len < (int)sizeof(com_token) - 1)
+                               com_token[len++] = *data;
+               com_token[len] = 0;
                *datapointer = data;
                return true;
        }
@@ -855,12 +1006,12 @@ skipwhite:
 
 /*
 ==============
-COM_ParseTokenConsole
+COM_ParseToken_Console
 
 Parse a token out of a string, behaving like the qwcl console
 ==============
 */
-int COM_ParseTokenConsole(const char **datapointer)
+int COM_ParseToken_Console(const char **datapointer)
 {
        int len;
        const char *data = *datapointer;
@@ -896,32 +1047,25 @@ skipwhite:
        else if (*data == '\"')
        {
                // quoted string
-               for (data++;*data != '\"';data++)
+               for (data++;*data && *data != '\"';data++)
                {
-                       if (!*data || len >= (int)sizeof(com_token) - 1)
-                       {
-                               com_token[0] = 0;
-                               *datapointer = NULL;
-                               return false;
-                       }
-                       com_token[len++] = *data;
+                       // allow escaped " and \ case
+                       if (*data == '\\' && (data[1] == '\"' || data[1] == '\\'))
+                               data++;
+                       if (len < (int)sizeof(com_token) - 1)
+                               com_token[len++] = *data;
                }
                com_token[len] = 0;
-               *datapointer = data+1;
+               if (*data == '\"')
+                       data++;
+               *datapointer = data;
        }
        else
        {
                // regular word
                for (;*data > ' ';data++)
-               {
-                       if (len >= (int)sizeof(com_token) - 1)
-                       {
-                               com_token[0] = 0;
-                               *datapointer = NULL;
-                               return false;
-                       }
-                       com_token[len++] = *data;
-               }
+                       if (len < (int)sizeof(com_token) - 1)
+                               com_token[len++] = *data;
                com_token[len] = 0;
                *datapointer = data;
        }
@@ -1293,15 +1437,19 @@ it does not end with an unfinished color code). If it gets filled with FALSE, a
 fix would be adding a STRING_COLOR_TAG at the end of the string.
 
 valid can be set to NULL if the caller doesn't care.
+
+For size_s, specify the maximum number of characters from s to use, or 0 to use
+all characters until the zero terminator.
 ============
 */
 size_t
-COM_StringLengthNoColors(const char *s, qboolean *valid)
+COM_StringLengthNoColors(const char *s, size_t size_s, qboolean *valid)
 {
+       const char *end = size_s ? (s + size_s) : NULL;
        size_t len = 0;
        for(;;)
        {
-               switch(*s)
+               switch((s == end) ? 0 : *s)
                {
                        case 0:
                                if(valid)
@@ -1309,7 +1457,7 @@ COM_StringLengthNoColors(const char *s, qboolean *valid)
                                return len;
                        case STRING_COLOR_TAG:
                                ++s;
-                               switch(*s)
+                               switch((s == end) ? 0 : *s)
                                {
                                        case 0: // ends with unfinished color code!
                                                ++len;
@@ -1352,24 +1500,28 @@ FALSE. Generally, if escape_carets is false, the output buffer needs
 strlen(str)+1 bytes, and if escape_carets is true, it can need strlen(str)+2
 bytes. In any case, the function makes sure that the resulting string is
 zero terminated.
+
+For size_in, specify the maximum number of characters from in to use, or 0 to use
+all characters until the zero terminator.
 ============
 */
 qboolean
-COM_StringDecolorize(const char *in, char *out, size_t size_out, qboolean escape_carets)
+COM_StringDecolorize(const char *in, size_t size_in, char *out, size_t size_out, qboolean escape_carets)
 {
 #define APPEND(ch) do { if(--size_out) { *out++ = (ch); } else { *out++ = 0; return FALSE; } } while(0)
+       const char *end = size_in ? (in + size_in) : NULL;
        if(size_out < 1)
                return FALSE;
        for(;;)
        {
-               switch(*in)
+               switch((in == end) ? 0 : *in)
                {
                        case 0:
                                *out++ = 0;
                                return TRUE;
                        case STRING_COLOR_TAG:
                                ++in;
-                               switch(*in)
+                               switch((in == end) ? 0 : *in)
                                {
                                        case 0: // ends with unfinished color code!
                                                APPEND(STRING_COLOR_TAG);