X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=prvm_cmds.c;h=fcf3d8ba40967301ca9134116435bc9ca4b52d12;hb=4507ee7b951dc192842b4eda9061fae4908bd0e1;hp=887192dda0456c79ae645688cebc4a9ec1a70561;hpb=16742571f9a7d696a654668febdc10b4f4affd57;p=xonotic%2Fdarkplaces.git diff --git a/prvm_cmds.c b/prvm_cmds.c index 887192dd..fcf3d8ba 100644 --- a/prvm_cmds.c +++ b/prvm_cmds.c @@ -115,7 +115,7 @@ void VM_error (void) if (prog->globaloffsets.self >= 0) { ed = PRVM_PROG_TO_EDICT(PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict); - PRVM_ED_Print(ed); + PRVM_ED_Print(ed, NULL); } PRVM_ERROR ("%s: Program error in function %s:\n%s\nTip: read above for entity information\n", PRVM_NAME, PRVM_GetString(prog->xfunction->s_name), string); @@ -141,7 +141,7 @@ void VM_objerror (void) if (prog->globaloffsets.self >= 0) { ed = PRVM_PROG_TO_EDICT(PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict); - PRVM_ED_Print(ed); + PRVM_ED_Print(ed, NULL); PRVM_ED_Free (ed); } @@ -446,28 +446,27 @@ float cvar (string) */ void VM_cvar (void) { - VM_SAFEPARMCOUNT(1,VM_cvar); - - PRVM_G_FLOAT(OFS_RETURN) = Cvar_VariableValue(PRVM_G_STRING(OFS_PARM0)); + char string[VM_STRINGTEMP_LENGTH]; + VM_SAFEPARMCOUNTRANGE(1,8,VM_cvar); + VM_VarString(0, string, sizeof(string)); + VM_CheckEmptyString(string); + PRVM_G_FLOAT(OFS_RETURN) = Cvar_VariableValue(string); } /* ================= VM_cvar_string -const string VM_cvar_string (string) +const string VM_cvar_string (string, ...) ================= */ void VM_cvar_string(void) { - const char *name; - VM_SAFEPARMCOUNT(1,VM_cvar_string); - - name = PRVM_G_STRING(OFS_PARM0); - - VM_CheckEmptyString(name); - - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(Cvar_VariableString(name)); + char string[VM_STRINGTEMP_LENGTH]; + VM_SAFEPARMCOUNTRANGE(1,8,VM_cvar_string); + VM_VarString(0, string, sizeof(string)); + VM_CheckEmptyString(string); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(Cvar_VariableString(string)); } @@ -475,32 +474,33 @@ void VM_cvar_string(void) ======================== VM_cvar_defstring -const string VM_cvar_defstring (string) +const string VM_cvar_defstring (string, ...) ======================== */ void VM_cvar_defstring (void) { - const char *name; - VM_SAFEPARMCOUNT(1,VM_cvar_string); - - name = PRVM_G_STRING(OFS_PARM0); - - VM_CheckEmptyString(name); - - PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(Cvar_VariableDefString(name)); + char string[VM_STRINGTEMP_LENGTH]; + VM_SAFEPARMCOUNTRANGE(1,8,VM_cvar_defstring); + VM_VarString(0, string, sizeof(string)); + VM_CheckEmptyString(string); + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(Cvar_VariableDefString(string)); } /* ================= VM_cvar_set -void cvar_set (string,string) +void cvar_set (string,string, ...) ================= */ void VM_cvar_set (void) { - VM_SAFEPARMCOUNT(2,VM_cvar_set); - - Cvar_Set(PRVM_G_STRING(OFS_PARM0), PRVM_G_STRING(OFS_PARM1)); + const char *name; + char string[VM_STRINGTEMP_LENGTH]; + VM_SAFEPARMCOUNTRANGE(2,8,VM_cvar_set); + VM_VarString(1, string, sizeof(string)); + name = PRVM_G_STRING(OFS_PARM0); + VM_CheckEmptyString(name); + Cvar_Set(name, string); } /* @@ -724,10 +724,6 @@ void VM_remove (void) } else PRVM_ED_Free (ed); -// if (ed == prog->edicts) -// PRVM_ERROR ("remove: tried to remove world"); -// if (PRVM_NUM_FOR_EDICT(ed) <= sv.maxclients) -// Host_Error("remove: tried to remove a client"); } /* @@ -1112,7 +1108,7 @@ void VM_eprint (void) { VM_SAFEPARMCOUNT(1,VM_eprint); - PRVM_ED_PrintNum (PRVM_G_EDICTNUM(OFS_PARM0)); + PRVM_ED_PrintNum (PRVM_G_EDICTNUM(OFS_PARM0), NULL); } /* @@ -1754,53 +1750,12 @@ void VM_strdecolorize(void) { char szNewString[VM_STRINGTEMP_LENGTH]; const char *szString; - size_t nCnt; - int nPos; - int nFillPos; - int bFinished; - nPos = 0; - nFillPos = 0; - nCnt = 0; - bFinished = 0; // Prepare Strings VM_SAFEPARMCOUNT(1,VM_strdecolorize); szString = PRVM_G_STRING(OFS_PARM0); - while(!bFinished) - { // Traverse through String - if( szString[nPos] == '\n' || szString[nPos] == '\r' || szString[nPos] <= 0) - { // String End Found - szNewString[nFillPos++] = szString[nPos]; - bFinished = 1; - } - else - if( szString[nPos] == STRING_COLOR_TAG) - { // Color Code Located - if( szString[nPos + 1] == STRING_COLOR_TAG) - { // Valid Characters to Include - szNewString[nFillPos++] = szString[nPos]; - nPos = nPos + 1; - szNewString[nFillPos++] = szString[nPos]; - } - else - if( szString[nPos + 1] >= '0' && szString[nPos + 1] <= '9' ) - { // Color Code Found; Increment Position - nPos = nPos + 1; - } - else - { // Unknown Color Code; Include - szNewString[nFillPos++] = szString[nPos]; - nPos = nPos + 1; - } - } - else - // Include Character - szNewString[nFillPos++] = szString[nPos]; - - // Increment Position - nPos = nPos + 1; - } + COM_StringDecolorize(szString, 0, szNewString, sizeof(szNewString), TRUE); PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(szNewString); } @@ -1818,56 +1773,62 @@ float strlennocol(string s) void VM_strlennocol(void) { const char *szString; - size_t nCnt; - int nPos; - int bFinished; - nPos = 0; - nCnt = 0; - bFinished = 0; + int nCnt; VM_SAFEPARMCOUNT(1,VM_strlennocol); szString = PRVM_G_STRING(OFS_PARM0); - while(!bFinished) - { // Count Characters - // SV_BroadcastPrintf("Position '%d'; Character '%c'; Length '%d'\n", nPos, szString[nPos], nCnt); + nCnt = COM_StringLengthNoColors(szString, 0, NULL); - if( szString[nPos] == '\n' || szString[nPos] == '\r' || szString[nPos] <= 0) - { // String End Found - // SV_BroadcastPrintf("Found End of String at '%d'\n", nPos); - bFinished = 1; - } - else - if( szString[nPos] == STRING_COLOR_TAG) - { // Color Code Located - if( szString[nPos + 1] == STRING_COLOR_TAG) - { // Increment Length; Skip Color Code - nCnt = nCnt + 1; - nPos = nPos + 1; - } - else - if( szString[nPos + 1] >= '0' && szString[nPos + 1] <= '9' ) - { // Color Code Found; Increment Position - // SV_BroadcastPrintf("Found Color Codes at '%d'\n", nPos); - nPos = nPos + 1; - } - else - { // Unknown Color Code; Increment Length! - nPos = nPos + 1; - nCnt = nCnt + 1; - } - } - else - // Increment String Length - nCnt = nCnt + 1; - - // Increment Position - nPos = nPos + 1; - } PRVM_G_FLOAT(OFS_RETURN) = nCnt; } +// DRESK - String to Uppercase and Lowercase +/* +========= +VM_strtolower + +string strtolower(string s) +========= +*/ +// string (string s) strtolower = #480; // returns passed in string in lowercase form +void VM_strtolower(void) +{ + char szNewString[VM_STRINGTEMP_LENGTH]; + const char *szString; + + // Prepare Strings + VM_SAFEPARMCOUNT(1,VM_strtolower); + szString = PRVM_G_STRING(OFS_PARM0); + + COM_ToLowerString(szString, szNewString, sizeof(szNewString) ); + + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(szNewString); +} + +/* +========= +VM_strtoupper + +string strtoupper(string s) +========= +*/ +// string (string s) strtoupper = #481; // returns passed in string in uppercase form +void VM_strtoupper(void) +{ + char szNewString[VM_STRINGTEMP_LENGTH]; + const char *szString; + + // Prepare Strings + VM_SAFEPARMCOUNT(1,VM_strtoupper); + szString = PRVM_G_STRING(OFS_PARM0); + + COM_ToUpperString(szString, szNewString, sizeof(szNewString) ); + + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(szNewString); +} + /* ========= VM_strcat @@ -2013,31 +1974,90 @@ int tokens[256]; void VM_tokenize (void) { const char *p; -#if 0 - size_t pos = 0; - char tokenbuf[MAX_INPUTLINE]; - size_t tokenlen; -#endif VM_SAFEPARMCOUNT(1,VM_tokenize); p = PRVM_G_STRING(OFS_PARM0); num_tokens = 0; - while(COM_ParseToken(&p, false)) + while(COM_ParseToken_VM_Tokenize(&p, false)) { if (num_tokens >= (int)(sizeof(tokens)/sizeof(tokens[0]))) break; -#if 0 - tokenlen = strlen(com_token) + 1; - if (pos + tokenlen > sizeof(tokenbuf)) - break; - tokens[num_tokens++] = PRVM_SetEngineString(tokenbuf + pos); - memcpy(tokenbuf + pos, com_token, tokenlen); - pos += tokenlen; -#else tokens[num_tokens++] = PRVM_SetTempString(com_token); -#endif + } + + PRVM_G_FLOAT(OFS_RETURN) = num_tokens; +} + +/* +========= +VM_tokenizebyseparator + +float tokenizebyseparator(string s, string separator1, ...) +========= +*/ +//float(string s, string separator1, ...) tokenizebyseparator = #479; // takes apart a string into individal words (access them with argv), returns how many +//this function returns the token preceding each instance of a separator (of +//which there can be multiple), and the text following the last separator +//useful for parsing certain kinds of data like IP addresses +//example: +//numnumbers = tokenizebyseparator("10.1.2.3", "."); +//returns 4 and the tokens "10" "1" "2" "3". +void VM_tokenizebyseparator (void) +{ + int j, k; + int numseparators; + int separatorlen[7]; + const char *separators[7]; + const char *p; + const char *token; + char tokentext[MAX_INPUTLINE]; + + VM_SAFEPARMCOUNTRANGE(2, 8,VM_tokenizebyseparator); + + p = PRVM_G_STRING(OFS_PARM0); + + numseparators = 0;; + for (j = 1;j < prog->argc;j++) + { + // skip any blank separator strings + const char *s = PRVM_G_STRING(OFS_PARM0+j*3); + if (!s[0]) + continue; + separators[numseparators] = s; + separatorlen[numseparators] = strlen(s); + numseparators++; + } + + num_tokens = 0; + j = 0; + + while (num_tokens < (int)(sizeof(tokens)/sizeof(tokens[0]))) + { + token = tokentext + j; + while (*p) + { + for (k = 0;k < numseparators;k++) + { + if (!strncmp(p, separators[k], separatorlen[k])) + { + p += separatorlen[k]; + break; + } + } + if (k < numseparators) + break; + if (j < (int)sizeof(tokentext)-1) + tokentext[j++] = *p; + p++; + } + if (j >= (int)sizeof(tokentext)) + break; + tokentext[j++] = 0; + tokens[num_tokens++] = PRVM_SetTempString(token); + if (!*p) + break; } PRVM_G_FLOAT(OFS_RETURN) = num_tokens; @@ -2186,15 +2206,15 @@ void VM_parseentitydata(void) VM_SAFEPARMCOUNT(2, VM_parseentitydata); - // get edict and test it + // get edict and test it ent = PRVM_G_EDICT(OFS_PARM0); if (ent->priv.required->free) PRVM_ERROR ("VM_parseentitydata: %s: Can only set already spawned entities (entity %i is free)!", PRVM_NAME, PRVM_NUM_FOR_EDICT(ent)); data = PRVM_G_STRING(OFS_PARM1); - // parse the opening brace - if (!COM_ParseTokenConsole(&data) || com_token[0] != '{' ) + // parse the opening brace + if (!COM_ParseToken_Simple(&data, false) || com_token[0] != '{' ) PRVM_ERROR ("VM_parseentitydata: %s: Couldn't parse entity data:\n%s", PRVM_NAME, data ); PRVM_ED_ParseEdict (data, ent); @@ -2522,7 +2542,7 @@ void VM_drawcharacter(void) return; } - DrawQ_String (pos[0], pos[1], &character, 1, scale[0], scale[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag); + DrawQ_String (pos[0], pos[1], &character, 1, scale[0], scale[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag, NULL, true); PRVM_G_FLOAT(OFS_RETURN) = 1; } @@ -2563,7 +2583,7 @@ void VM_drawstring(void) if(pos[2] || scale[2]) Con_Printf("VM_drawstring: z value%s from %s discarded\n",(pos[2] && scale[2]) ? "s" : " ",((pos[2] && scale[2]) ? "pos and scale" : (pos[2] ? "pos" : "scale"))); - DrawQ_String (pos[0], pos[1], string, 0, scale[0], scale[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag); + DrawQ_String (pos[0], pos[1], string, 0, scale[0], scale[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag, NULL, true); PRVM_G_FLOAT(OFS_RETURN) = 1; } /* @@ -2641,7 +2661,7 @@ void VM_drawfill(void) if(pos[2] || size[2]) Con_Printf("VM_drawfill: z value%s from %s discarded\n",(pos[2] && size[2]) ? "s" : " ",((pos[2] && size[2]) ? "pos and size" : (pos[2] ? "pos" : "size"))); - DrawQ_Pic(pos[0], pos[1], NULL, size[0], size[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM3), flag); + DrawQ_Fill(pos[0], pos[1], size[0], size[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM3), flag); PRVM_G_FLOAT(OFS_RETURN) = 1; } @@ -3596,7 +3616,9 @@ void VM_changeyaw (void) prvm_edict_t *ent; float ideal, current, move, speed; - VM_SAFEPARMCOUNT(0, VM_changeyaw); + // this is called (VERY HACKISHLY) by SV_MoveToGoal, so it can not use any + // parameters because they are the parameters to SV_MoveToGoal, not this + //VM_SAFEPARMCOUNT(0, VM_changeyaw); ent = PRVM_PROG_TO_EDICT(PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict); if (ent == prog->edicts) @@ -3750,15 +3772,40 @@ void VM_uncolorstring (void) PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(out); } +// #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS) +//strstr, without generating a new string. Use in conjunction with FRIK_FILE's substring for more similar strstr. +void VM_strstrofs (void) +{ + const char *instr, *match; + int firstofs; + VM_SAFEPARMCOUNTRANGE(2, 3, VM_strstrofs); + instr = PRVM_G_STRING(OFS_PARM0); + match = PRVM_G_STRING(OFS_PARM1); + firstofs = (prog->argc > 2)?PRVM_G_FLOAT(OFS_PARM2):0; + + if (firstofs && (firstofs < 0 || firstofs > (int)strlen(instr))) + { + PRVM_G_FLOAT(OFS_RETURN) = -1; + return; + } + + match = strstr(instr+firstofs, match); + if (!match) + PRVM_G_FLOAT(OFS_RETURN) = -1; + else + PRVM_G_FLOAT(OFS_RETURN) = match - instr; +} + //#222 string(string s, float index) str2chr (FTE_STRINGS) void VM_str2chr (void) { const char *s; VM_SAFEPARMCOUNT(2, VM_str2chr); s = PRVM_G_STRING(OFS_PARM0); - if((unsigned)PRVM_G_FLOAT(OFS_PARM1) > strlen(s)) - return; - PRVM_G_FLOAT(OFS_RETURN) = (unsigned char)s[(int)PRVM_G_FLOAT(OFS_PARM1)]; + if((unsigned)PRVM_G_FLOAT(OFS_PARM1) < strlen(s)) + PRVM_G_FLOAT(OFS_RETURN) = (unsigned char)s[(unsigned)PRVM_G_FLOAT(OFS_PARM1)]; + else + PRVM_G_FLOAT(OFS_RETURN) = 0; } //#223 string(float c, ...) chr2str (FTE_STRINGS) @@ -3773,14 +3820,222 @@ void VM_chr2str (void) PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(t); } +static int chrconv_number(int i, int base, int conv) +{ + i -= base; + switch (conv) + { + default: + case 5: + case 6: + case 0: + break; + case 1: + base = '0'; + break; + case 2: + base = '0'+128; + break; + case 3: + base = '0'-30; + break; + case 4: + base = '0'+128-30; + break; + } + return i + base; +} +static int chrconv_punct(int i, int base, int conv) +{ + i -= base; + switch (conv) + { + default: + case 0: + break; + case 1: + base = 0; + break; + case 2: + base = 128; + break; + } + return i + base; +} + +static int chrchar_alpha(int i, int basec, int baset, int convc, int convt, int charnum) +{ + //convert case and colour seperatly... + + i -= baset + basec; + switch (convt) + { + default: + case 0: + break; + case 1: + baset = 0; + break; + case 2: + baset = 128; + break; + + case 5: + case 6: + baset = 128*((charnum&1) == (convt-5)); + break; + } + + switch (convc) + { + default: + case 0: + break; + case 1: + basec = 'a'; + break; + case 2: + basec = 'A'; + break; + } + return i + basec + baset; +} +// #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS) +//bulk convert a string. change case or colouring. +void VM_strconv (void) +{ + int ccase, redalpha, rednum, len, i; + unsigned char resbuf[VM_STRINGTEMP_LENGTH]; + unsigned char *result = resbuf; + + VM_SAFEPARMCOUNTRANGE(3, 8, VM_strconv); + + ccase = PRVM_G_FLOAT(OFS_PARM0); //0 same, 1 lower, 2 upper + redalpha = PRVM_G_FLOAT(OFS_PARM1); //0 same, 1 white, 2 red, 5 alternate, 6 alternate-alternate + rednum = PRVM_G_FLOAT(OFS_PARM2); //0 same, 1 white, 2 red, 3 redspecial, 4 whitespecial, 5 alternate, 6 alternate-alternate + VM_VarString(3, (char *) resbuf, sizeof(resbuf)); + len = strlen((char *) resbuf); + + for (i = 0; i < len; i++, result++) //should this be done backwards? + { + if (*result >= '0' && *result <= '9') //normal numbers... + *result = chrconv_number(*result, '0', rednum); + else if (*result >= '0'+128 && *result <= '9'+128) + *result = chrconv_number(*result, '0'+128, rednum); + else if (*result >= '0'+128-30 && *result <= '9'+128-30) + *result = chrconv_number(*result, '0'+128-30, rednum); + else if (*result >= '0'-30 && *result <= '9'-30) + *result = chrconv_number(*result, '0'-30, rednum); + + else if (*result >= 'a' && *result <= 'z') //normal numbers... + *result = chrchar_alpha(*result, 'a', 0, ccase, redalpha, i); + else if (*result >= 'A' && *result <= 'Z') //normal numbers... + *result = chrchar_alpha(*result, 'A', 0, ccase, redalpha, i); + else if (*result >= 'a'+128 && *result <= 'z'+128) //normal numbers... + *result = chrchar_alpha(*result, 'a', 128, ccase, redalpha, i); + else if (*result >= 'A'+128 && *result <= 'Z'+128) //normal numbers... + *result = chrchar_alpha(*result, 'A', 128, ccase, redalpha, i); + + else if ((*result & 127) < 16 || !redalpha) //special chars.. + *result = *result; + else if (*result < 128) + *result = chrconv_punct(*result, 0, redalpha); + else + *result = chrconv_punct(*result, 128, redalpha); + } + *result = '\0'; + + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString((char *) resbuf); +} + +// #225 string(float chars, string s, ...) strpad (FTE_STRINGS) +void VM_strpad (void) +{ + char src[VM_STRINGTEMP_LENGTH]; + char destbuf[VM_STRINGTEMP_LENGTH]; + int pad; + VM_SAFEPARMCOUNTRANGE(1, 8, VM_strpad); + pad = PRVM_G_FLOAT(OFS_PARM0); + VM_VarString(1, src, sizeof(src)); + + // note: < 0 = left padding, > 0 = right padding, + // this is reverse logic of printf! + dpsnprintf(destbuf, sizeof(destbuf), "%*s", -pad, src); + + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(destbuf); +} + +// #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS) +//uses qw style \key\value strings +void VM_infoadd (void) +{ + const char *info, *key; + char value[VM_STRINGTEMP_LENGTH]; + char temp[VM_STRINGTEMP_LENGTH]; + + VM_SAFEPARMCOUNTRANGE(2, 8, VM_infoadd); + info = PRVM_G_STRING(OFS_PARM0); + key = PRVM_G_STRING(OFS_PARM1); + VM_VarString(2, value, sizeof(value)); + + strlcpy(temp, info, VM_STRINGTEMP_LENGTH); + + InfoString_SetValue(temp, VM_STRINGTEMP_LENGTH, key, value); + + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(temp); +} + +// #227 string(string info, string key) infoget (FTE_STRINGS) +//uses qw style \key\value strings +void VM_infoget (void) +{ + const char *info; + const char *key; + char value[VM_STRINGTEMP_LENGTH]; + + VM_SAFEPARMCOUNT(2, VM_infoget); + info = PRVM_G_STRING(OFS_PARM0); + key = PRVM_G_STRING(OFS_PARM1); + + InfoString_GetValue(info, key, value, VM_STRINGTEMP_LENGTH); + + PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(value); +} + //#228 float(string s1, string s2, float len) strncmp (FTE_STRINGS) +// also float(string s1, string s2) strcmp (FRIK_FILE) void VM_strncmp (void) { const char *s1, *s2; - VM_SAFEPARMCOUNT(1, VM_strncmp); + VM_SAFEPARMCOUNTRANGE(2, 3, VM_strncmp); s1 = PRVM_G_STRING(OFS_PARM0); s2 = PRVM_G_STRING(OFS_PARM1); - PRVM_G_FLOAT(OFS_RETURN) = strncmp(s1, s2, (size_t)PRVM_G_FLOAT(OFS_PARM2)); + if (prog->argc > 2) + { + PRVM_G_FLOAT(OFS_RETURN) = strncmp(s1, s2, (size_t)PRVM_G_FLOAT(OFS_PARM2)); + } + else + { + PRVM_G_FLOAT(OFS_RETURN) = strcmp(s1, s2); + } +} + +// #229 float(string s1, string s2) strcasecmp (FTE_STRINGS) +// #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS) +void VM_strncasecmp (void) +{ + const char *s1, *s2; + VM_SAFEPARMCOUNTRANGE(2, 3, VM_strncasecmp); + s1 = PRVM_G_STRING(OFS_PARM0); + s2 = PRVM_G_STRING(OFS_PARM1); + if (prog->argc > 2) + { + PRVM_G_FLOAT(OFS_RETURN) = strncasecmp(s1, s2, (size_t)PRVM_G_FLOAT(OFS_PARM2)); + } + else + { + PRVM_G_FLOAT(OFS_RETURN) = strcasecmp(s1, s2); + } } void VM_wasfreed (void)