Nemo  2.4.0
Simulate forward-in-time genetic evolution in a spatially explicit, individual-based stochastic simulator
StreamParser Class Reference

Read parameters from a text buffer. More...

#include <paramsparser.h>

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

Public Member Functions

 StreamParser (const char *stream)
 
virtual ~StreamParser ()
 
virtual bool read (const char *stream)
 
virtual bool readArguments (istream &IN, int &l_count, string &args)
 
void replaceCR (string &stream, const char rpl='\n')
 
- Public Member Functions inherited from ParamsParser
 ParamsParser (const char *name)
 
virtual ~ParamsParser ()
 
void setName (const char *name)
 
map< string, string > get_inputParams ()
 
map< string, vector< string > > & getParsedParameters (const char *stream_name)
 
map< string, vector< string > > & getParsedParameters ()
 
map< string, string > & getParameters (const char *stream_name)
 
map< string, string > & getParameters ()
 
void parse ()
 Builds the _parsedParams from the _inputParams. More...
 
string replaceMacro (const string &arg)
 Macros. More...
 
string parseMacroFunctionBlock (const string &in_arg)
 
string callMacro (const string &name, const string &argstr)
 
vector< string > getMacroArgs (const string &args, const int min_arg, const size_t max_arg, const string macro_name, const string syntax, bool lastArgIsSeparatorChar=true)
 
string getMacroSepParamChar (const string &sep_in, const string macro_name)
 
string getMacroParamValue (const string &str_in, const string &par_name, const string &macro_name)
 
string quote (const string &argstr)
 Macro "q" returns a quoted string. More...
 
string concat (const string &argstr)
 Macro "c" returns a character-delimited string of atomic arguments. More...
 
string rep (const string &argstr)
 
string seq (const string &argstr)
 
string tempseq (const string &argstr)
 
string matrix (const string &argstr)
 
string diag_matrix (const string &argstr)
 
string sym_matrix (const string &argstr)
 
string runif (const string &argstr)
 
string rnorm (const string &argstr)
 
string rpoiss (const string &argstr)
 
string rbernoul (const string &argstr)
 
string rgamma (const string &argstr)
 
string rlognorm (const string &argstr)
 
string rexp (const string &argstr)
 

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. More...
 
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. More...
 
static string readUntilCharacter (istream &IN, int &l_count, const char start_c, const char end_c)
 
static void eatLine (istream &IN, int &l_count)
 
- Static Public Member Functions inherited from ParamsParser
static void getBlockArgument (istream &IN, char &c, string &arg)
 
static void getArguments (string &arg_str, vector< string > &arg_vect)
 

Additional Inherited Members

- Protected Member Functions inherited from ParamsParser
void reset_inputParams ()
 
void add_inputParam (string &param, const string &arg)
 

Detailed Description

Read parameters from a text buffer.

Constructor & Destructor Documentation

◆ StreamParser()

StreamParser::StreamParser ( const char *  stream)
inline
122 : ParamsParser(stream) {}
ParamsParser(const char *name)
Definition: paramsparser.cc:56

◆ ~StreamParser()

virtual StreamParser::~StreamParser ( )
inlinevirtual
123 {}

Member Function Documentation

◆ eatLine()

void StreamParser::eatLine ( istream &  IN,
int &  l_count 
)
static
1736 {
1737  char c;
1738  while(IN.get(c) && IN.good() && c != EOL && !IN.eof());
1739  ++l_count;
1740 }
#define EOL
Definition: paramsparser.cc:48

References EOL.

◆ read()

bool StreamParser::read ( const char *  stream)
virtual

Implements ParamsParser.

Reimplemented in BinaryFileParser, and FileParser.

