X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=cmd.c;h=e8a275f545ee301d03aed0b7980a40b0c39d9a95;hb=ec5bfe9159477756e615cf1cd69dfb66ac75b9a2;hp=d94857655984e47d91cd23c2fe2c0b295c13edff;hpb=4fcf642ab8c87b9cd34580c69c2bccded2d8fd83;p=xonotic%2Fdarkplaces.git diff --git a/cmd.c b/cmd.c index d9485765..e8a275f5 100644 --- a/cmd.c +++ b/cmd.c @@ -181,7 +181,7 @@ void Cbuf_Execute (void) { i++; cmd_text.cursize -= i; - memcpy (cmd_text.data, text+i, cmd_text.cursize); + memmove (cmd_text.data, text+i, cmd_text.cursize); } // execute the command line @@ -518,19 +518,49 @@ cmd_source_t cmd_source; static cmd_function_t *cmd_functions; // possible commands to execute -static const char *Cmd_GetDirectCvarValue(const char *varname, cmdalias_t *alias) +static const char *Cmd_GetDirectCvarValue(const char *varname, cmdalias_t *alias, qboolean *is_multiple) { cvar_t *cvar; long argno; char *endptr; + if(is_multiple) + *is_multiple = false; + if(!varname || !*varname) return NULL; if(alias) { if(!strcmp(varname, "*")) + { + if(is_multiple) + *is_multiple = true; return Cmd_Args(); + } + else if(varname[strlen(varname) - 1] == '-') + { + argno = strtol(varname, &endptr, 10); + if(endptr == varname + strlen(varname) - 1) + { + // whole string is a number, apart from the - + const char *p = Cmd_Args(); + for(; argno > 1; --argno) + if(!COM_ParseToken_Console(&p)) + break; + if(p) + { + if(is_multiple) + *is_multiple = true; + + // kill pre-argument whitespace + for (;*p && *p <= ' ';p++) + ; + + return p; + } + } + } else { argno = strtol(varname, &endptr, 10); @@ -550,11 +580,63 @@ static const char *Cmd_GetDirectCvarValue(const char *varname, cmdalias_t *alias return NULL; } +qboolean Cmd_QuoteString(char *out, size_t outlen, const char *in, const char *quoteset) +{ + qboolean quote_quot = !!strchr(quoteset, '"'); + qboolean quote_backslash = !!strchr(quoteset, '\\'); + qboolean quote_dollar = !!strchr(quoteset, '$'); + + while(*in) + { + if(*in == '"' && quote_quot) + { + if(outlen <= 2) + { + *out++ = 0; + return false; + } + *out++ = '\\'; --outlen; + *out++ = '"'; --outlen; + } + else if(*in == '\\' && quote_backslash) + { + if(outlen <= 2) + { + *out++ = 0; + return false; + } + *out++ = '\\'; --outlen; + *out++ = '\\'; --outlen; + } + else if(*in == '$' && quote_dollar) + { + if(outlen <= 2) + { + *out++ = 0; + return false; + } + *out++ = '$'; --outlen; + *out++ = '$'; --outlen; + } + else + { + if(outlen <= 1) + { + *out++ = 0; + return false; + } + *out++ = *in; --outlen; + } + ++in; + } + *out++ = 0; + return true; +} + static const char *Cmd_GetCvarValue(const char *var, size_t varlen, cmdalias_t *alias) { static char varname[MAX_INPUTLINE]; static char varval[MAX_INPUTLINE]; - char *p; const char *varstr; char *varfunc; @@ -578,14 +660,16 @@ static const char *Cmd_GetCvarValue(const char *var, size_t varlen, cmdalias_t * varstr = NULL; - // Exception: $* doesn't use the quoted form by default - if(!strcmp(varname, "*")) - varfunc = "asis"; - if(varname[0] == '$') - varstr = Cmd_GetDirectCvarValue(Cmd_GetDirectCvarValue(varname + 1, alias), alias); + varstr = Cmd_GetDirectCvarValue(Cmd_GetDirectCvarValue(varname + 1, alias, NULL), alias, NULL); else - varstr = Cmd_GetDirectCvarValue(varname, alias); + { + qboolean is_multiple = false; + // Exception: $* and $n- don't use the quoted form by default + varstr = Cmd_GetDirectCvarValue(varname, alias, &is_multiple); + if(is_multiple) + varfunc = "asis"; + } if(!varstr) { @@ -599,34 +683,8 @@ static const char *Cmd_GetCvarValue(const char *var, size_t varlen, cmdalias_t * if(!varfunc || !strcmp(varfunc, "q")) // note: quoted form is default, use "asis" to override! { // quote it so it can be used inside double quotes - // we just need to replace " by \" - p = varval; - while(*varstr) - { - if(*varstr == '"') - { - if(p - varval >= (ssize_t)(sizeof(varval) - 2)) - break; - *p++ = '\\'; - *p++ = '"'; - } - else if(*varstr == '\\') - { - if(p - varval >= (ssize_t)(sizeof(varval) - 2)) - break; - *p++ = '\\'; - *p++ = '\\'; - } - else - { - if(p - varval >= (ssize_t)(sizeof(varval) - 1)) - break; - *p++ = *varstr; - } - ++varstr; - } - *p++ = 0; - //Con_Printf("quoted form: %s\n", varval); + // we just need to replace " by \", and of course, double backslashes + Cmd_QuoteString(varval, sizeof(varval), varstr, "\"\\"); return varval; } else if(!strcmp(varfunc, "asis")) @@ -681,7 +739,8 @@ static void Cmd_PreprocessString( const char *intext, char *outtext, unsigned ma // alias parameter, where the name of the alias is $0, the first // parameter is $1 and so on; as a special case, $* inserts all // parameters, without extra quoting, so one can use $* to just - // pass all parameters around + // pass all parameters around. All parameters starting from $n + // can be referred to as $n- (so $* is equivalent to $1-). // // Note: when expanding an alias, cvar expansion is done in the SAME step // as alias expansion so that alias parameters or cvar values containing @@ -727,7 +786,7 @@ static void Cmd_PreprocessString( const char *intext, char *outtext, unsigned ma eat = varlen + 1; } } else { - varlen = strspn(in, "*0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"); + varlen = strspn(in, "*0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-"); val = Cmd_GetCvarValue(in, varlen, alias); eat = varlen; } @@ -766,8 +825,6 @@ static void Cmd_ExecuteAlias (cmdalias_t *alias) { static char buffer[ MAX_INPUTLINE + 2 ]; static char buffer2[ MAX_INPUTLINE * 2 + 2 ]; - char *q; - const char *p; Cmd_PreprocessString( alias->value, buffer, sizeof(buffer) - 2, alias ); // insert at start of command buffer, so that aliases execute in order // (fixes bug introduced by Black on 20050705) @@ -775,14 +832,7 @@ static void Cmd_ExecuteAlias (cmdalias_t *alias) // Note: Cbuf_PreprocessString will be called on this string AGAIN! So we // have to make sure that no second variable expansion takes place, otherwise // alias parameters containing dollar signs can have bad effects. - for(p = buffer, q = buffer2; *p; ) - { - if(*p == '$') - *q++ = '$'; - *q++ = *p++; - } - *q++ = 0; - + Cmd_QuoteString(buffer2, sizeof(buffer2), buffer, "$"); Cbuf_InsertText( buffer2 ); }