]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - prvm_cmds.c
cvarlist, buf_cvarlist: support wildcards if present (if not present, it's treated...
[xonotic/darkplaces.git] / prvm_cmds.c
index ccd5b0a02eaa4a16ebab1e1d1af61deaf0ead895..cb3107cff2dfc65ec44b1a6484bebe65a96d48c0 100644 (file)
@@ -45,7 +45,7 @@ void VM_Warning(const char *fmt, ...)
 
 void VM_CheckEmptyString (const char *s)
 {
-       if (s[0] <= ' ')
+       if (ISWHITESPACE(s[0]))
                PRVM_ERROR ("%s: Bad string", PRVM_NAME);
 }
 
@@ -439,6 +439,7 @@ float CVAR_TYPEFLAG_SAVED = 2;
 float CVAR_TYPEFLAG_PRIVATE = 4;
 float CVAR_TYPEFLAG_ENGINE = 8;
 float CVAR_TYPEFLAG_HASDESCRIPTION = 16;
+float CVAR_TYPEFLAG_READONLY = 32;
 =================
 */
 void VM_cvar_type (void)
@@ -466,8 +467,10 @@ void VM_cvar_type (void)
                ret |= 4; // CVAR_TYPE_PRIVATE
        if(!(cvar->flags & CVAR_ALLOCATED))
                ret |= 8; // CVAR_TYPE_ENGINE
-       if(strcmp(cvar->description, "custom cvar")) // has to match Cvar_Get's placeholder string
+       if(cvar->description != cvar_dummy_description)
                ret |= 16; // CVAR_TYPE_HASDESCRIPTION
+       if(cvar->flags & CVAR_READONLY)
+               ret |= 32; // CVAR_TYPE_READONLY
        
        PRVM_G_FLOAT(OFS_RETURN) = ret;
 }
@@ -504,6 +507,22 @@ void VM_cvar_defstring (void)
        VM_CheckEmptyString(string);
        PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(Cvar_VariableDefString(string));
 }