1436  {
1437  int linecnt = 0;
1438  //output string to collect parameter arguments
1439  string args;
1440  //string to store parameter name
1441  string key;
1442 
1444 
1445  //--------------------------------------------------------------------------------
1446  char c = 0, eof = '\0';
1447  //put the char stream into a string
1448  string input_stream(stream);
1449  //add the terminating character to the string:
1450  input_stream += eof;
1451 
1452  //check if LF
1453  if(input_stream.find_first_of('\r') != string::npos) {
1454  //guess if NL is CRLF as in DOS files:
1455  if(input_stream.find_first_of('\n') == input_stream.find_first_of('\r') + 1)
1456  replaceCR(input_stream, ' '); //remove CR
1457  else
1458  replaceCR(input_stream); //replaces CR with LF
1459  }
1460 
1461  //initiate the input stringstream:
1462  istringstream IN(input_stream);
1463 
1464  //--------------------------------------------------------------------------------
1465  //read the file line by line
1466  while(IN.good() && !IN.eof()) {
1467 
1468  linecnt++;
1469 
1470  // remove the forgoing space of the line, returns false if EOL is reached
1471  if(!removeSpaceAndComment(IN, linecnt)) continue;
1472 
1473  //--------------------------------------------------------------------------------
1474  //read the parameter name and record it in 'key':
1475 
1476  key="";
1477  while(IN.get(c) && IN.good() && !IN.eof() && c != EOL && !isspace(c)){
1478  //whitespace is the split char between a parameter and its argument
1479  //this basically does the same as IN>>key, but we have to check for comments:
1480  if(c == '#'){
1481  removeComment(IN, linecnt);
1482  break;
1483  }
1484 
1485  key += c;
1486  } //__end_while_key__
1487 
1488  if(c == EOL || !removeSpaceAndComment(IN, linecnt) ) {
1489  if(c != eof){
1490  if(key.size() != 0) {//boolean param
1491  args = "1";
1492  ParamsParser::add_inputParam(key, args);
1493  }
1494 #ifdef _DEBUG_
1495  message(" line %i: %s (1)\n", linecnt, key.c_str());
1496 #endif
1497  }
1498  continue;
1499  }
1500 
1501 #ifdef _DEBUG_
1502  message(" line %i: %s (", linecnt, key.c_str());
1503 #endif
1504 
1505  //--------------------------------------------------------------------------------
1506  //read the arguments:
1507  args = "";
1508  while( readArguments(IN, linecnt, args) );
1509 
1510  //remove any trailling space on the argument string
1511  int i;
1512  for(i=(int)args.size()-1; i>=0; --i){
1513  if(!isspace(args[i])) break;
1514  }
1515  args[i+1]='\0';
1516 
1517  //--------------------------------------------------------------------------------
1518  // store the key - args pair in the _inputParam table
1519  ParamsParser::add_inputParam(key, args.c_str());
1520 
1521 #ifdef _DEBUG_
1522  message("%s)\n", args.c_str());
1523 #endif
1524  //reset the stream state, is changed by operator >>
1525  IN.clear(ios::goodbit);
1526 
1527  }//__END__WHILE__
1528 
1529  return true;
1530  }
void add_inputParam(string &param, const string &arg)
Definition: paramsparser.h:101
void reset_inputParams()
Definition: paramsparser.h:100
virtual bool readArguments(istream &IN, int &l_count, string &args)
Definition: paramsparser.cc:1629
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.
Definition: paramsparser.cc:1537
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.
Definition: paramsparser.cc:1572
void replaceCR(string &stream, const char rpl='\n')
Definition: paramsparser.cc:1744
void message(const char *message,...)
Definition: output.cc:39

References ParamsParser::add_inputParam(), EOL, message(), and ParamsParser::reset_inputParams().

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

+ Here is the caller graph for this function:

◆ readArguments()

bool StreamParser::readArguments ( istream &  IN,
int &  l_count,
string &  args 
)
virtual
1630 {
1631  char c;
1632 
1633  //read one byte at a time
1634  while(IN.get(c) && IN.good() && !IN.eof() && c != EOL){
1635 
1636  if(c == '\\')
1637  eatLine(IN, l_count);
1638  //block delimiters: the block will be parsed in Param
1639  else if(c == '{')
1640  args += readUntilCharacter(IN, l_count, c, '}');
1641  else if(c == '(')
1642  args += readUntilCharacter(IN, l_count, c, ')');
1643  else if(c == '[')
1644  args += readUntilCharacter(IN, l_count, c, ']');
1645  else if(c == '\"')
1646  args += readUntilCharacter(IN, l_count, c, '\"');
1647  //comment delimiter:
1648  else if(c == '#') {
1649  if(!removeComment(IN, l_count))
1650  return false; // reached end of line
1651 
1652  //argument in external file
1653  } else if (c == '&') {
1654 
1655  //read the file name
1656  string file;
1657 
1658  while(IN.get(c) && IN.good() && !IN.eof() && !isspace(c)){
1659 
1660  if(c=='#'){ // check if a comment is included
1661  IN.putback(c); // comment
1662  if(!removeSpaceAndComment(IN, l_count)) break;
1663  }
1664  file += c;
1665  }
1666 
1667  if(c==EOL || isspace(c)) IN.putback(c);
1668 
1669  //put the file name back into the arg, will be processed later
1670  args += "&" + file + " ";
1671 
1672  } else
1673  args += c;
1674 
1675  }//end while read args
1676 
1677  if(c == EOL || IN.eof()) return false;
1678 
1679  if(!IN.good()) //this may happen if an external file doesn't end with a \n
1680  fatal("problem reading input file; line %i appears corrupted, skipping line\n",l_count);
1681 
1682  return true;
1683 }
static string readUntilCharacter(istream &IN, int &l_count, const char start_c, const char end_c)
Definition: paramsparser.cc:1687
static void eatLine(istream &IN, int &l_count)
Definition: paramsparser.cc:1735
void fatal(const char *str,...)
Definition: output.cc:99

