20                 enum symType { symNull, symNumber, symOp, symVar };
 
   23                 explicit Token(
enum symType type) : s(
""), t(type) {}
 
   24                 explicit Token() : s(
""), t(symNull) {}
 
   28 typedef std::map<string,double> 
symtab;
 
   57 const char *
nWord(
const char *chKey, 
 
   64         while (isspace(*chKey))
 
   69         const long lenkey = strlen(chKey);
 
   72         bool atBoundary = 
true, inQuote=
false;
 
   73         for (
const char *ptr = chCard; *ptr; ++ptr)
 
   83                                 if ( atBoundary && strncmp( ptr, chKey, lenkey) == 0 )
 
  105         const bool lgAnyWhitespacePrecedesWord = 
false;
 
  107         if (lgAnyWhitespacePrecedesWord)
 
  108                 return isspace(c) ? 
true : false ;
 
  110                 return (! isalpha(c) ) && c != 
'_';
 
  128         std::string name(
"");
 
  132                 if (!(isalnum(c) || c == 
'_'))
 
  177                 " A filename or label must be specified within double quotes, but no quotes were encountered on this command.\n" 
  178                 " Name must be surrounded by exactly two double quotes, like \"name.txt\". \n"  
  200         if( i0 == NULL || i1 == NULL )
 
  209         chLabel = string(i0+1,i1);
 
  242         fprintf( 
ioQQQ, 
"  Unrecognized command. Key=\"%4.4s\".  This is routine ParseCommands.\n", 
 
  270         fprintf(fp,
"Available commands are:\n\n");
 
  271         long int i=0, l=0, len;
 
  288         fprintf(fp,
"\n\nSorry, no further help available yet -- try Hazy.\n\n");
 
  305         for( i=0; i<(int)
LIMELM; ++i )
 
  323         fprintf( 
ioQQQ, 
" There is a problem on the following command line:\n" );
 
  325         fprintf( 
ioQQQ, 
" A value for %s should have been on this line.\n   Sorry.\n",chDesc );
 
  383         else if(! 
nMatch(
"LINE") )
 
  405                                   "large, I shall probably crash.  The value was %.2e\n",
 
  450                 if( lchr == 
'-' || lchr == 
'+' )
 
  472         deque<Token> chTokens(0);
 
  475                          (isdigit(chr) || chr == 
'.' || chr == 
'-' || chr == 
'+'  
  476                           || chr == 
'e' || chr == 
'E' || chr == 
'^' || chr == 
'*' || chr == 
'/'  
  480                 if (chr == 
'^' || chr == 
'*' || chr == 
'/' ) 
 
  482                         chTokens.push_back(Token(Token::symOp));
 
  483                         chTokens.back().s += chr;
 
  488                         chTokens.push_back(Token(Token::symVar));
 
  494                         if (chTokens.size() == 0 || chTokens.back().t != Token::symNumber)
 
  495                                 chTokens.push_back(Token(Token::symNumber));
 
  496                         chTokens.back().s += chr;
 
  501         ASSERT (chTokens.size() != 0);
 
  504         vector<double> valstack;
 
  506         if (!lgParseOK || 1 != valstack.size())
 
  508                 fprintf(
ioQQQ,
" PROBLEM - syntax error in number or expression on line\n");
 
  514         double value = valstack[0];
 
  527                                   " input line too short to provide %ld character label\n" 
  528                                   "== %-80s ==\n", nchar,
m_card);
 
  532         return string(
m_card).substr(0,nchar);
 
  581         if ( chTokens.size() < 1)
 
  584         if (Token::symNumber == chTokens[0].t)
 
  586                 valstack.push_back(atof(chTokens[0].s.c_str()));
 
  587                 chTokens.pop_front();
 
  590         if (Token::symVar == chTokens[0].t)
 
  592                 symtab::const_iterator var = tab.find(chTokens[0].s);
 
  593                 if (var == tab.end())
 
  595                         fprintf(
ioQQQ,
"ERROR: No value found for variable $%s\n",
 
  596                                           chTokens[0].s.c_str());
 
  599                 valstack.push_back(var->second);
 
  600                 chTokens.pop_front();
 
  610         const double v2 = valstack.back();
 
  612         const double v1 = valstack.back();
 
  632         valstack.push_back(result);
 
  641         vector<string> opstack;
 
  647                 if ( chTokens.size() == 0 )
 
  650                 if ( chTokens.size() < 2 )
 
  653                 if ( Token::symOp != chTokens[0].t || 
"^" != chTokens[0].s )
 
  656                 opstack.push_back(chTokens[0].s);
 
  657                 chTokens.pop_front();
 
  663         while (!opstack.empty())
 
  665                 if (!
doop(valstack, opstack.back()))
 
  677         if (!
ParseExp(chTokens, valstack, tab))
 
  680         while ( chTokens.size() > 0 && 
 
  681                           Token::symOp == chTokens[0].t &&
 
  682                           ( 
"*" == chTokens[0].s || 
"/" ==  chTokens[0].s ) ) 
 
  684                 string op = chTokens[0].s;
 
  685                 chTokens.pop_front();
 
  687                 if (!
ParseExp(chTokens, valstack, tab))
 
  690                 if (!
doop(valstack, op))
 
  708         size_t len = strlen(s2);
 
  709         if (::strncmp(
m_card, s2, len) != 0)
 
  712         while (isspace(
m_card[len-1]))
 
  739                         fprintf( 
ioQQQ, 
" Hit EOF while reading element list; use END to end list.\n" );
 
  754                         fprintf( 
ioQQQ, 
" There must be a two numbers on this line, or END.\n" );
 
  761                         fprintf( 
ioQQQ, 
" There must be a two numbers on this line, or END.\n" );
 
  779                                   " at end of input term, error after '%s'\n",s.
value.c_str());
 
  791                 if (c != 
' ' && c != 
'\t')
 
  880                                                           " at end of input term\n");
 
  905         fprintf(
ioQQQ,
"Parser error, character not recognized '%c'\n",
 
  919                                 " Save %s hit EOF while reading list; use END to end list.\n" ,chName);
 
  921                                 " This command requires either a species within quotes or the keyword ALL.\n" );
 
  930                         list.push_back(chTerm);
 
  947         if (table.
nvals != 0)
 
  949                 fprintf( 
ioQQQ, 
" Warning: over-writing existing table\n" );
 
  958                 fprintf( 
ioQQQ, 
" No pairs entered - can\'t interpolate.\n Sorry.\n" );
 
  982                                 NoNumb(
"radius, value pair on each line");
 
  983                         table.
