// // $Id$ //----------------------------------------------------------------------- // // (c) Copyright 2005 by GATS, Inc., // 11864 Canon Blvd, Suite 101, Newport News VA 23606 // // All Rights Reserved. No part of this software or publication may be // reproduced, stored in a retrieval system, or transmitted, in any form // or by any means, electronic, mechanical, photocopying, recording, or // otherwise without the prior written permission of GATS, Inc. // //----------------------------------------------------------------------- // // Module: ConfigTable.cpp // // Author: John Burton // Brian Magill 11/15/2001 // // Date: Fri Jan 07 16:28:37 2005 // //----------------------------------------------------------------------- // // Modification History: // // $Log$ // //----------------------------------------------------------------------- // // ConfigTable.c // // Description: contains the configuration table data structure // and the utilities to access it. These functions use the // atble and Atom structures described in the book "C Interfaces // and Implementations" by David R. Hanson // // Module Variables: // Name Description // ---- ----------- // ConfigTable table which holds all initialization files // //----------------------------------------------------------------------- // Include Files: //----------------------------------------------------------------------- // #include #include #include #include #include #include #include #include #include #include "FlexLexer.h" #include "Value.h" #include "ConfigLexer.h" #include "ConfigFile.h" #include "Error.h" // //----------------------------------------------------------------------- // Defines and Macros: //----------------------------------------------------------------------- // // //----------------------------------------------------------------------- // Type Definitions: //----------------------------------------------------------------------- // // //----------------------------------------------------------------------- // Global Variables: //----------------------------------------------------------------------- // // //----------------------------------------------------------------------- // Utility Routines: //----------------------------------------------------------------------- // void ConfigFile::open(string filename) { yyFlexLexer *clex; ifstream *ifile; ifile = new ifstream(filename.c_str()); if(!(ifile->is_open())) { std::string errstr = "Unable to open file: " + filename; THROW_GATS_EXCEPTION(ConfigFileException,errstr); } clex = new yyFlexLexer(ifile); ParseFile(clex); } ConfigFile::ConfigFile(void) { } ConfigFile::ConfigFile(string filename) { open(filename); } int ConfigFile::ParseFile(yyFlexLexer *clex) { int token; string Symbol; string Section; ValueClass *retval; ValueClass *val; retval = 0; while((token = clex->yylex()) != EOF) { switch(token) { case SECTIONNAME: Section = clex->YYText(); break; case SYMBOL: Symbol = clex->YYText(); token = clex->yylex(); if(token == ASSIGN) { val = ParseValues(clex); PutValue(Section,Symbol,val); } else { std::string errstr = "Incorrect token: expected ASSIGN"; THROW_GATS_EXCEPTION(ConfigFileException,errstr); } break; default: std::string errstr = "Unexpected token: expected SECTIONNAME or SYMBOL"; THROW_GATS_EXCEPTION(ConfigFileException,errstr); break; } } return token; } ValueClass *ConfigFile::ParseValues(yyFlexLexer *clex) { ValueClass *initval; int token; token = clex->yylex(); initval = (token == LBRACE) ? ParseValueList(clex) : ParseSimpleValue(token,clex); return initval; } ValueClass *ConfigFile::ParseSimpleValue(int token, yyFlexLexer *clex) { ValueClass *retval; string tmp; int ndx; if(token == 0) token = clex->yylex(); switch(token) { case CHRSTR: tmp = clex->YYText(); ndx = tmp.find('\"'); tmp.erase(ndx,1); ndx = tmp.rfind('\"'); tmp.erase(ndx,1); retval = new ValueClass(tmp); break; case PATHNAME: case SYMBOL: retval = new ValueClass(clex->YYText()); break; case IVALUE: retval = new ValueClass(atoi(clex->YYText())); break; case RVALUE: retval = new ValueClass((float)atof(clex->YYText())); break; default: std::string errstr = "Unknown Token Type - "; THROW_GATS_EXCEPTION(ConfigFileException,errstr); break; } return retval; } ValueClass *ConfigFile::CatValueList(ValueClass *vl1, ValueClass *vl2) { int nvals; int i,j; vl1->AddValueList(vl2); return vl1; } ValueClass *ConfigFile::ParseValueList(yyFlexLexer *clex) { int token; ValueClass *retval; ValueClass *tmp; std::string errstr; retval = ParseSimpleValue(0,clex); token = clex->yylex(); switch(token) { case COMMA: tmp = ParseValueList(clex); retval = CatValueList(retval,tmp); break; case EOF: errstr = "Unexpected End Of File "; THROW_GATS_EXCEPTION(ConfigFileException,errstr); break; case RBRACE: break; default: errstr = "Unknown Token Type "; THROW_GATS_EXCEPTION(ConfigFileException,errstr); break; } return retval; } int ConfigFile::PrintValue (ValMap::iterator vitr) { int i; ValueClass *val = vitr->second; val->PrintValues(); } int ConfigFile::PrintTable () // //----------------------------------------------------------------------- // // Routine: PrintConfigTable // // Author: John Burton Tue Jun 3 16:15:55 2003 // // Description: prints the config table to fpout // // //----------------------------------------------------------------------- // // Description of Parameters: // // FILE *fpout // fpout -- output file pointer // //----------------------------------------------------------------------- // { MapMap::iterator mitr; ValMap::iterator vitr; ValMap vmap; ValueClass *val; int i,j; string symbol,section; string Section,Symbol; // ofstream *fpout = cerr; mitr = ConfigMap.begin(); while(mitr != ConfigMap.end()) { section = mitr->first; cerr << "[" << section << "]" << "\n"; vmap = mitr->second; vitr = vmap.begin(); while(vitr != vmap.end()) { symbol = vitr->first; cerr << " " << symbol << " = "; PrintValue(vitr); vitr++; } mitr++; } return 0; } // End of PrintConfigTable// //int PutConfigVal(char* Section, char* Symbol, Value * value) // // Description: Adds an entry for a given Section and key word. // section name and key are concatenated to form the total key. // // Comments: Data Stored is a character string. // // Calling Arguments: // Variable Name Description // ------------- ----------- // SectionName Name of section for stored data // KeyName key for stored data // value data to be stored // // Local Variables: // Name Description // ---- ----------- // copy_value string to be actually stored in the table // p for testing existence of a key in the table // string temporary storage // totalKey Stores total key // //----------------------------------------------------------------------------- // void ConfigFile::PutValue(string Section, string Symbol, ValueClass *value) { MapMap::iterator mitr; ValMap::iterator vitr; ValMap vmap; char *key; int retval; #ifdef DEBUG int i; cerr << Section << "::" << Symbol << " = "; value->PrintValues(); #endif ConfigMap[Section][Symbol] = value; } ValueClass *ConfigFile::GetValue(string Section, string Symbol) // // Description: Retrieves the string value for a given section name and key // // Calling Arguments: // Variable Name Description // ------------- ----------- // SectionName Name of section for stored data // KeyName key for stored data // // // Local Variables: // Name Description // ---- ----------- // value string to be retrieved // string temporary storage // totalKey Stores total key // // // Comments: The pointer returned by GetConfig is to an actual string. // As long as the value is not modified, it can be used as is. // //----------------------------------------------------------------------------- // { ValueClass *val = NULL; val = ConfigMap[Section][Symbol]; if(val == NULL) { std::string errstr = "Configuration item " + Section + "::" + Symbol + " not found"; THROW_GATS_EXCEPTION(ConfigFileException,errstr); } return val; } //string ConfigFile::GetStr(string Section, string Symbol) // // Description: Retrieves the string value for a given section name and key // // Calling Arguments: // Variable Name Description // ------------- ----------- // SectionName Name of section for stored data // KeyName key for stored data // // // Local Variables: // Name Description // ---- ----------- // value string to be retrieved // string temporary storage // totalKey Stores total key // // // Comments: The pointer returned by GetConfig is to an actual string. // As long as the value is not modified, it can be used as is. // //----------------------------------------------------------------------------- // //{ // ValueClass *val; // string retval; // // val = GetValue(Section,Symbol); // retval = val->GetStringValue()[0]; // // return retval; //} bool ConfigFile::ValidEntry(string Section, string Symbol) { bool retval; retval = (ConfigMap[Section][Symbol] != 0); return retval; } bool ConfigFile::GetFlag(string Section, string Symbol) { ValueClass *val; vector tmp; int i; bool retval; retval = false; if (ConfigMap[Section][Symbol] != 0) { val = GetValue(Section,Symbol); if(val->GetType() == INT) { tmp = val->GetIntValue(); retval = (tmp[0] != 0); } } return retval; } //float ConfigFile::GetReal(string Section, string Symbol) // // Description: Retrieves the double precision value for a given // section name and key. // // // Calling Arguments: // Variable Name Description // ------------- ----------- // SectionName Name of section for stored data // KeyName key for stored data // // // Local Variables: // Name Description // ---- ----------- // ptrRemainder used to check that the value is an integer // real_value double precision value returned // string temporary storage // totalKey Stores total key // value string to be converted to integer // // //----------------------------------------------------------------------------- // //{ // ValueClass *val; // float retval; // // val = GetValue(Section,Symbol); // retval = 0; // switch(val->GetType()) // { // case INT: // retval = (float)val->GetIntValue()[0]; // break; // case REAL: // retval = (float)val->GetRealValue()[0]; // break; // case STRING: // break; // default: // fprintf(stderr,"**undefined**\n"); // break; // } // // return retval; //} vector ConfigFile::GetStrValues(string Section, string Symbol) // // Description: Retrieves the string value for a given section name and key // // Calling Arguments: // Variable Name Description // ------------- ----------- // SectionName Name of section for stored data // KeyName key for stored data // // // Local Variables: // Name Description // ---- ----------- // value string to be retrieved // string temporary storage // totalKey Stores total key // // // Comments: The pointer returned by GetConfig is to an actual string. // As long as the value is not modified, it can be used as is. // //----------------------------------------------------------------------------- // { ValueClass *val; int i; vector retval; retval.clear(); val = GetValue(Section,Symbol); if(val != NULL) retval = val->GetStringValue(); return retval; } vector ConfigFile::GetIntValues(string Section, string Symbol) // // Description: Retrieves the long integer value for a given section name // and key // // Calling Arguments: // Variable Name Description // ------------- ----------- // SectionName Name of section for stored data // KeyName key for stored data // // // Local Variables: // Name Description // ---- ----------- // long_value integer value returned // ptrRemainder used to check that the value is an integer // string temporary storage // totalKey Stores total key // value string to be converted to integer // // //----------------------------------------------------------------------------- // { ValueClass *val; vector retval; vector tmp; int i; retval.clear(); val = GetValue(Section,Symbol); if(val != NULL) { switch(val->GetType()) { case INT: retval = val->GetIntValue(); break; case REAL: tmp = val->GetRealValue(); for(i=0;i ConfigFile::GetRealValues(string Section, string Symbol) // // Description: Retrieves the double precision value for a given // section name and key. // // // Calling Arguments: // Variable Name Description // ------------- ----------- // SectionName Name of section for stored data // KeyName key for stored data // // // Local Variables: // Name Description // ---- ----------- // ptrRemainder used to check that the value is an integer // real_value double precision value returned // string temporary storage // totalKey Stores total key // value string to be converted to integer // // //----------------------------------------------------------------------------- // { ValueClass *val; vector retval; vector tmp; int i; retval.clear(); val = GetValue(Section,Symbol); if(val != NULL) { switch(val->GetType()) { case INT: tmp = val->GetIntValue(); for(i=0;iGetRealValue(); break; case STRING: break; default: fprintf(stderr,"**undefined**\n"); break; } } return retval; } // // Compatibility routines // int ConfigFile::GetInt(char* Section, char* Symbol) { string section(Section); string symbol(Symbol); vector tmp; tmp = GetIntValues(section,symbol); return tmp[0]; } int ConfigFile::GetInt(const char* Section, const char* Symbol) { string section(Section); string symbol(Symbol); vector tmp; tmp = GetIntValues(section,symbol); return tmp[0]; } int ConfigFile::GetInt(string Section, string Symbol) { vector tmp; int retval; tmp = GetIntValues(Section,Symbol); return tmp[0]; } char *ConfigFile::GetStr(char* Section, char* Symbol) { string section(Section); string symbol(Symbol); vector tmp; char *retval; tmp = GetStrValues(section,symbol); retval = strdup(tmp[0].c_str()); return retval; } char *ConfigFile::GetStr(const char* Section, const char* Symbol) { string section(Section); string symbol(Symbol); vector tmp; char *retval; tmp = GetStrValues(section,symbol); retval = strdup(tmp[0].c_str()); return retval; } string ConfigFile::GetStr(string Section, string Symbol) { vector tmp; tmp = GetStrValues(Section,Symbol); return tmp[0]; } float ConfigFile::GetReal(char* Section, char* Symbol) { string section(Section); string symbol(Symbol); vector tmp; tmp = GetRealValues(section,symbol); return tmp[0]; } float ConfigFile::GetReal(const char* Section, const char* Symbol) { string section(Section); string symbol(Symbol); vector tmp; tmp = GetRealValues(section,symbol); return tmp[0]; } float ConfigFile::GetReal(string Section, string Symbol) { vector tmp; tmp = GetRealValues(Section,Symbol); return tmp[0]; } char **ConfigFile::GetStrArray(char* Section, char* Symbol, int *nvals) { string section(Section); string symbol(Symbol); vector tmp; int i; int nv; char **retval; tmp = GetStrValues(section,symbol); nv = tmp.size(); retval = (char **)calloc(nv,sizeof(char *)); for (i=0;i tmp; int i; int nv; char **retval; tmp = GetStrValues(section,symbol); nv = tmp.size(); retval = (char **)calloc(nv,sizeof(char *)); for (i=0;i tmp; int i; int nv; int *retval; tmp = GetIntValues(section,symbol); nv = tmp.size(); retval = (int *)calloc(nv,sizeof(int)); for (i=0;i tmp; int i; int nv; int *retval; tmp = GetIntValues(section,symbol); nv = tmp.size(); retval = (int *)calloc(nv,sizeof(int)); for (i=0;i tmp; int i; int nv; float *retval; tmp = GetRealValues(section,symbol); nv = tmp.size(); retval = (float *)calloc(nv,sizeof(float)); for (i=0;i tmp; int i; int nv; float *retval; tmp = GetRealValues(section,symbol); nv = tmp.size(); retval = (float *)calloc(nv,sizeof(float)); for (i=0;i