References EOL, and fatal().

Referenced by Param::getArgumentFromFile().

+ Here is the caller graph for this function:

◆ readUntilCharacter()

string StreamParser::readUntilCharacter ( istream &  IN,
int &  l_count,
const char  start_c,
const char  end_c 
)
static
1688 {
1689  string out;
1690  char c;
1691  bool closed = false;
1692 
1693  out += start_c;
1694 
1695  //cout << "start block : "<<start_c<<endl;
1696  while (IN.get(c) && IN.good() && !IN.eof() ) {
1697 
1698  if(c == EOL) //a block can span several lines
1699 
1700  ++l_count;
1701 
1702  else if(c == end_c) {
1703 
1704  out += c;
1705  //remove trailing spaces but keep last one, it's the arg seperator
1706  if(!removeSpaceAndComment(IN, l_count, true)) {
1707  IN.putback(EOL); //we've reached eol, put it back
1708  }
1709 
1710  closed = true;
1711  break;
1712 
1713  } else if(c == start_c) {//nested blocks
1714 
1715  out += readUntilCharacter(IN, l_count, start_c, end_c);
1716 
1717  } else if(c == '\\') {//line continuation within a block
1718 
1719  eatLine(IN, l_count);
1720 
1721  } else if(c == '#') {
1722 
1723  if(!removeComment(IN, l_count)) l_count++;
1724 
1725  } else out += c;
1726  } //__end_while__
1727 
1728  if(!closed) fatal("missing closing character '%c' on line %i.\n", end_c, l_count);
1729 
1730  return out;
1731 }

References EOL, and fatal().

Referenced by ParamsParser::getBlockArgument().

+ Here is the caller graph for this function:

◆ removeComment()

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)

1573 {
1574  char c;
1575 
1576  //remember: we enter the loop with c = '#'
1577  //check if next char is the start of a block comment:
1578  bool isBlock = (IN.peek() == '/');
1579  bool prevIsComment = true;
1580 
1581  while(IN.get(c) && IN.good() && !IN.eof()){
1582 
1583  //break if EOL && next line not a comment, continue otherwise:
1584  if (c == EOL){
1585  //check if next line is also a comment, start the loop again:
1586  if (IN.peek() == '#') {
1587 
1588  IN.get(c);
1589  prevIsComment = true;
1590  ++l_count;
1591  continue;
1592 
1593  //continue if within a block comment:
1594  } else if( isBlock ) {
1595  ++l_count;
1596  continue;
1597  //next line not a comment, get out of the loop:
1598  } else
1599  return false;
1600  }
1601 
1602  //check if we had the block str '#/' within a commented line
1603  if (c == '/'){
1604 
1605  if(IN.peek() == '#') {
1606  IN.get(c);
1607 
1608  if(isBlock)
1609  //block termination string '/#', remove trailing space
1610  //note: the string '#/#' is also considered as a terminating string
1611  return removeSpaceAndComment(IN, l_count);
1612 
1613  } else if(prevIsComment) {
1614  //we've got '#/', a block comment may start anywhere on a comment line
1615  isBlock = true;
1616  }
1617  }
1618 
1619  if(c == '#') prevIsComment = true;
1620  else prevIsComment = false;
1621 
1622  } //__END_WHILE__
1623 
1624  return false;
1625 }

References EOL.

◆ removeSpaceAndComment()

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.

1538 {
1539  char c;
1540 
1541  while(IN.get(c) && IN.good() && !IN.eof() && c != EOL) {
1542 
1543  if(!isspace(c)){
1544 
1545  if(c=='#') return removeComment(IN, l_count); // recursively remove comment
1546 
1547  IN.putback(c); //this is a parameter: put the character back
1548 
1549  if(keepLast) {
1550  //get back one char:
1551  IN.unget();
1552  IN.get(c); //read it again and check if whitespace:
1553  if(isspace(c)) IN.putback(c);
1554  }
1555 
1556  return true;
1557  }
1558  }
1559  return false;
1560 }

References EOL.

Referenced by ParamsParser::getArguments().

+ Here is the caller graph for this function:

◆ replaceCR()

void StreamParser::replaceCR ( string &  stream,
const char  rpl = '\n' 
)
1745 {
1746  size_t pos = 0;
1747 
1748  while ( (pos = stream.find_first_of('\r', pos)) != string::npos) {
1749  stream[pos] = rpl;
1750  }
1751 }

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

Generated for Nemo v2.4.0 by  doxygen 1.9.1 -- Nemo is hosted on  Download Nemo

Locations of visitors to this page
Catalogued on GSR