- size_t pos, cmdsize = 0, start = 0;
- qbool command = false, lookahead = false;
- qbool quotes = false, comment = false;
- qbool escaped = false;
-
- /*
- * The Quake command-line is super basic. It can be entered in the console
- * or in config files. A semicolon is used to terminate a command and chain
- * them together. Otherwise, a newline delineates command input.
- *
- * In most engines, the Quake command-line is a simple linear text buffer that
- * is parsed when it executes. In Darkplaces, we use a linked list of command
- * input and parse the input on the spot.
- *
- * This was done because Darkplaces allows multiple command interpreters on the
- * same thread. Previously, each interpreter maintained its own buffer and this
- * caused problems related to execution order, and maintaining a single simple
- * buffer for all interpreters makes it non-trivial to keep track of which
- * command should execute on which interpreter.
- */
-
- // Run until command and lookahead are both true, or until we run out of input.
- for (pos = 0; (*input)[pos]; pos++)
- {
- // Look for newlines and semicolons. Ignore semicolons in quotes.
- switch((*input)[pos])
- {
- case '\r':
- case '\n':
- command = false;
- comment = false;
- break;
- default:
- if(!comment) // Not a newline so far. Still not a valid command yet.
- {
- if(!quotes && (*input)[pos] == ';') // Ignore semicolons in quotes.
- command = false;
- else if (ISCOMMENT((*input), pos)) // Comments
- {
- comment = true;
- command = false;
- }
- else
- {
- command = true;
- if(!lookahead)
- {
- if(!cmdsize)
- start = pos;
- cmdsize++;
- }
-
- switch((*input)[pos])
- {
- case '"':
- if (!escaped)
- quotes = !quotes;
- else
- escaped = false;
- break;
- case '\\':
- if (!escaped && quotes)
- escaped = true;
- else if (escaped)
- escaped = false;
- break;
- }
- }
- }
- }
- if(cmdsize && !command)
- lookahead = true;