--- a/scriptreader.cxx Sun Jul 15 19:01:47 2012 +0300 +++ b/scriptreader.cxx Mon Jul 16 04:07:15 2012 +0300 @@ -54,20 +54,22 @@ } ScriptReader::ScriptReader (str path) { - atnewline = false; - filepath = path; if (!(fp = fopen (path, "r"))) { error ("couldn't open %s for reading!\n", path.chars ()); exit (1); } + filepath = path; curline = 1; curchar = 1; pos = 0; token = ""; + atnewline = false; + commentmode = 0; } ScriptReader::~ScriptReader () { + FinalChecks (); fclose (fp); } @@ -90,12 +92,66 @@ return c[0]; } +char ScriptReader::PeekChar (int offset) { + // Store current position + long curpos = ftell (fp); + + // Forward by offset + fseek (fp, offset, SEEK_CUR); + + // Read the character + char* c = (char*)malloc (sizeof (char)); + if (!fread (c, sizeof (char), 1, fp)) + return 0; + + // Rewind back + fseek (fp, curpos, SEEK_SET); + + return c[0]; +} + // true if was found, false if not. bool ScriptReader::Next () { str tmp = ""; + while (!feof (fp)) { + // Check if the next token possibly starts a comment. + if (PeekChar () == '/' && !tmp.len()) { + char c2 = PeekChar (1); + // C++-style comment + if (c2 == '/') + commentmode = 1; + else if (c2 == '*') + commentmode = 2; + + // We don't need to actually read in the + // comment characters, since they will get + // ignored due to comment mode anyway. + } + c = ReadChar (); + // If this is a comment we're reading, check if this character + // gets the comment terminated, otherwise ignore it. + if (commentmode > 0) { + if (commentmode == 1 && c == '\n') { + // C++-style comments are terminated by a newline + commentmode = 0; + continue; + } else if (commentmode == 2 && c == '*') { + // C-style comments are terminated by a `*/` + if (PeekChar() == '/') { + commentmode = 0; + // Now the char has to be read in since we + // no longer are reading a comment + ReadChar (); + } + } + + // Otherwise, ignore it. + continue; + } + // Non-alphanumber characters (sans underscore) break the word too. // If there was prior data, the delimeter pushes the cursor back so // that the next character will be the same delimeter. If there isn't, @@ -243,4 +299,13 @@ case RETURNVAL_STRING: MustString (); break; case RETURNVAL_BOOLEAN: MustBool (); break; } +} + +// Checks to be performed at the end of file +void ScriptReader::FinalChecks () { + // If comment mode is 2 by the time the file ended, the + // comment was left unterminated. 1 is no problem, since + // it's terminated by newlines anyway. + if (commentmode == 2) + ParserError ("unterminated `/*`-style comment"); } \ No newline at end of file