Nemo  2.2.0
Public Member Functions | Static Public Member Functions
StreamParser Class Reference

Read parameters from a text buffer. More...

#include <paramsparser.h>

+ Inheritance diagram for StreamParser:
+ Collaboration diagram for StreamParser:

List of all members.

Public Member Functions

 StreamParser (const char *stream)
virtual ~StreamParser ()
virtual bool read (const char *stream)
 Read/parse params & args from a file or a string or an R object.
virtual bool readArguments (istream &IN, int &l_count, string &args)
void replaceCR (string &stream, const char rpl= '\n')

Static Public Member Functions

static bool removeComment (istream &IN, int &l_count)
 Recusively removes comments until the end of a line/of the file, or of a block comment is reached.
static bool removeSpaceAndComment (istream &IN, int &l_count, bool keepLast=false)
 Removes whitespace char on a line until a non-ws or EOL is reached.
static string readUntilCharacter (istream &IN, int &l_count, char &start_c, const char end_c)
static void eatLine (istream &IN, int &l_count)

Detailed Description

Read parameters from a text buffer.

Definition at line 79 of file paramsparser.h.


Constructor & Destructor Documentation

StreamParser::StreamParser ( const char *  stream) [inline]

Definition at line 82 of file paramsparser.h.

: ParamsParser(stream) {}
virtual StreamParser::~StreamParser ( ) [inline, virtual]

Definition at line 83 of file paramsparser.h.

{}

Member Function Documentation

void StreamParser::eatLine ( istream &  IN,
int &  l_count 
) [static]

Definition at line 448 of file paramsparser.cc.

References EOL.

{
  char c;
  while(IN.get(c) && IN.good() && c != EOL && !IN.eof());
  ++l_count;
}
bool StreamParser::read ( const char *  stream) [virtual]

Read/parse params & args from a file or a string or an R object.

Params and their args are put in the _inputParams.

Implements ParamsParser.

Reimplemented in BinaryFileParser, and FileParser.

Definition at line 176 of file paramsparser.cc.

References EOL, and message().

Referenced by FileParser::read(), and BinaryFileParser::read().

  {
    int linecnt = 0;    
    //output string to collect parameter arguments
    string args;
    //string to store parameter name
    string key;
    
    reset_inputParams();
    
    //--------------------------------------------------------------------------------
    char c = 0, eof = '\0';
    //put the char stream into a string
    string input_stream(stream);
    //add the terminating character to the string:
    input_stream += eof;
    
    //check if LF 
    if(input_stream.find_first_of('\r') != string::npos) {
      //guess if NL is CRLF as in DOS files:
      if(input_stream.find_first_of('\n') == input_stream.find_first_of('\r') + 1)
        replaceCR(input_stream, ' '); //remove CR
      else
        replaceCR(input_stream); //replaces CR with LF
    }
    
    //initiate the input stringstream:
    istringstream IN(input_stream);

    //--------------------------------------------------------------------------------
    //read the file line by line
    while(IN.good() && !IN.eof()) {
      
      linecnt++;
      
      // remove the forgoing space of the line, returns false if EOL is reached
      if(!removeSpaceAndComment(IN, linecnt)) continue;
      
      key="";
      //read the parameter name:
      while(IN.get(c) && IN.good() && !IN.eof() && c != EOL && !isspace(c)){
        //whitespace is the split char between a parameter and its argument
        //this basically does the same as IN>>key, but we have to chek for comments:
        if(c == '#'){
          removeComment(IN, linecnt);
          break;
        }
        
        key += c;
      } //__end_while_key__
      
      if(c == EOL || !removeSpaceAndComment(IN, linecnt) ) {
        if(c != eof){
          if(key.size() != 0) {//boolean param
            args = "1";
            add_inputParam(key, args);
          }
#ifdef _DEBUG_
          message("  line %i: %s (1)\n", linecnt, key.c_str());
#endif 
        }
          continue;
      }
      //remove whitespace before arguments
//      if( !removeSpaceAndComment(IN, linecnt) ) continue;
                      
#ifdef _DEBUG_
      message("  line %i: %s (", linecnt, key.c_str());
#endif
            
      //read the arguments:
      args = "";
      while( readArguments(IN, linecnt, args) );
      
      //remove any trailling space on the argument string
      unsigned int i;
      for(i=args.size()-1; i>=0; --i){
        if(!isspace(args[i])) break;
      }
      args[i+1]='\0';
      
      add_inputParam(key, args.c_str());
      
#ifdef _DEBUG_
      message("%s)\n", args.c_str());
#endif
      //reset the stream state, is changed by operator >>
      IN.clear(ios::goodbit);
            
    }//__END__WHILE__
    
    return true;
  }
bool StreamParser::readArguments ( istream &  IN,
int &  l_count,
string &  args 
) [virtual]

Definition at line 367 of file paramsparser.cc.

References EOL, and warning().

