Sat, 14 Jul 2012 02:16:48 +0300
Improved error handling; added parser warnings
commands.cxx | file | annotate | diff | comparison | revisions | |
parser.cxx | file | annotate | diff | comparison | revisions | |
scriptreader.cxx | file | annotate | diff | comparison | revisions | |
scriptreader.h | file | annotate | diff | comparison | revisions |
--- a/commands.cxx Sat Jul 14 01:49:32 2012 +0300 +++ b/commands.cxx Sat Jul 14 02:16:48 2012 +0300 @@ -48,6 +48,7 @@ CommandDef* g_CommDef; +#define MAX void ReadCommands () { ScriptReader* r = new ScriptReader ((char*)"commands.def"); g_CommDef = NULL; @@ -57,6 +58,11 @@ while (r->Next()) { CommandDef* comm = new CommandDef; + // Any more than 4 is a warning, any less is an error. + unsigned int c = r->token.count (const_cast<char*> (":")); + if (c < 4) + r->ParserError ("not enough parameters: got %d, expected 4", c); + int n = 0; str t = ""; for (unsigned int u = 0; u < r->token.len(); u++) { @@ -89,7 +95,7 @@ else if (!t.compare ("bool")) comm->returnvalue = RETURNVAL_BOOLEAN; else - r->ParseError ("bad return value type `%s`", t.chars()); + r->ParserError ("bad return value type `%s`", t.chars()); break; case 3: // Num args @@ -99,6 +105,9 @@ // Max args comm->maxargs = i; break; + default: + r->ParserWarning ("too many parameters"); + break; } n++;
--- a/parser.cxx Sat Jul 14 01:49:32 2012 +0300 +++ b/parser.cxx Sat Jul 14 02:16:48 2012 +0300 @@ -51,7 +51,7 @@ #define TOKEN_CHARS token.chars() #define TOKEN_IS(s) !token.compare (s) #define MUST_TOPLEVEL if (g_CurMode != MODE_TOPLEVEL) \ - ParseError ("%ss may only be defined at top level!", token.chars()); + ParserError ("%ss may only be defined at top level!", token.chars()); int g_NumStates = 0; int g_NumEvents = 0; @@ -66,7 +66,7 @@ // First ensure that the file can be opened FILE* newfile = fopen (token.chars(), "r"); if (!newfile) - ParseError ("couldn't open included file `%s`!", token.chars()); + ParserError ("couldn't open included file `%s`!", token.chars()); fclose (newfile); ScriptReader* newreader = new ScriptReader (token.chars()); newreader->BeginParse (w); @@ -79,7 +79,7 @@ // State name must be a word. if (statename.first (" ") != statename.len()) - ParseError ("state name must be a single word! got `%s`", (char*)statename); + ParserError ("state name must be a single word! got `%s`", (char*)statename); // Must end in a colon MustNext (":"); @@ -100,7 +100,7 @@ EventDef* e = FindEventByName (token); if (!e) - ParseError ("bad event! got `%s`\n", token.chars()); + ParserError ("bad event! got `%s`\n", token.chars()); MustNext ("{"); @@ -118,15 +118,15 @@ g_CurMode = MODE_TOPLEVEL; break; default: - ParseError ("unexpected `}`"); + ParserError ("unexpected `}`"); } } else { - ParseError ("unknown keyword `%s`!", TOKEN_CHARS); + ParserError ("unknown keyword `%s`!", TOKEN_CHARS); } } if (g_CurMode != MODE_TOPLEVEL) - ParseError ("script did not end at top level! did you forget a `}`?\n"); + ParserError ("script did not end at top level! did you forget a `}`?\n"); /* // State
--- a/scriptreader.cxx Sat Jul 14 01:49:32 2012 +0300 +++ b/scriptreader.cxx Sat Jul 14 02:16:48 2012 +0300 @@ -53,9 +53,11 @@ return false; } -ScriptReader::ScriptReader (char* path) { +ScriptReader::ScriptReader (str path) { + atnewline = false; + filepath = path; if (!(fp = fopen (path, "r"))) { - error ("couldn't open %s for reading!\n", path); + error ("couldn't open %s for reading!\n", path.chars ()); exit (1); } @@ -73,9 +75,14 @@ if (!fread (c, sizeof (char), 1, fp)) return 0; - // If we just read a new line, increase current line number counter. + // We're at a newline, thus next char read will begin the next line + if (atnewline) { + atnewline = false; + curline++; + } + if (c[0] == '\n') - curline++; + atnewline = true; return c[0]; } @@ -157,17 +164,28 @@ void ScriptReader::MustNext (const char* c) { if (!Next()) { if (strlen (c)) - ParseError ("expected `%s`, reached end of file instead\n", c); + ParserError ("expected `%s`, reached end of file instead\n", c); else - ParseError ("expected a token, reached end of file instead\n"); + ParserError ("expected a token, reached end of file instead\n"); } if (strlen (c) && token.compare (c) != 0) { - ParseError ("expected `%s`, got `%s` instead", c, token.chars()); + ParserError ("expected `%s`, got `%s` instead", c, token.chars()); } } -void ScriptReader::ParseError (const char* message, ...) { +void ScriptReader::ParserError (const char* message, ...) { + PERFORM_FORMAT (message, outmessage); + ParserMessage ("\nParse error\n", outmessage); + exit (1); +} + +void ScriptReader::ParserWarning (const char* message, ...) { PERFORM_FORMAT (message, outmessage); - error ("Parse error on line %d:\n%s\n", curline, outmessage); + ParserMessage ("Warning: ", outmessage); +} + +void ScriptReader::ParserMessage (const char* header, char* message) { + fprintf (stderr, "%sIn file %s, on line %d: %s\n", + header, filepath.chars(), curline, message); } \ No newline at end of file
--- a/scriptreader.h Sat Jul 14 01:49:32 2012 +0300 +++ b/scriptreader.h Sat Jul 14 02:16:48 2012 +0300 @@ -56,21 +56,25 @@ // ==================================================================== // MEMBERS FILE* fp; + str filepath; unsigned int pos; unsigned int curline; str token; bool tokenquoted; + bool atnewline; // ==================================================================== // METHODS - ScriptReader (char* path); + ScriptReader (str path); ~ScriptReader (); char ReadChar (); bool Next (); str PeekNext (); void Seek (unsigned int n, int origin); void MustNext (const char* c = ""); - void ParseError (const char* message, ...); + void ParserError (const char* message, ...); + void ParserWarning (const char* message, ...); + void ParserMessage (const char* header, char* message); void BeginParse (ObjWriter* w); };