+
+/*
+========================
+VM_cvar_defstring
+
+const string   VM_cvar_description (string, ...)
+========================
+*/
+void VM_cvar_description (void)
+{
+       char string[VM_STRINGTEMP_LENGTH];
+       VM_SAFEPARMCOUNTRANGE(1,8,VM_cvar_description);
+       VM_VarString(0, string, sizeof(string));
+       VM_CheckEmptyString(string);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(Cvar_VariableDescription(string));
+}
 /*
 =================
 VM_cvar_set
@@ -1439,7 +1458,7 @@ void VM_registercvar (void)
                return;
        }
 
-       Cvar_Get(name, value, flags);
+       Cvar_Get(name, value, flags, NULL);
 
        PRVM_G_FLOAT(OFS_RETURN) = 1; // success
 }
@@ -1957,9 +1976,7 @@ void VM_strdecolorize(void)
        // Prepare Strings
        VM_SAFEPARMCOUNT(1,VM_strdecolorize);
        szString = PRVM_G_STRING(OFS_PARM0);
-
        COM_StringDecolorize(szString, 0, szNewString, sizeof(szNewString), TRUE);
-
        PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(szNewString);
 }
 
@@ -2272,24 +2289,67 @@ float tokenize(string s)
 //float(string s) tokenize = #441; // takes apart a string into individal words (access them with argv), returns how many
 //this function originally written by KrimZon, made shorter by LordHavoc
 //20040203: rewritten by LordHavoc (no longer uses allocations)
-int num_tokens = 0;
-int tokens[256];
+static int num_tokens = 0;
+static int tokens[256];
+static int tokens_startpos[256];
+static int tokens_endpos[256];
+static char tokenize_string[VM_STRINGTEMP_LENGTH];
 void VM_tokenize (void)
 {
        const char *p;
-       static char string[VM_STRINGTEMP_LENGTH]; // static, because it's big
 
        VM_SAFEPARMCOUNT(1,VM_tokenize);
 
-       strlcpy(string, PRVM_G_STRING(OFS_PARM0), sizeof(string));
-       p = string;
+       strlcpy(tokenize_string, PRVM_G_STRING(OFS_PARM0), sizeof(tokenize_string));
+       p = tokenize_string;
 
        num_tokens = 0;
-       while(COM_ParseToken_VM_Tokenize(&p, false))
+       for(;;)
        {
                if (num_tokens >= (int)(sizeof(tokens)/sizeof(tokens[0])))
                        break;
-               tokens[num_tokens++] = PRVM_SetTempString(com_token);
+
+               // skip whitespace here to find token start pos
+               while(*p && ISWHITESPACE(*p))
+                       ++p;
+
+               tokens_startpos[num_tokens] = p - tokenize_string;
+               if(!COM_ParseToken_VM_Tokenize(&p, false))
+                       break;
+               tokens_endpos[num_tokens] = p - tokenize_string;
+               tokens[num_tokens] = PRVM_SetTempString(com_token);
+               ++num_tokens;
+       }
+
+       PRVM_G_FLOAT(OFS_RETURN) = num_tokens;
+}
+
+//float(string s) tokenize = #514; // takes apart a string into individal words (access them with argv), returns how many
+void VM_tokenize_console (void)
+{
+       const char *p;
+
+       VM_SAFEPARMCOUNT(1,VM_tokenize);
+
+       strlcpy(tokenize_string, PRVM_G_STRING(OFS_PARM0), sizeof(tokenize_string));
+       p = tokenize_string;
+
+       num_tokens = 0;
+       for(;;)
+       {
+               if (num_tokens >= (int)(sizeof(tokens)/sizeof(tokens[0])))
+                       break;
+
+               // skip whitespace here to find token start pos
+               while(*p && ISWHITESPACE(*p))
+                       ++p;
+
+               tokens_startpos[num_tokens] = p - tokenize_string;
+               if(!COM_ParseToken_Console(&p))
+                       break;
+               tokens_endpos[num_tokens] = p - tokenize_string;
+               tokens[num_tokens] = PRVM_SetTempString(com_token);
+               ++num_tokens;
        }
 
        PRVM_G_FLOAT(OFS_RETURN) = num_tokens;
@@ -2318,12 +2378,11 @@ void VM_tokenizebyseparator (void)
        const char *p;
        const char *token;
        char tokentext[MAX_INPUTLINE];
-       static char string[VM_STRINGTEMP_LENGTH]; // static, because it's big
 
        VM_SAFEPARMCOUNTRANGE(2, 8,VM_tokenizebyseparator);
 
-       strlcpy(string, PRVM_G_STRING(OFS_PARM0), sizeof(string));
-       p = string;
+       strlcpy(tokenize_string, PRVM_G_STRING(OFS_PARM0), sizeof(tokenize_string));
+       p = tokenize_string;
 
        numseparators = 0;
        for (j = 1;j < prog->argc;j++)
@@ -2343,6 +2402,7 @@ void VM_tokenizebyseparator (void)
        while (num_tokens < (int)(sizeof(tokens)/sizeof(tokens[0])))
        {
                token = tokentext + j;
+               tokens_startpos[num_tokens] = p - tokenize_string;
                while (*p)
                {
                        for (k = 0;k < numseparators;k++)
@@ -2359,6 +2419,7 @@ void VM_tokenizebyseparator (void)
                                tokentext[j++] = *p;
                        p++;
                }
+               tokens_endpos[num_tokens] = p - tokenize_string;
                if (j >= (int)sizeof(tokentext))
                        break;
                tokentext[j++] = 0;
@@ -2380,12 +2441,51 @@ void VM_argv (void)
 
        token_num = (int)PRVM_G_FLOAT(OFS_PARM0);
 
+       if(token_num < 0)
+               token_num += num_tokens;
+
        if (token_num >= 0 && token_num < num_tokens)
                PRVM_G_INT(OFS_RETURN) = tokens[token_num];
        else
                PRVM_G_INT(OFS_RETURN) = OFS_NULL;
 }
 
+//float(float n) argv_start_index = #515; // returns the start index of a token
+void VM_argv_start_index (void)
+{
+       int token_num;
+
+       VM_SAFEPARMCOUNT(1,VM_argv);
+
+       token_num = (int)PRVM_G_FLOAT(OFS_PARM0);
+
+       if(token_num < 0)
+               token_num += num_tokens;
+
+       if (token_num >= 0 && token_num < num_tokens)
+               PRVM_G_FLOAT(OFS_RETURN) = tokens_startpos[token_num];
+       else
+               PRVM_G_FLOAT(OFS_RETURN) = -1;
+}
+
+//float(float n) argv_end_index = #516; // returns the end index of a token
+void VM_argv_end_index (void)
+{
+       int token_num;
+
+       VM_SAFEPARMCOUNT(1,VM_argv);
+
+       token_num = (int)PRVM_G_FLOAT(OFS_PARM0);
+
+       if(token_num < 0)
+               token_num += num_tokens;
+
+       if (token_num >= 0 && token_num < num_tokens)
+               PRVM_G_FLOAT(OFS_RETURN) = tokens_endpos[token_num];
+       else
+               PRVM_G_FLOAT(OFS_RETURN) = -1;
+}
+
 /*
 =========
 VM_isserver
@@ -4285,6 +4385,91 @@ void VM_bufstr_free (void)
        BufStr_Shrink(stringbuffer);
 }
 
+
+
+
+
+
+
+void VM_buf_cvarlist(void)
+{
+       cvar_t *cvar;
+       const char *partial, *antipartial;
+       size_t len, antilen;
+       size_t alloclen;
+       qboolean ispattern, antiispattern;
+       int n;
+       prvm_stringbuffer_t     *stringbuffer;
+       VM_SAFEPARMCOUNTRANGE(2, 3, VM_buf_cvarlist);
+
+       stringbuffer = (prvm_stringbuffer_t *)Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, (int)PRVM_G_FLOAT(OFS_PARM0));
+       if(!stringbuffer)
+       {
+               VM_Warning("VM_bufstr_free: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+               return;
+       }
+
+       partial = PRVM_G_STRING(OFS_PARM1);
+       if(!partial)
+               len = 0;
+       else
+               len = strlen(partial);
+
+       if(prog->argc == 3)
+               antipartial = PRVM_G_STRING(OFS_PARM2);
+       else
+               antipartial = NULL;
+       if(!antipartial)
+               antilen = 0;
+       else
+               antilen = strlen(antipartial);
+       
+       for (n = 0;n < stringbuffer->num_strings;n++)
+               if (stringbuffer->strings[n])
+                       Mem_Free(stringbuffer->strings[n]);
+       if (stringbuffer->strings)
+               Mem_Free(stringbuffer->strings);
+       stringbuffer->strings = NULL;
+
+       ispattern = partial && (strchr(partial, '*') || strchr(partial, '?'));
+       antiispattern = antipartial && (strchr(antipartial, '*') || strchr(antipartial, '?'));
+
+       n = 0;
+       for(cvar = cvar_vars; cvar; cvar = cvar->next)
+       {
+               if(len && (ispattern ? !matchpattern_with_separator(cvar->name, partial, false, "", false) : strncmp(partial, cvar->name, len)))
+                       continue;
+
+               if(antilen && (antiispattern ? matchpattern_with_separator(cvar->name, antipartial, false, "", false) : !strncmp(antipartial, cvar->name, antilen)))
+                       continue;
+
+               ++n;
+       }
+
+       stringbuffer->max_strings = stringbuffer->num_strings = n;
+       if (stringbuffer->max_strings)
+               stringbuffer->strings = (char **)Mem_Alloc(prog->progs_mempool, sizeof(stringbuffer->strings[0]) * stringbuffer->max_strings);
+       
+       n = 0;
+       for(cvar = cvar_vars; cvar; cvar = cvar->next)
+       {
+               if(len && (ispattern ? !matchpattern_with_separator(cvar->name, partial, false, "", false) : strncmp(partial, cvar->name, len)))
+                       continue;
+
+               if(antilen && (antiispattern ? matchpattern_with_separator(cvar->name, antipartial, false, "", false) : !strncmp(antipartial, cvar->name, antilen)))
+                       continue;
+
+               alloclen = strlen(cvar->name) + 1;
+               stringbuffer->strings[n] = (char *)Mem_Alloc(prog->progs_mempool, alloclen);
+               memcpy(stringbuffer->strings[n], cvar->name, alloclen);
+
+               ++n;
+       }
+}
+
+
+
+
 //=============
 
 /*
@@ -4409,50 +4594,18 @@ void VM_changepitch (void)
        PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.angles)->vector[0] = ANGLEMOD (current + move);
 }
 
-// TODO: adapt all static function names to use a single naming convention... [12/3/2007 Black]
-static int Is_Text_Color (char c, char t)
-{
-       int a = 0;
-       char c2 = c - (c & 128);
-       char t2 = t - (t & 128);
-
-       if(c != STRING_COLOR_TAG && c2 != STRING_COLOR_TAG)             return 0;
-       if(t >= '0' && t <= '9')                a = 1;
-       if(t2 >= '0' && t2 <= '9')              a = 1;
-/*     if(t >= 'A' && t <= 'Z')                a = 2;
-       if(t2 >= 'A' && t2 <= 'Z')              a = 2;
-
-       if(a == 1 && scr_colortext.integer > 0)
-               return 1;
-       if(a == 2 && scr_multifonts.integer > 0)
-               return 2;
-*/
-       return a;
-}
 
 void VM_uncolorstring (void)
 {
-       const char      *in;
-       char            out[VM_STRINGTEMP_LENGTH];
-       int                     k = 0, i = 0;
+       char szNewString[VM_STRINGTEMP_LENGTH];
+       const char *szString;
 
+       // Prepare Strings
        VM_SAFEPARMCOUNT(1, VM_uncolorstring);
-       in = PRVM_G_STRING(OFS_PARM0);
-       VM_CheckEmptyString (in);
-
-       while (in[k])
-       {
-               if(in[k+1])
-               if(Is_Text_Color(in[k], in[k+1]) == 1/* || (in[k] == '&' && in[k+1] == 'r')*/)
-               {
-                       k += 2;
-                       continue;
-               }
-               out[i] = in[k];
-               ++k;
-               ++i;
-       }
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(out);
+       szString = PRVM_G_STRING(OFS_PARM0);
+       COM_StringDecolorize(szString, 0, szNewString, sizeof(szNewString), TRUE);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(szNewString);
+       
 }
 
 // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)