123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362 |
- #include "cmdlib.h"
- #include "filelib.h"
- #include "messages.h"
- #include "log.h"
- #include "scriplib.h"
- char g_token[MAXTOKEN];
- char g_TXcommand;
- typedef struct
- {
- char filename[_MAX_PATH];
- char* buffer;
- char* script_p;
- char* end_p;
- int line;
- }
- script_t;
- #define MAX_INCLUDES 8
- static script_t s_scriptstack[MAX_INCLUDES];
- script_t* s_script;
- int s_scriptline;
- bool s_endofscript;
- bool s_tokenready; // only true if UnGetToken was just called
- // AddScriptToStack
- // LoadScriptFile
- // ParseFromMemory
- // UnGetToken
- // EndOfScript
- // GetToken
- // TokenAvailable
- // =====================================================================================
- // AddScriptToStack
- // =====================================================================================
- static void AddScriptToStack(const char* const filename)
- {
- int size;
- s_script++;
- if (s_script == &s_scriptstack[MAX_INCLUDES])
- Error("s_script file exceeded MAX_INCLUDES");
- strcpy_s(s_script->filename, filename);
- size = LoadFile(s_script->filename, (char**)&s_script->buffer);
- Log("Entering %s\n", s_script->filename);
- s_script->line = 1;
- s_script->script_p = s_script->buffer;
- s_script->end_p = s_script->buffer + size;
- }
- // =====================================================================================
- // LoadScriptFile
- // =====================================================================================
- void LoadScriptFile(const char* const filename)
- {
- s_script = s_scriptstack;
- AddScriptToStack(filename);
- s_endofscript = false;
- s_tokenready = false;
- }
- // =====================================================================================
- // ParseFromMemory
- // =====================================================================================
- void ParseFromMemory(char* buffer, const int size)
- {
- s_script = s_scriptstack;
- s_script++;
- if (s_script == &s_scriptstack[MAX_INCLUDES])
- Error("s_script file exceeded MAX_INCLUDES");
- strcpy_s(s_script->filename, "memory buffer");
- s_script->buffer = buffer;
- s_script->line = 1;
- s_script->script_p = s_script->buffer;
- s_script->end_p = s_script->buffer + size;
- s_endofscript = false;
- s_tokenready = false;
- }
- // =====================================================================================
- // UnGetToken
- /*
- * Signals that the current g_token was not used, and should be reported
- * for the next GetToken. Note that
- *
- * GetToken (true);
- * UnGetToken ();
- * GetToken (false);
- *
- * could cross a line boundary.
- */
- // =====================================================================================
- void UnGetToken()
- {
- s_tokenready = true;
- }
- // =====================================================================================
- // EndOfScript
- // =====================================================================================
- bool EndOfScript(const bool crossline)
- {
- if (!crossline)
- Error("Line %i is incomplete (did you place a \" inside an entity string?) \n", s_scriptline);
- if (!strcmp(s_script->filename, "memory buffer"))
- {
- s_endofscript = true;
- return false;
- }
- free(s_script->buffer);
- if (s_script == s_scriptstack + 1)
- {
- s_endofscript = true;
- return false;
- }
- s_script--;
- s_scriptline = s_script->line;
- Log("returning to %s\n", s_script->filename);
- return GetToken(crossline);
- }
- // =====================================================================================
- // GetToken
- // =====================================================================================
- bool GetToken(const bool crossline)
- {
- char *token_p;
- if (s_tokenready) // is a g_token allready waiting?
- {
- s_tokenready = false;
- return true;
- }
- if (s_script->script_p >= s_script->end_p)
- return EndOfScript(crossline);
- // skip space
- skipspace:
- while (*s_script->script_p <= 32)
- {
- if (s_script->script_p >= s_script->end_p)
- return EndOfScript(crossline);
- if (*s_script->script_p++ == '\n')
- {
- if (!crossline)
- Error("Line %i is incomplete (did you place a \" inside an entity string?) \n", s_scriptline);
- s_scriptline = s_script->line++;
- }
- }
- if (s_script->script_p >= s_script->end_p)
- return EndOfScript(crossline);
- // comment fields
- if (*s_script->script_p == ';' || *s_script->script_p == '#' || // semicolon and # is comment field
- (*s_script->script_p == '/' && *((s_script->script_p) + 1) == '/')) // also make // a comment field
- {
- if (!crossline)
- Error("Line %i is incomplete (did you place a \" inside an entity string?) \n", s_scriptline);
- //ets+++
- if (*s_script->script_p == '/')
- s_script->script_p++;
- if (s_script->script_p[1] == 'T' && s_script->script_p[2] == 'X')
- g_TXcommand = s_script->script_p[3]; // AR: "//TX#"-style comment
- //ets---
- while (*s_script->script_p++ != '\n')
- {
- if (s_script->script_p >= s_script->end_p)
- return EndOfScript(crossline);
- }
- //ets+++
- s_scriptline = s_script->line++; // AR: this line was missing
- //ets---
- goto skipspace;
- }
- // copy g_token
- token_p = g_token;
- if (*s_script->script_p == '"')
- {
- // quoted token
- s_script->script_p++;
- while (*s_script->script_p != '"')
- {
- *token_p++ = *s_script->script_p++;
- if (s_script->script_p == s_script->end_p)
- break;
- if (token_p == &g_token[MAXTOKEN])
- Error("Token too large on line %i\n", s_scriptline);
- }
- s_script->script_p++;
- }
- else
- {
- // regular token
- while (*s_script->script_p > 32 && *s_script->script_p != ';')
- {
- *token_p++ = *s_script->script_p++;
- if (s_script->script_p == s_script->end_p)
- break;
- if (token_p == &g_token[MAXTOKEN])
- Error("Token too large on line %i\n", s_scriptline);
- }
- }
- *token_p = 0;
- if (!strcmp(g_token, "$include"))
- {
- GetToken(false);
- AddScriptToStack(g_token);
- return GetToken(crossline);
- }
- return true;
- }
- #if 0
- // AJM: THIS IS REDUNDANT
- // =====================================================================================
- // ParseWadToken
- // basically the same as gettoken, except it isnt limited by MAXTOKEN and is
- // specificaly designed to parse out the wadpaths from the wad keyvalue and dump
- // them into the wadpaths list
- // this was implemented as a hack workaround for Token Too Large errors caused by
- // having long wadpaths or lots of wads in the map editor.
- extern void PushWadPath(const char* const path, bool inuse);
- // =====================================================================================
- void ParseWadToken(const bool crossline)
- {
- // code somewhat copied from GetToken()
- int i, j;
- char* token_p;
- char temp[_MAX_PATH];
- if (s_script->script_p >= s_script->end_p)
- return;
- // skip space
- while (*s_script->script_p <= 32)
- {
- if (s_script->script_p >= s_script->end_p)
- return;
- if (*s_script->script_p++ == '\n')
- {
- if (!crossline)
- Error("Line %i is incomplete (did you place a \" inside an entity string?) \n", s_scriptline);
- s_scriptline = s_script->line++;
- }
- }
- // EXPECT A QUOTE
- if (*s_script->script_p++ != '"')
- Error("Line %i: Expected a wadpaths definition, got '%s'\n", s_scriptline, *--s_script->script_p);
- // load wadpaths manually
- bool endoftoken = false;
- for (i = 0; !endoftoken; i++)
- {
- // get the path
- for (j = 0; ; j++)
- {
- token_p = ++s_script->script_p;
-
- // assert max path length
- if (j > _MAX_PATH)
- Error("Line %i: Wadpath definition %i is too long (%s)\n", s_scriptline, temp);
- if (*token_p == '\n')
- Error("Line %i: Expected a wadpaths definition, got linebreak\n", s_scriptline);
- if (*token_p == '"') // end of wadpath definition
- {
- if (i == 0 && j == 0) // no wadpaths!
- {
- Warning("No wadpaths specified.\n");
- return;
- }
- endoftoken = true;
- break;
- }
- if (*token_p == ';') // end of this wadpath
- break;
- temp[j] = *token_p;
- temp[j + 1] = 0;
- }
- // push it into the list
- PushWadPath(temp, true);
- temp[0] = 0;
- }
- for (; *s_script->script_p != '\n'; s_script->script_p++)
- {
- }
- }
- #endif
- // =====================================================================================
- // TokenAvailable
- // returns true if there is another token on the line
- // =====================================================================================
- bool TokenAvailable()
- {
- char *search_p;
- search_p = s_script->script_p;
- if (search_p >= s_script->end_p)
- return false;
- while (*search_p <= 32)
- {
- if (*search_p == '\n')
- return false;
- search_p++;
- if (search_p == s_script->end_p)
- return false;
- }
- if (*search_p == ';')
- return false;
- return true;
- }
|