dist.push_back( dist );
 
  984                         table.
val.push_back( val );
 
  990         for( 
long i=1; i < table.
nvals; i++ )
 
  993                 if( table.
dist[i] <= table.
dist[i-1] )
 
  995                         fprintf( 
ioQQQ, 
" Radii must be in increasing order.  Sorry.\n" );
 
bool nMatch(const char *chKey) const 
 
bool hasCommand(const char *s2)
 
Symbol maybeNumber(bool numOK, const Symbol &s)
 
NORETURN void TotalInsanity(void)
 
double getNumberCheckLogLinNegImplLog(const char *chDesc)
 
STATIC bool ParseProduct(deque< Token > &chTokens, vector< double > &valstack, const symtab &tab)
 
void readList(vector< string > &list, const char *chName)
 
int GetQuote(string &chLabel)
 
char m_card[INPUT_LINE_LENGTH]
 
bool isCommandComment(void) const 
 
double getNumberDefaultAlwaysLog(const char *chDesc, double fdef)
 
STATIC bool ParseExpr(deque< Token > &chTokens, vector< double > &valstack, const symtab &tab)
 
bool isBoundaryChar(char c)
 
STATIC bool doop(vector< double > &valstack, const string &op)
 
void trimTrailingWhiteSpace(string &str)
 
NORETURN void StringError() const 
 
double getNumberPlain(const char *chDesc)
 
char m_card_raw[INPUT_LINE_LENGTH]
 
t_elementnames elementnames
 
string StandardFluxUnit(void) const 
 
const char * StandardEnergyUnit(void) const 
 
const int INPUT_LINE_LENGTH
 
NORETURN void NoNumb(const char *chDesc) const 
 
STATIC bool ParseExp(deque< Token > &chTokens, vector< double > &valstack, const symtab &tab)
 
const char * strchr_s(const char *s, int c)
 
long int GetElem(void) const 
 
const char * nWord(const char *chKey) const 
 
string getFirstChunk(long i)
 
string StandardFluxUnit(const char *chCard)
 
char chElementNameShort[LIMELM][CHARS_ELEMENT_NAME_SHORT]
 
const char * nWord(const char *chKey, const char *chCard)
 
STATIC double dist(long, realnum[], realnum[])
 
double getNumberCheckAlwaysLogLim(const char *chDesc, double flim)
 
void help(FILE *fp) const 
 
const char * StandardEnergyUnit(const char *chCard)
 
NORETURN void Error(const char *msg) const 
 
#define DEBUG_ENTRY(funcname)
 
STATIC bool ParseNumber(deque< Token > &chTokens, vector< double > &valstack, const symtab &tab)
 
double getNumberCheckAlwaysLog(const char *chDesc)
 
const CloudyCommand *const m_Commands
 
double getNumberDefault(const char *chDesc, double fdef)
 
std::map< string, double > symtab
 
int fprintf(const Output &stream, const char *format,...)
 
NORETURN void CommandError(void) const 
 
void getPairs(vector< double > &a, vector< double > &b)
 
double pow(double x, int i)
 
int PrintLine(FILE *fp) const 
 
std::string getVarName(void)
 
void readLaw(DepthTable &table)
 
double getNumberDefaultNegImplLog(const char *chDesc, double fdef)
 
std::map< string, double > m_symtab
 
bool isComment(void) const 
 
double getNumberCheck(const char *chDesc)