{
  char c;
  
  while(IN.get(c) && IN.good() && !IN.eof() && c != EOL){

    if(c == '\\')
      eatLine(IN, l_count);
    else if(c == '{')
      args += readUntilCharacter(IN, l_count, c, '}');
    else if(c == '(')
      args += readUntilCharacter(IN, l_count, c, ')');
    else if(c == '[')
      args += readUntilCharacter(IN, l_count, c, ']');
    else if(c == '\"')
      args += readUntilCharacter(IN, l_count, c, '\"');
    else if(c == '#') {
      if(!removeComment(IN, l_count))
        return false; // reached end of line
    } else
      args += c;
    
  }//end while read args

  if(c == EOL || IN.eof())  return false;
  if(!IN.good()) warning("problem reading input file; line %i appears corrupted, skipping line\n",l_count);
  return true; 
}
string StreamParser::readUntilCharacter ( istream &  IN,
int &  l_count,
char &  start_c,
const char  end_c 
) [static]

Definition at line 398 of file paramsparser.cc.

References EOL, and fatal().

Referenced by ParamsParser::getBlockArgument().

{
  string out;
  char c;
  bool closed = false;
    
  out += start_c;
  //cout << "start block : "<<start_c<<endl;
  while (IN.get(c) && IN.good() && !IN.eof() ) {
    
    if(c == EOL) //a block can span several lines
    
      ++l_count;
    
    else if(c == end_c) {
      
      out += c;
      //remove trailing spaces but keep last one, it's the arg seperator
      if(!removeSpaceAndComment(IN, l_count, true)) {
        IN.putback(EOL); //we've reached eol, put it back
      }
      
      closed = true;
      break;
    
    } else if(c == start_c) {//nested blocks

      out += readUntilCharacter(IN, l_count, start_c, end_c);
    
    } else if(c == '\\') //line continuation within a block
      
      eatLine(IN, l_count);
      
    else if(c == '#') {
    
      if(!removeComment(IN, l_count)) l_count++;
    
    } else out += c;
  } //__end_while__
  //cout<<out<<endl;
  
  if(!closed) fatal("missing closing character '%c' on line %i.\n", end_c, l_count);
  
  //cout << "close block : "<< c << endl;
  
  return out;
}
bool StreamParser::removeComment ( istream &  IN,
int &  l_count 
) [static]

Recusively removes comments until the end of a line/of the file, or of a block comment is reached.

#: commented line (removed until the end of the line is reached) #/ ... /#: a block comment (may span several lines) Consecutive lines of comments are also removed, even if not part of a block comment. Note: this function always returns false, unless something remains on a line after a block comment (i.e. if removeSpaceAndComment() returns true)

Definition at line 310 of file paramsparser.cc.

References EOL.

{
  char c;
  
  //remember: we enter the loop with c = '#'
  //check if next char is the start of a block comment:
  bool isBlock = (IN.peek() == '/');
  bool prevIsComment = true;
  
  while(IN.get(c) && IN.good() && !IN.eof()){
    
    //break if EOL && next line not a comment, continue otherwise:
    if (c == EOL){
      //check if next line is also a comment, start the loop again:
      if (IN.peek() == '#') {
        
        IN.get(c);
        prevIsComment = true;
        ++l_count;
        continue;
        
      //continue if within a block comment:
      } else if( isBlock ) {
        ++l_count;
        continue;
      //next line not a comment, get out of the loop:
      } else
        return false;
    }
    
    //check if we had the block str '#/' within a commented line
    if (c == '/'){ 
      
      if(IN.peek() == '#') {
        IN.get(c);
        
        if(isBlock)
          //block termination string '/#', remove trailing space
          //note: the string '#/#' is also considered as a terminating string
          return removeSpaceAndComment(IN, l_count);
        
      } else if(prevIsComment) { 
        //we've got '#/', a block comment may start anywhere on a comment line
        isBlock = true;
      }
    }
    
    if(c == '#') prevIsComment = true;
    else prevIsComment = false;
    
  } //__END_WHILE__
  
  return false;
}
bool StreamParser::removeSpaceAndComment ( istream &  IN,
int &  l_count,
bool  keepLast = false 
) [static]

Removes whitespace char on a line until a non-ws or EOL is reached.

Returns false if EOL or EOF is reached or true otherwise.

Definition at line 275 of file paramsparser.cc.

References EOL.

Referenced by ParamsParser::getArguments().

{
  char c;
  
  while(IN.get(c) && IN.good() && !IN.eof() && c != EOL) {
        
    if(!isspace(c)){
      
      if(c=='#') return removeComment(IN, l_count); // recursively remove comment
      
      IN.putback(c); //this is a parameter: put the character back
      
      if(keepLast) {
        //get back one char:
        IN.unget();
        IN.get(c); //read it again and check if whitespace:
        if(isspace(c)) IN.putback(c);
      }
      
      return true;
    }
  }
  return false;
}
void StreamParser::replaceCR ( string &  stream,
const char  rpl = '\n' 
)

Definition at line 457 of file paramsparser.cc.

{
  size_t pos = 0;
  
  while ( (pos = stream.find_first_of('\r', pos)) != string::npos) {
    stream[pos] = rpl;
  }
}

The documentation for this class was generated from the following files:

Generated for Nemo v2.2.0 by  doxygen 1.7.5.1 -- Nemo is hosted by  SourceForge.net Logo