new tokenizer tokenize_console that matches the console tokenizing
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 27 Dec 2008 14:35:13 +0000 (14:35 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 27 Dec 2008 14:35:13 +0000 (14:35 +0000)
new builtins argv_start_index and argv_end_index
support negative indexes to argv* as indexes from the end of the argument list (similar to perl)
--> extension: DP_QC_TOKENIZE_CONSOLE

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@8605 d7cf8633-e32d-0410-b094-e92efae38249

clvm_cmds.c
mvm_cmds.c
prvm_cmds.c
prvm_cmds.h
svvm_cmds.c

index 24fe26e..8f72cc4 100644 (file)
@@ -3535,9 +3535,9 @@ VM_uri_escape,                                    // #510 string(string in) uri_escape = #510;
 VM_uri_unescape,                               // #511 string(string in) uri_unescape = #511;
 VM_etof,                                       // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
 VM_uri_get,                                            // #513 float(string uril, float id) uri_get = #512; (DP_QC_URI_GET)
-NULL,                                                  // #514
-NULL,                                                  // #515
-NULL,                                                  // #516
+VM_tokenize_console,                                   // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE)
+VM_argv_start_index,                                   // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE)
+VM_argv_end_index,                                             // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE)
 NULL,                                                  // #517
 NULL,                                                  // #518
 NULL,                                                  // #519
index e0ae2ba..28fa492 100644 (file)
@@ -24,6 +24,7 @@ char *vm_m_extensions =
 "DP_QC_STRING_CASE_FUNCTIONS "
 "DP_QC_STRREPLACE "
 "DP_QC_TOKENIZEBYSEPARATOR "
+"DP_QC_TOKENIZE_CONSOLE "
 "DP_QC_UNLIMITEDTEMPSTRINGS "
 "DP_QC_URI_ESCAPE "
 "DP_QC_URI_GET "
@@ -1332,9 +1333,9 @@ VM_uri_escape,                                    // #510 string(string in) uri_escape = #510;
 VM_uri_unescape,                               // #511 string(string in) uri_unescape = #511;
 VM_etof,                                       // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
 VM_uri_get,                                            // #513 float(string uril, float id) uri_get = #513; (DP_QC_URI_GET)
-NULL,                                                                  // #514
-NULL,                                                                  // #515
-NULL,                                                                  // #516
+VM_tokenize_console,                                   // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE)
+VM_argv_start_index,                                   // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE)
+VM_argv_end_index,                                             // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE)
 NULL,                                                                  // #517
 NULL,                                                                  // #518
 NULL,                                                                  // #519
index 924f688..696ffea 100644 (file)
@@ -2270,24 +2270,68 @@ 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];
 void VM_tokenize (void)
 {
        const char *p;
-       static char string[VM_STRINGTEMP_LENGTH]; // static, because it's big
+       const char *string;
 
        VM_SAFEPARMCOUNT(1,VM_tokenize);
 
-       strlcpy(string, PRVM_G_STRING(OFS_PARM0), sizeof(string));
+       string = PRVM_G_STRING(OFS_PARM0);
+       p = 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 && (unsigned char) *p <= ' ')
+                       ++p;
+
+               tokens_startpos[num_tokens] = p - string;
+               if(!COM_ParseToken_VM_Tokenize(&p, false))
+                       break;
+               tokens_endpos[num_tokens] = p - 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;
+       const char *string;
+
+       VM_SAFEPARMCOUNT(1,VM_tokenize);
+
+       string = PRVM_G_STRING(OFS_PARM0);
        p = 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 && (unsigned char) *p <= ' ')
+                       ++p;
+
+               tokens_startpos[num_tokens] = p - string;
+               if(!COM_ParseToken_Console(&p))
+                       break;
+               tokens_endpos[num_tokens] = p - string;
+               tokens[num_tokens] = PRVM_SetTempString(com_token);
+               ++num_tokens;
        }
 
        PRVM_G_FLOAT(OFS_RETURN) = num_tokens;
@@ -2316,11 +2360,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
+       const char *string;
 
        VM_SAFEPARMCOUNTRANGE(2, 8,VM_tokenizebyseparator);
 
-       strlcpy(string, PRVM_G_STRING(OFS_PARM0), sizeof(string));
+       string = PRVM_G_STRING(OFS_PARM0);
        p = string;
 
        numseparators = 0;
@@ -2341,6 +2385,7 @@ void VM_tokenizebyseparator (void)
        while (num_tokens < (int)(sizeof(tokens)/sizeof(tokens[0])))
        {
                token = tokentext + j;
+               tokens_startpos[num_tokens] = p - string;
                while (*p)
                {
                        for (k = 0;k < numseparators;k++)
@@ -2357,6 +2402,7 @@ void VM_tokenizebyseparator (void)
                                tokentext[j++] = *p;
                        p++;
                }
+               tokens_endpos[num_tokens] = p - string;
                if (j >= (int)sizeof(tokentext))
                        break;
                tokentext[j++] = 0;
@@ -2378,12 +2424,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
index 79646f7..59377ce 100644 (file)
@@ -432,3 +432,7 @@ void VM_whichpack (void);
 void VM_etof (void);
 void VM_uri_get (void);
 void VM_netaddress_resolve (void);
+
+void VM_tokenize_console (void);
+void VM_argv_start_index (void);
+void VM_argv_end_index (void);
index a2c2cee..c454c2d 100644 (file)
@@ -87,6 +87,7 @@ char *vm_sv_extensions =
 "DP_QC_STRING_CASE_FUNCTIONS "
 "DP_QC_STRREPLACE "
 "DP_QC_TOKENIZEBYSEPARATOR "
+"DP_QC_TOKENIZE_CONSOLE "
 "DP_QC_TRACEBOX "
 "DP_QC_TRACETOSS "
 "DP_QC_TRACE_MOVETYPE_HITMODEL "
@@ -3414,9 +3415,9 @@ VM_uri_escape,                                    // #510 string(string in) uri_escape = #510;
 VM_uri_unescape,                               // #511 string(string in) uri_unescape = #511;
 VM_etof,                                       // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
 VM_uri_get,                                            // #513 float(string uril, float id) uri_get = #513; (DP_QC_URI_GET)
-NULL,                                                  // #514
-NULL,                                                  // #515
-NULL,                                                  // #516
+VM_tokenize_console,                                   // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE)
+VM_argv_start_index,                                   // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE)
+VM_argv_end_index,                                             // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE)
 NULL,                                                  // #517
 NULL,                                                  // #518
 NULL,                                                  // #519