]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - common.c
removed a wasted normalize in fragment shader for model lighting
[xonotic/darkplaces.git] / common.c
index dad84c89dd83055ee8cf5a03b69b297e74863038..fe7e44298823f3d2fdcdb3461490ec1895b44176 100644 (file)
--- a/common.c
+++ b/common.c
@@ -740,11 +740,18 @@ skipwhite:
                                        data++;
                                        c = *data;
                                }
+                               else if (data[1] == '\'')
+                               {
+                                       data++;
+                                       c = *data;
+                               }
                                else if (data[1] == 'n')
                                {
                                        data++;
                                        c = '\n';
                                }
+                               else if (data[1] == '\\')
+                                       data++;
                        }
                        com_token[len++] = c;
                }
@@ -757,15 +764,34 @@ skipwhite:
                // quoted string
                for (data++;*data != '\'';data++)
                {
-                       if (*data == '\\' && data[1] == '\'' )
-                               data++;
                        if (!*data || len >= (int)sizeof(com_token) - 1)
                        {
                                com_token[0] = 0;
                                *datapointer = NULL;
                                return false;
                        }
-                       com_token[len++] = *data;
+                       c = *data;
+                       if (*data == '\\')
+                       {
+                               if (data[1] == '"')
+                               {
+                                       data++;
+                                       c = *data;
+                               }
+                               else if (data[1] == '\'')
+                               {
+                                       data++;
+                                       c = *data;
+                               }
+                               else if (data[1] == 'n')
+                               {
+                                       data++;
+                                       c = '\n';
+                               }
+                               else if (data[1] == '\\')
+                                       data++;
+                       }
+                       com_token[len++] = c;
                }
                com_token[len] = 0;
                *datapointer = data+1;
@@ -798,7 +824,28 @@ skipwhite:
                                *datapointer = NULL;
                                return false;
                        }
-                       com_token[len++] = *data;
+                       c = *data;
+                       if (*data == '\\')
+                       {
+                               if (data[1] == '"')
+                               {
+                                       data++;
+                                       c = *data;
+                               }
+                               else if (data[1] == '\'')
+                               {
+                                       data++;
+                                       c = *data;
+                               }
+                               else if (data[1] == 'n')
+                               {
+                                       data++;
+                                       c = '\n';
+                               }
+                               else if (data[1] == '\\')
+                                       data++;
+                       }
+                       com_token[len++] = c;
                }
                com_token[len] = 0;
                *datapointer = data;
@@ -816,7 +863,6 @@ Parse a token out of a string, behaving like the qwcl console
 int COM_ParseTokenConsole(const char **datapointer)
 {
        int len;
-       int c;
        const char *data = *datapointer;
 
        len = 0;
@@ -858,21 +904,10 @@ skipwhite:
                                *datapointer = NULL;
                                return false;
                        }
-                       c = *data;
-                       if (*data == '\\')
-                       {
-                               if (data[1] == '"')
-                               {
-                                       data++;
-                                       c = *data;
-                               }
-                               else if (data[1] == 'n')
-                               {
-                                       data++;
-                                       c = '\n';
-                               }
-                       }
-                       com_token[len++] = c;
+                       // allow escaped " case
+                       if (*data == '\\' && data[1] == '\"')
+                               data++;
+                       com_token[len++] = *data;
                }
                com_token[len] = 0;
                *datapointer = data+1;
@@ -1250,6 +1285,135 @@ int COM_ReadAndTokenizeLine(const char **text, char **argv, int maxargc, char *t
        return argc;
 }
 
+/*
+============
+COM_StringLengthNoColors
+
+calculates the visible width of a color coded string.
+
+*valid is filled with TRUE if the string is a valid colored string (that is, if
+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, size_t size_s, qboolean *valid)
+{
+       const char *end = size_s ? (s + size_s) : NULL;
+       size_t len = 0;
+       for(;;)
+       {
+               switch((s == end) ? 0 : *s)
+               {
+                       case 0:
+                               if(valid)
+                                       *valid = TRUE;
+                               return len;
+                       case STRING_COLOR_TAG:
+                               ++s;
+                               switch((s == end) ? 0 : *s)
+                               {
+                                       case 0: // ends with unfinished color code!
+                                               ++len;
+                                               if(valid)
+                                                       *valid = FALSE;
+                                               return len;
+                                       case STRING_COLOR_TAG: // escaped ^
+                                               ++len;
+                                               break;
+                                       case '0': case '1': case '2': case '3': case '4':
+                                       case '5': case '6': case '7': case '8': case '9': // color code
+                                               break;
+                                       default: // not a color code
+                                               ++len; // STRING_COLOR_TAG
+                                               ++len; // the character
+                                               break;
+                               }
+                               break;
+                       default:
+                               ++len;
+                               break;
+               }
+               ++s;
+       }
+       // never get here
+}
+
+/*
+============
+COM_StringDecolorize
+
+removes color codes from a string.
+
+If escape_carets is true, the resulting string will be safe for printing. If
+escape_carets is false, the function will just strip color codes (for logging
+for example).
+
+If the output buffer size did not suffice for converting, the function returns
+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, 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 == end) ? 0 : *in)
+               {
+                       case 0:
+                               *out++ = 0;
+                               return TRUE;
+                       case STRING_COLOR_TAG:
+                               ++in;
+                               switch((in == end) ? 0 : *in)
+                               {
+                                       case 0: // ends with unfinished color code!
+                                               APPEND(STRING_COLOR_TAG);
+                                               // finish the code by appending another caret when escaping
+                                               if(escape_carets)
+                                                       APPEND(STRING_COLOR_TAG);
+                                               *out++ = 0;
+                                               return TRUE;
+                                       case STRING_COLOR_TAG: // escaped ^
+                                               APPEND(STRING_COLOR_TAG);
+                                               // append a ^ twice when escaping
+                                               if(escape_carets)
+                                                       APPEND(STRING_COLOR_TAG);
+                                               break;
+                                       case '0': case '1': case '2': case '3': case '4':
+                                       case '5': case '6': case '7': case '8': case '9': // color code
+                                               break;
+                                       default: // not a color code
+                                               APPEND(STRING_COLOR_TAG);
+                                               APPEND(*in);
+                                               break;
+                               }
+                               break;
+                       default:
+                               APPEND(*in);
+                               break;
+               }
+               ++in;
+       }
+       // never get here
+#undef APPEND
+}
+
 // written by Elric, thanks Elric!
 char *SearchInfostring(const char *infostring, const char *key)
 {