From f78ec56975a17c28574022cbda5a7a8408aa1357 Mon Sep 17 00:00:00 2001 From: Brian Koropoff Date: Sun, 3 Mar 2002 08:29:28 +0000 Subject: [PATCH] Added escape characters, the tag to ignore tags enclosed within it, and generally cleaned the parser up. If a line begins with |, it will be stripped off by the tokenizer and no tags or escape characters will be processed. Commands stuffed into the console from the server are prepended with | to ensure backward compatibility. This can also be used anywhere backward compatibility is needed, such as where info strings are stuffed into the console, or as an alternative to using escape characters in the entire string. --- libs/console/client.c | 2 + libs/util/cmd.c | 130 +++++++++++++++++++++++++++--------------- qw/source/cl_parse.c | 1 + 3 files changed, 86 insertions(+), 47 deletions(-) diff --git a/libs/console/client.c b/libs/console/client.c index 96e387cff..8af5bc716 100644 --- a/libs/console/client.c +++ b/libs/console/client.c @@ -288,6 +288,8 @@ C_ExecLine (const char *line) { if (line[0] == '/' && line [1] == '/') goto no_lf; + else if (line[0] == '|') + Cbuf_AddText (line); else if (line[0] == '\\' || line[0] == '/') Cbuf_AddText (line + 1); else if (cl_chatmode->int_val != 1 && CheckForCommand (line)) diff --git a/libs/util/cmd.c b/libs/util/cmd.c index 91e4bd248..8b8bce881 100644 --- a/libs/util/cmd.c +++ b/libs/util/cmd.c @@ -411,29 +411,34 @@ Cmd_Args (int start) int Cmd_GetToken (const char *str) { int i, squote, dquote; + /* Only stop on comments at the beginning of tokens */ + if (!strncmp(str, "//", 2)) + return 0; for (i = 0, squote = 0, dquote = 0; i <= strlen(str); i++) { - if (!strncmp(str+i, "//", 2) && !dquote && !squote) // When we hit a comment, just stop - return 0; + /* If we find a comment in the middle of a token, end the token + so it will be picked up on the next call */ + if (!strncmp(str+i, "//", 2) && !dquote && !squote) + break; if (str[i] == 0) { - if (dquote) { // We never found another quote, backtrack - for (; str[i] != '"'; i--); - dquote = 0; - continue; - } - else if (squote) { - for (; str[i] != '\''; i--); - squote = 0; - continue; - } - else // End of string, this token is done - break; + if (dquote) { // We never found another quote, backtrack + for (; str[i] != '"'; i--); + dquote = 0; + continue; + } + else if (squote) { + for (; str[i] != '\''; i--); + squote = 0; + continue; + } + else // End of string, this token is done + break; } - else if (str[i] == '\'' && !dquote) { + else if (str[i] == '\'' && (!i || str[i-1] != '\\') && !dquote) { if (i) // If not at start of string, we must be at the end of a token break; squote = 1; } - else if (str[i] == '"' && !squote) { + else if (str[i] == '"' && (!i || str[i-1] != '\\') && !squote) { if (i) // Start new token break; dquote = 1; @@ -451,7 +456,7 @@ int tag_special = 0; struct stable_s {char a, b;} stable1[] = { -// {'\\',0x0D}, // Fake message + {'f', 0x0D}, // Fake message {'[', 0x90}, // Gold braces {']', 0x91}, {'(', 0x80}, // Scroll bar characters @@ -469,55 +474,79 @@ struct stable_s {char a, b;} stable1[] = {'B', 0x89}, {'a', 0x7F}, // White arrow {'A', 0x8D}, // Brown arrow -// {'0', 0x92}, // Gold numbers -// {'1', 0x93}, -// {'2', 0x94}, -// {'3', 0x95}, -// {'4', 0x96}, -// {'5', 0x97}, -// {'6', 0x98}, -// {'7', 0x99}, -// {'8', 0x9A}, -// {'9', 0x9B}, -// {'n', '\n'}, // Newline! {0, 0} }; void Cmd_ProcessTags (dstring_t *dstr) { - int close = 0, i, n, c; + int close = 0, ignore = 0, i, n, c; char *str = dstr->str; for (i = 0; i < strlen(str); i++) { - if (str[i] == '<') { + if (str[i] == '<' && (!i || str[i-1] != '\\')) { close = 0; - for (n = 0; str[i+n] != '>'; n++) + for (n = 1; str[i+n] != '>' || str[i+n-1] == '\\'; n++) if (str[n] == 0) return; if (str[i+1] == '/') close = 1; - if (!strncmp(str+i+close+1, "g", 1)) - tag_gold = tag_gold > 0 && close ? tag_gold - 1 : tag_gold + 1; - if (!strncmp(str+i+close+1, "b", 1)) - tag_shift = tag_shift > 0 && close ? tag_shift - 1 : tag_shift + 1; - if (!strncmp(str+i+close+1, "s", 1)) - tag_special = tag_special > 0 && close ? tag_special - 1 : tag_special + 1; + if (!strncmp(str+i+close+1, "i", 1)) { + if (ignore && !close) // If we are ignoring, ignore a non close + continue; + else if (close && ignore) // If we are closing, turn off ignore + ignore--; + else if (!close) + ignore++; // Otherwise, turn ignore on + } + else if (ignore) // If ignore isn't being changed and we are ignore, go on + continue; + else if (!strncmp(str+i+close+1, "g", 1)) + tag_gold = close ? tag_gold - 1 : tag_gold + 1; + else if (!strncmp(str+i+close+1, "b", 1)) + tag_shift = close ? tag_shift - 1 : tag_shift + 1; + else if (!strncmp(str+i+close+1, "s", 1)) + tag_special = close ? tag_special - 1 : tag_special + 1; + if (tag_gold < 0) + tag_gold = 0; + if (tag_shift < 0) + tag_shift = 0; + if (tag_special < 0) + tag_special = 0; dstring_snip(dstr, i, n+1); i--; continue; } c = str[i]; - - if (tag_gold && c >='0' && c <= '9') - c = (str[i] += (146 - '0')); - if (tag_special) - for (n = 0; stable1[n].a; n++) - if (c == stable1[n].a) - c = str[i] = stable1[n].b; - if (tag_shift && c < 128) - c = (str[i] += 128); + /* This ignores escape characters, unless it is itself escaped */ + if (c == '\\' && (!i || str[i-1] != '\\')) + continue; + else if (tag_gold && c >='0' && c <= '9') + c = (str[i] += (146 - '0')); + else if (tag_special) { + for (n = 0; stable1[n].a; n++) + if (c == stable1[n].a) + c = str[i] = stable1[n].b; + } + else if (tag_shift && c < 128) + c = (str[i] += 128); } } +void Cmd_ProcessEscapes (dstring_t *dstr) { + int i; + char *str = dstr->str; + + for (i = 0; i < strlen(str); i++) { + if (str[i] == '\\' && str[i+1]) { + dstring_snip(dstr, i, 1); + if (str[i] == '\\') + i++; + if (str[i] == 'n') + str[i] = '\n'; + i--; + } + } +} + void Cmd_TokenizeString (const char *text) { int i = 0, n, len = 0, quotes = 0, space; const char *str = text; @@ -526,6 +555,10 @@ void Cmd_TokenizeString (const char *text) { tag_shift = 0; tag_gold = 0; tag_special = 0; + printf("String in: %s\n", text); + if (text[0] == '|') + str++; + printf("Tokenizing: %s\n", str); while (strlen(str + i)) { space = 0; while (isspace(str[i])) { @@ -559,7 +592,10 @@ void Cmd_TokenizeString (const char *text) { quotes = 1; } dstring_insert(cmd_argv[cmd_argc-1], str + i, len, 0); - Cmd_ProcessTags(cmd_argv[cmd_argc-1]); + if (text[0] != '|') { // Lines beginning with | are not modified + Cmd_ProcessTags(cmd_argv[cmd_argc-1]); + Cmd_ProcessEscapes(cmd_argv[cmd_argc-1]); + } i += len + quotes; /* If we ended on a quote, skip it */ } /* Now we must reconstruct cmd_args */ diff --git a/qw/source/cl_parse.c b/qw/source/cl_parse.c index ccb9a0be8..775a4f771 100644 --- a/qw/source/cl_parse.c +++ b/qw/source/cl_parse.c @@ -1208,6 +1208,7 @@ CL_ParseServerMessage (void) case svc_stufftext: s = MSG_ReadString (net_message); Con_DPrintf ("stufftext: %s\n", s); + Cbuf_AddText ("|"); // Make command be executed in a backward-compatible fashion Cbuf_AddText (s); break;