"Fossies" - the Fresh Open Source Software Archive

Member "bbkeys-0.9.1/src/FileTokenizer.cpp" (6 Dec 2007, 5049 Bytes) of package /linux/privat/old/bbkeys-0.9.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "FileTokenizer.cpp" see the Fossies "Dox" file reference documentation.

    1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
    2 // -- FileTokenizer.cpp --
    3 // Copyright (c) 2001 - 2003 Jason 'vanRijn' Kasper <vR at movingparts dot net>
    4 //
    5 // Permission is hereby granted, free of charge, to any person obtaining a
    6 // copy of this software and associated documentation files (the "Software"),
    7 // to deal in the Software without restriction, including without limitation
    8 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
    9 // and/or sell copies of the Software, and to permit persons to whom the
   10 // Software is furnished to do so, subject to the following conditions:
   11 //
   12 // The above copyright notice and this permission notice shall be included in
   13 // all copies or substantial portions of the Software.
   14 //
   15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
   18 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   21 // DEALINGS IN THE SOFTWARE.
   22 
   23 // E_O_H_VR
   24 
   25 #include "FileTokenizer.h"
   26 
   27 static unsigned int keywordLookup(const KeywordMap& keys, const string& tag) {
   28     const KeywordMap::const_iterator it = keys.find(tag);
   29     if (it != keys.end())
   30         return it->second;
   31     return 0;
   32 }
   33 
   34 
   35 static char tabToSpace(char c) {
   36     if (c == '\t')
   37         return ' ';
   38     return c;
   39 }
   40 
   41 
   42 /* read a line into the string 'line', if it is continued then keep reading
   43  * until we have the whole line
   44  * returns the number of lines read and the line via the reference
   45  */
   46 static unsigned int getFullLine(ifstream& file, string& line) {
   47     if (! file.good()) return 0;
   48 
   49     getline(file, line);
   50     unsigned int count = 1;
   51     while (file.good() && line[line.length() - 1] == '\\') {
   52         string tmp;
   53         getline(file, tmp);
   54         line.erase(line.length() - 1);
   55         line += tmp;
   56         ++count;
   57     }
   58     transform(line.begin(), line.end(), line.begin(), tabToSpace);
   59     return count;
   60 }
   61 
   62 
   63 
   64 FileTokenizer::FileTokenizer(const KeywordMap& keys, const char* fname,
   65                  TokenError errhandler): filename(fname),
   66                              keywords(keys),
   67                              error(errhandler),
   68                              lineno(0l),
   69                              state(WANT_TAG) {
   70     file.open(filename.c_str());
   71 
   72     if (! file.good()) {
   73         cerr << BBTOOL << ": " << "FileTokenizer::constructor: couldn't open file: [" << filename << "]" << endl;
   74     }
   75 }
   76 
   77 
   78 FileTokenizer::~FileTokenizer(void) {
   79     file.close();
   80 }
   81 
   82 
   83 TokenBlock* FileTokenizer::next(void) {
   84     string line;
   85 
   86  TOP:
   87     unsigned int count;
   88     if ((count = getFullLine(file, line)) == 0)
   89         return (TokenBlock*) 0;
   90     lineno += count;
   91 
   92     TokenBlock* block = new TokenBlock;
   93     block->lineno = lineno;
   94 
   95     string::size_type pos = 0, len = line.length();
   96     for (; state != WANT_NOTHING && pos < len; ++pos) {
   97         if (isspace(line[pos])) continue;
   98 
   99         if (state == WANT_TAG && line[pos] == '[') {
  100             string::size_type start = ++pos;
  101             while (pos < len && line[pos] != ']') ++pos; // no escapes allowed
  102 
  103             string tag(line, start, pos - start);
  104             transform(tag.begin(), tag.end(), tag.begin(), ::tolower);
  105             unsigned int value = keywordLookup(keywords, tag);
  106             if (value == 0) {
  107                 if (! error(filename, "unknown tag: " + tag, lineno))
  108                     goto ERR_EXIT;
  109                 goto TOP;
  110             }
  111             block->tag = value;
  112             state = WANT_NAME;
  113         } else if (state == WANT_NAME && line[pos] == '(') {
  114             string::size_type start = ++pos;
  115             while (pos < len && line[pos] != ')') {
  116                 if (line[pos++] == '\\') ++pos;
  117             }
  118 
  119             block->name.assign(line, start, pos - start);
  120             state = WANT_DATA;
  121         } else if (state == WANT_DATA && line[pos] == '{') {
  122             string::size_type start = ++pos;
  123         // now start to search for the closing curly bracket at the end
  124         // as there might be a curly bracket in between starting and
  125         // ending brackets
  126             pos = len;
  127             while (pos > start && line[pos] != '}') {
  128             --pos;
  129             }
  130 
  131             block->data.assign(line, start, pos - start);
  132             state = WANT_NOTHING;
  133         } else {
  134             if (line[pos] != '#') { // this isn't a comment, complain
  135                 const string e = "invalid input: " + string(line, pos, line.length());
  136                 if (! error(filename, e, lineno))
  137                     goto ERR_EXIT;
  138             }
  139             break;
  140         }
  141     }
  142     if (state == WANT_TAG) {
  143         // we never found what we wanted, so let's get a new line and try again
  144         delete block;
  145         goto TOP;
  146     }
  147 
  148     state = WANT_TAG; // reset state for next call
  149 
  150     return block;
  151 
  152  ERR_EXIT:
  153     delete block;
  154     return (TokenBlock*) 0;
  155 }
  156