// // Copyright (C) 1996 Brian Murray // // You may distribute under the terms of the GNU General Public // License as specified in the COPYING file. // // $Id: TokenParser.C,v 1.1 1996/11/17 09:14:41 ben Exp $ #include #include #include #include #define TOKENPARSER_QUOTE '"' #define TOKENPARSER_COMMENT '#' #define abTRUE 1 #define abFALSE 0 #define abNULL 0 TokenParser::TokenParser(const char* fileName, int maxLineLen, int maxArgs) : _maxArgs(maxArgs), _maxLineLen(maxLineLen) { _args = new char*[maxArgs]; _lineBuffer = new char[maxLineLen]; _fileName = strdup(fileName); _file = fopen(fileName, "rt"); if (!_file) _errno = errno; _lineNo = 0; } TokenParser::~TokenParser(void) { if (_file) fclose(_file); delete[] _fileName; delete[] _lineBuffer; delete[] _args; } TokenParser::ParserStatus TokenParser::readLine(void) { if (!_file) return FATAL_ERROR; do { _lineNo++; if (fgets(_lineBuffer, _maxLineLen, _file) == abNULL) { if (feof(_file)) return FINISHED; else { _errno = errno; return FATAL_ERROR; } } TokenParser::ParserStatus status = parseLine(); if (status != OK) return status; } while (_numArgs == 0); return OK; } TokenParser::ParserStatus TokenParser::parseLine(void) { _numArgs = 0; char* c = _lineBuffer; while (abTRUE) { while (abTRUE) { if (!(*c) || *c == TOKENPARSER_COMMENT) return OK; if (!isspace(*c)) break; c++; } if (_numArgs == _maxArgs) { //cerr << "Warning: too many arguments in line " << _lineNo // << " of file " << _fileName << endl; return OK; } if (*c == TOKENPARSER_QUOTE) { // // We have an open quote, point the word to just after this // quote, effectively removing it from the argument. // _args[_numArgs++] = ++c; while (abTRUE) { // // If we find the end of the string first, then we have // a erroneous line. Terminate here and hope it was the // last argument required, but not without a warning // message. // if (*c == '\n') *c = '\0'; if (*c == '\0') { //cerr << "Warning: missing quote in line " << _lineNo // << " of file " << _fileName << endl; return OK; //XXX } if (*c == TOKENPARSER_QUOTE) break; c++; } // // Leave the pointer here, so we null out the closing quoue // and remove it from the word. // } else { // // We have a normal word, so point the argument here, and find // the next space or end of word. // _args[_numArgs++] = c++; while (abTRUE) { if (*c == '\0') return OK; if (*c == TOKENPARSER_COMMENT) { *c = '\0'; return OK; } if (isspace(*c)) break; c++; } } *c++ = '\0'; } } void TokenParser::rewind(void) { ::rewind(_file); } void TokenParser::printUserError(const char*) { //cerr << "Error in file " << _fileName; //if (_lineNo) //cerr << ", line " << _lineNo; //cerr << ": " << message << endl; } void TokenParser::printParserError(void) { printUserError(strerror(_errno)); }