Configuration.cpp
Go to the documentation of this file.
00001 /*
00002  * Configuration.cpp
00003  *
00004  *  Created on: Mar 6, 2009
00005  *      Author: Erik Schuitema
00006  */
00007 
00008 #include <threemxl/platform/io/configuration/Configuration.h>
00009 #include <muParser.h>
00010 #include <stdlib.h>
00011 
00012 #ifdef WIN32
00013 #include <win32_compat.h>
00014 #endif
00015 
00016 // ************************************************************************ //
00017 // *************************** IConfigProperty **************************** //
00018 // ************************************************************************ //
00019 bool IConfigProperty::toBool() const
00020 {
00021         if (strcasecmp(toString().c_str(), "true") == 0)
00022                 return true;
00023         else if (strcasecmp(toString().c_str(), "yes") == 0)
00024                 return true;
00025         else if (strcasecmp(toString().c_str(), "false") == 0)
00026                 return false;
00027         else if (strcasecmp(toString().c_str(), "no") == 0)
00028                 return false;
00029         else
00030                 return atoi(toString().c_str())!=0;
00031 }
00032 
00033 long IConfigProperty::toInt() const
00034 {
00035         return strtol(toString().c_str(), NULL, 10);
00036 }
00037 
00038 unsigned long IConfigProperty::toUInt() const
00039 {
00040         return strtoul(toString().c_str(), NULL, 10);
00041 }
00042 
00043 double IConfigProperty::toFloat() const
00044 {
00045         std::istringstream i(toString());
00046         double result;
00047         // Convert and check result. Make sure that there are no characters left over in the stream afterwards.
00048         if (!(i >> result) || !i.eof())
00049                 logErrorLn(CLog2("config"), "Could not convert \"" << toString() << "\" to a floating point value");
00050         else
00051                 logCrawlLn(CLog2("config"), name() << "=" << toString());
00052         return result;
00053 }
00054 
00055 // ************************************************************************ //
00056 // *************************** CConfigProperty **************************** //
00057 // ************************************************************************ //
00058 
00059 CConfigProperty::CConfigProperty(IConfigProperty* configPropertyInterface)
00060 {
00061         mIConfigProperty = configPropertyInterface;
00062 }
00063 
00064 CConfigProperty::~CConfigProperty()
00065 {
00066 }
00067 
00068 std::string CConfigProperty::name() const
00069 {
00070         if (mIConfigProperty)
00071                 return mIConfigProperty->name();
00072         else
00073                 return "";
00074 }
00075 
00076 
00077 // ************************************************************************ //
00078 // **************************** CConfigSection **************************** //
00079 // ************************************************************************ //
00080 
00081 CConfigSection::CConfigSection(IConfigSection* configSectionInterface)
00082 {
00083         mIConfigSection = configSectionInterface;
00084 }
00085 
00086 CConfigSection::~CConfigSection()
00087 {
00088 }
00089 
00090 std::string CConfigSection::name() const
00091 {
00092         if (mIConfigSection)
00093                 return mIConfigSection->name();
00094         else
00095                 return "";
00096 }
00097 
00098 bool CConfigSection::hasSection(const std::string& section) const
00099 {
00100         if (mIConfigSection)
00101                 return mIConfigSection->hasSection(section);
00102         else
00103                 return false;
00104 }
00105 
00106 CConfigSection CConfigSection::parent() const
00107 {
00108         IConfigSection *newSection = NULL;
00109         if (mIConfigSection)
00110                 newSection = mIConfigSection->parent();
00111         return CConfigSection(newSection);
00112 }
00113 
00114 CConfigSection CConfigSection::section(const std::string& section) const
00115 {
00116         IConfigSection *newSection = NULL;
00117         if (mIConfigSection)
00118                 newSection = mIConfigSection->section(section);
00119         return CConfigSection(newSection);
00120 }
00121 
00122 CConfigSection CConfigSection::firstSection() const
00123 {
00124         IConfigSection *newSection = NULL;
00125         if (mIConfigSection)
00126                 newSection = mIConfigSection->firstSection();
00127         return CConfigSection(newSection);
00128 }
00129 
00130 CConfigSection CConfigSection::nextSection() const
00131 {
00132         IConfigSection *newSection = NULL;
00133         if (mIConfigSection)
00134                 newSection = mIConfigSection->nextSection();
00135         return CConfigSection(newSection);
00136 }
00137 
00138 CConfigSection CConfigSection::nextSimilarSection() const
00139 {
00140         IConfigSection *newSection = NULL;
00141         if (mIConfigSection)
00142                 newSection = mIConfigSection->nextSimilarSection();
00143         return CConfigSection(newSection);
00144 }
00145 
00146 bool CConfigSection::has(const std::string& property) const
00147 {
00148         if (mIConfigSection)
00149                 return mIConfigSection->has(property);
00150         else
00151                 return false;
00152 }
00153 
00162 CConfigProperty CConfigSection::get(const std::string& property) const
00163 {
00164         IConfigProperty *newProperty = NULL;
00165         if (mIConfigSection)
00166                 newProperty = mIConfigSection->get(property);
00167         return CConfigProperty(newProperty);
00168 }
00169 
00170 CConfigProperty CConfigSection::firstProperty() const
00171 {
00172         IConfigProperty *newProperty = NULL;
00173         if (mIConfigSection)
00174                 newProperty = mIConfigSection->firstProperty();
00175         return CConfigProperty(newProperty);
00176 }
00177 
00178 #define CCONFIGSECTION_GET_MACRO(TYPE, ASSIGNMENT_STATEMENT)                            \
00179 bool CConfigSection::get(const std::string& property, TYPE *value) const        \
00180 {                                                                                                                                                       \
00181         if (mIConfigSection)                                                                                                    \
00182         {                                                                                                                                               \
00183                 IConfigProperty* iConfigProp = mIConfigSection->get(property);          \
00184                 if (iConfigProp)                                                                                                        \
00185                 {                                                                                                                                       \
00186                         ASSIGNMENT_STATEMENT;                                                                                   \
00187                         return true;                                                                                                    \
00188                 }                                                                                                                                       \
00189                 else                                                                                                                            \
00190                         return false;                                                                                                   \
00191         }                                                                                                                                               \
00192         else                                                                                                                                    \
00193                 return false;                                                                                                           \
00194 }
00195 
00196 CCONFIGSECTION_GET_MACRO(std::string    , *value = iConfigProp->toString())
00197 CCONFIGSECTION_GET_MACRO(bool                   , *value = iConfigProp->toBool())
00198 CCONFIGSECTION_GET_MACRO(char                   , *value = (char)iConfigProp->toInt())
00199 CCONFIGSECTION_GET_MACRO(unsigned char  , *value = (unsigned char)iConfigProp->toUInt())
00200 CCONFIGSECTION_GET_MACRO(short                  , *value = (short)iConfigProp->toInt())
00201 CCONFIGSECTION_GET_MACRO(unsigned short , *value = (unsigned short)iConfigProp->toUInt())
00202 CCONFIGSECTION_GET_MACRO(int                    , *value = (int)iConfigProp->toInt())
00203 CCONFIGSECTION_GET_MACRO(unsigned int   , *value = (unsigned int)iConfigProp->toUInt())
00204 CCONFIGSECTION_GET_MACRO(long                   , *value = iConfigProp->toInt())
00205 CCONFIGSECTION_GET_MACRO(unsigned long  , *value = iConfigProp->toUInt())
00206 CCONFIGSECTION_GET_MACRO(long long              , *value = iConfigProp->toInt())
00207 CCONFIGSECTION_GET_MACRO(unsigned long long     , *value = iConfigProp->toUInt())
00208 CCONFIGSECTION_GET_MACRO(float                  , *value = (float)iConfigProp->toFloat())
00209 CCONFIGSECTION_GET_MACRO(double                 , *value = iConfigProp->toFloat())
00210 // OptionVar variants
00211 CCONFIGSECTION_GET_MACRO(COptionBool    , *value = iConfigProp->toBool())
00212 CCONFIGSECTION_GET_MACRO(COptionInt             , *value = iConfigProp->toInt())
00213 CCONFIGSECTION_GET_MACRO(COptionDouble  , *value = iConfigProp->toFloat())
00214 CCONFIGSECTION_GET_MACRO(COptionChar    , *value = (char)iConfigProp->toInt())
00215 CCONFIGSECTION_GET_MACRO(COptionByte    , *value = (unsigned char)iConfigProp->toUInt())
00216 CCONFIGSECTION_GET_MACRO(COptionWord    , *value = (unsigned short)iConfigProp->toUInt())
00217 
00218 #define CCONFIGSECTION_GET_PRESET_MACRO(TYPE)                                                                                   \
00219 bool CConfigSection::get(const std::string& property, TYPE *value, TYPE preset) const   \
00220 {                                                                                                                                                                               \
00221         if (get(property, value))                                                                                                                       \
00222                 return true;                                                                                                                                    \
00223         else                                                                                                                                                            \
00224         {                                                                                                                                                                       \
00225                 *value = preset;                                                                                                                                \
00226                 return false;                                                                                                                                   \
00227         }                                                                                                                                                                       \
00228 }
00229 
00230 CCONFIGSECTION_GET_PRESET_MACRO(std::string)
00231 CCONFIGSECTION_GET_PRESET_MACRO(bool)
00232 CCONFIGSECTION_GET_PRESET_MACRO(char)
00233 CCONFIGSECTION_GET_PRESET_MACRO(unsigned char)
00234 CCONFIGSECTION_GET_PRESET_MACRO(short)
00235 CCONFIGSECTION_GET_PRESET_MACRO(unsigned short)
00236 CCONFIGSECTION_GET_PRESET_MACRO(int)
00237 CCONFIGSECTION_GET_PRESET_MACRO(unsigned int)
00238 CCONFIGSECTION_GET_PRESET_MACRO(long)
00239 CCONFIGSECTION_GET_PRESET_MACRO(unsigned long)
00240 CCONFIGSECTION_GET_PRESET_MACRO(long long)
00241 CCONFIGSECTION_GET_PRESET_MACRO(unsigned long long)
00242 CCONFIGSECTION_GET_PRESET_MACRO(double)
00243 CCONFIGSECTION_GET_PRESET_MACRO(float)
00244 
00245 bool CConfigSection::isNull() const
00246 {
00247         return (mIConfigSection == NULL);
00248 }
00249 
00250 bool CConfigSection::getArray(const std::string& property, CConfigPropertyArray* array) const
00251 {
00252         if (mIConfigSection)
00253         {
00254                 IConfigProperty* iConfigProp = mIConfigSection->get(property);
00255                 if (iConfigProp)
00256                 {
00257                         array->setData(iConfigProp->toString());
00258                         return true;
00259                 }
00260                 else
00261                         return false;
00262         }
00263         else
00264                 return false;
00265 }
00266 
00267 bool CConfigSection::getArray(const std::string& property, double* array, unsigned int maxNumElements) const
00268 {
00269         CConfigPropertyArray propArray;
00270         if (getArray(property, &propArray))
00271         {
00272                 for (unsigned int i=0; i<propArray.size() && i<maxNumElements; i++)
00273                         array[i] = propArray[i].toFloat();
00274                 return true;
00275         }
00276         else
00277                 return false;
00278 }
00279 
00280 
00281 // ************************************************************************ //
00282 // **************************** CConfigProperty *************************** //
00283 // ************************************************************************ //
00284 
00285 std::string CConfigProperty::value() const
00286 {
00287         if (mIConfigProperty)
00288                 return mIConfigProperty->toString();
00289         else
00290                 return "";
00291 }
00292 
00293 CConfigProperty CConfigProperty::nextProperty() const
00294 {
00295         IConfigProperty *newProperty = NULL;
00296         if (mIConfigProperty)
00297                 newProperty = mIConfigProperty->nextProperty();
00298         return CConfigProperty(newProperty);
00299 }
00300 
00301 bool CConfigProperty::isNull() const
00302 {
00303         return (mIConfigProperty == NULL);
00304 }
00305 
00306 void CConfigProperty::set(const std::string& value)
00307 {
00308         if (mIConfigProperty)
00309                 mIConfigProperty->set(value);
00310 }
00311 
00312 // ************************************************************************ //
00313 // ************************* CConfigPropertyArray ************************* //
00314 // ************************************************************************ //
00315 
00316 void CConfigPropertyArray::setData(const std::string& data, const char delimiter)
00317 {
00318         clear();
00319         std::istringstream ss(data);
00320         std::string dataFieldStr;
00321 
00322         while (std::getline(ss, dataFieldStr, delimiter))
00323                 push_back(IConfigPropertyString(dataFieldStr));
00324 }
00325 
00326 CConfigProperty CConfigPropertyArray::operator[](size_type __n)
00327 {
00328         return CConfigProperty(&at(__n));
00329 }
00330 
00331 // ************************************************************************ //
00332 // **************************** CConfiguration **************************** //
00333 // ************************************************************************ //
00334 
00335 /*
00336 int CConfiguration::resolveSectionConstants(const CConfigSection& section, CConfigConstants *constants)
00337 {
00338         int numResolvedConstants = 0;
00339 
00340         if (section.name() == std::string("constants"))
00341         {
00342                 //printf("(resolveSectionConstants) skipping constants section\n");
00343                 return 0;
00344         }
00345 
00346         //printf("(resolveSectionConstants) processing section \"%s\"\n", section.name().c_str());
00347         // process its properties
00348         for (CConfigProperty iProp = section.firstProperty(); !iProp.isNull(); iProp = iProp.nextProperty())
00349         {
00350                 //printf("processing property %s\n", iProp.name().c_str());
00351                 for (unsigned int iConst=0; iConst<constants->size(); iConst++)
00352                 {
00353                         if (iProp.value() == constants->at(iConst).mKey)
00354                         {
00355                                 //printf("\treplacing value \"%s\" with \"%s\"\n", iProp.value().c_str(), constants->at(iConst).mValue.c_str());
00356                                 iProp.set(constants->at(iConst).mValue);
00357                                 numResolvedConstants++;
00358                         }
00359                 }
00360         }
00361 
00362         // process its sections
00363         for (CConfigSection iSection = section.firstSection(); !iSection.isNull(); iSection = iSection.nextSection())
00364         {
00365                 numResolvedConstants += resolveSectionConstants(iSection, constants);
00366         }
00367 
00368         return numResolvedConstants;
00369 }
00370 
00371 int CConfiguration::resolveConstants()
00372 {
00373         CConfigConstants constants;
00374         CConfigSection constantsSection = root().section("constants");
00375         if (!constantsSection.isNull())
00376         {
00377                 for (CConfigProperty iProp = constantsSection.firstProperty(); !iProp.isNull(); iProp = iProp.nextProperty())
00378                 {
00379                         CConfigConstant newConstant("@" + iProp.name(), iProp.value());
00380                         //printf("Constant found: key = \"%s\", value = \"%s\"\n", iProp.name().c_str(), iProp.value().c_str());
00381                         constants.push_back(newConstant);
00382                 }
00383                 //printf("now processing sections\n");
00384                 return resolveSectionConstants(root(), &constants);
00385         }
00386         else
00387         {
00388                 //printf("no constants section found\n");
00389                 return 0;
00390         }
00391 }
00392 */
00393 
00394 std::string CConfiguration::replaceConstants(const std::string& expr, mu::Parser *parser)
00395 {
00396         char buf[256];
00397         std::string result(expr);
00398         mu::valmap_type cmap = parser->GetConst();
00399         if (cmap.size())
00400         {
00401                 for (mu::valmap_type::const_iterator item = cmap.begin(); item!=cmap.end(); ++item)
00402                 {
00403                         int pos=-1;
00404                         while ((pos = result.find(item->first, pos+1)) != (int)result.npos)
00405                         {
00406                                 if ((pos == 0 || !isalpha(result[pos-1])) &&
00407                                     (pos+item->first.length() == result.length() || !isalnum(result[pos+item->first.length()])))
00408                                 {
00409                                         if (snprintf(buf, 255, "%.20g", item->second) >= 255) buf[255] = '\0';
00410                                         result.replace(pos, item->first.length(), buf);
00411                                 }
00412                         }
00413                 }
00414         }
00415         return result;
00416 }
00417 
00418 std::string CConfiguration::replaceStringConstants(const std::string& expr)
00419 {
00420         std::string result(expr);
00421         if (mStringConstants.size())
00422         {
00423                 for (std::map<std::string, std::string>::const_iterator item = mStringConstants.begin(); item!=mStringConstants.end(); ++item)
00424                 {
00425                         int pos=-1;
00426                         while ((pos = result.find(item->first, pos+1)) != (int)result.npos)
00427                         {
00428                                 if ((pos == 0 || !isalpha(result[pos-1])) &&
00429                                     (pos+item->first.length() == result.length() || !isalnum(result[pos+item->first.length()])))
00430                                 {
00431                                         result.replace(pos, item->first.length(), item->second);
00432                                 }
00433                         }
00434                 }
00435         }
00436         return result;
00437 }
00438 
00439 int CConfiguration::resolveExpressionsInSection(const CConfigSection& section, mu::Parser *parser)
00440 {
00441         int numResolvedExpressions = 0;
00442 
00443         if (shouldParseNode(section.name()))
00444         {
00445                 //printf("(resolveSectionConstants) processing section \"%s\"\n", section.name().c_str());
00446                 // process its properties
00447                 for (CConfigProperty iProp = section.firstProperty(); !iProp.isNull(); iProp = iProp.nextProperty())
00448                 {
00449                         //printf("processing property %s\n", iProp.name().c_str());
00450                         // Make sure we should not skip this property: check name and value for exclusion
00451                         if (shouldParseNode(iProp.name()) && !isRegisteredString(iProp.value()))
00452                         {
00453                                 std::string expression = iProp.value();
00454                                 char buf[256];
00455 
00456                                 // Try to evaluate the expression as a floating point value
00457                                 parser->SetExpr(expression);
00458                                 try
00459                                 {
00460                                         double resolvedValue = parser->Eval();
00461                                         if (snprintf(buf, 255, "%.20g", resolvedValue) >= 255) buf[255] = '\0';
00462                                         expression = std::string(buf);
00463                                 }
00464                                 catch (...)
00465                                 {
00466                                         // Unable to resolve expression, replace constants instead
00467                                         expression = replaceConstants(expression, parser);
00468 
00469                                         // Try to define all string constants as variables and then see if there are unknowns left
00470                                         //TODO: It might be slow to define and remove variables repeatedly at this place in the code
00471                                         double dummy=0;
00472                                         for (std::map<std::string, std::string>::const_iterator item = mStringConstants.begin(); item!=mStringConstants.end(); ++item)
00473                                                 parser->DefineVar(item->first, &dummy);
00474                                         parser->SetExpr(expression);
00475                                         try
00476                                         {
00477                                                 parser->Eval();
00478                                                 // If we survived Eval(), all unknowns are defined as string constants, so we are happy
00479                                                 //mLogCrawlLn("Found expression with string constants!");
00480                                         }
00481                                         catch (...)
00482                                         {
00483                                                 // There are some unknowns left. Perform a final check to ignore array-type entries
00484                                                 if (expression.find(CONFIGURATION_ARRAY_DELIMITER) == std::string::npos)
00485                                                         mLogNoticeLn("Found expression with unknowns: \"" << expression << "\"");
00486                                         }
00487                                         // Undefine the string constants again.
00488                                         for (std::map<std::string, std::string>::const_iterator item = mStringConstants.begin(); item!=mStringConstants.end(); ++item)
00489                                                 parser->RemoveVar(item->first);
00490                                         // Replace string constants in the expression
00491                                         expression = replaceStringConstants(expression);
00492                                 }
00493 
00494                                 if (expression != iProp.value())
00495                                 {
00496                                         mLogCrawlLn("Resolved expression \"" << iProp.value() << "\" to \"" << expression << "\".");
00497                                         numResolvedExpressions++;
00498                                         iProp.set(expression);
00499                                 }
00500                                 // If the property is verbose, print its value
00501                                 if (iProp.isVerbose())
00502                                         mLogNoticeLn("**VERBOSE** " << iProp.name() << " = " << expression);
00503                         }
00504                 }
00505 
00506                 // process its sections
00507                 for (CConfigSection iSection = section.firstSection(); !iSection.isNull(); iSection = iSection.nextSection())
00508                         numResolvedExpressions += resolveExpressionsInSection(iSection, parser);
00509         }
00510 
00511         return numResolvedExpressions;
00512 }
00513 
00514 int CConfiguration::resolveExpressions()
00515 {
00516         // Define math parser
00517         mu::Parser parser;
00518 
00519         // Define constants for parser.
00520         // Also parse the constant expressions, using the defined constants from preceding entries :)
00521         CConfigSection constantsSection = root().section(CONST_ConfConstantsSectionName);
00522         if (!constantsSection.isNull())
00523         {
00524                 for (CConfigProperty iProp = constantsSection.firstProperty(); !iProp.isNull(); iProp = iProp.nextProperty())
00525                 {
00526                         // Convert the property value into a constant value using the parser itself
00527                         parser.SetExpr(iProp.value());
00528                         try
00529                         {
00530                                 // Evaluate. String constants will automatically lead to the catch(&e) section.
00531                                 double resolvedValue = parser.Eval();
00532                                 // Check if constant was defined before, and whether that was with a *different* value.
00533                                 // If so, throw an error. Multiply defining a constant, such as pi, is okay.
00534                                 bool constHasConflict=false;
00535                                 mu::valmap_type cmap = parser.GetConst();
00536                                 if (cmap.size())
00537                                 {
00538                                         mu::valmap_type::const_iterator item = cmap.begin();
00539                                         for (; item!=cmap.end(); ++item)
00540                                                 if (item->first == iProp.name())
00541                                                         if (item->second != resolvedValue)
00542                                                         {
00543                                                                 constHasConflict = true;
00544                                                                 break;
00545                                                         }
00546                                 }
00547                                 // Check if this name is in use as a string constant
00548                                 if (mStringConstants.find(iProp.name()) != mStringConstants.end())
00549                                 {
00550                                         // The value cannot be the same since string constants don't evaluate, while this property did
00551                                         // Therefore, this always means there's a conflict.
00552                                         constHasConflict = true;
00553                                 }
00554 
00555                                 // If it's a new one, define it!
00556                                 if (!constHasConflict)
00557                                 {
00558                                         parser.DefineConst(iProp.name(), resolvedValue);
00559                                         mLogCrawlLn(iProp.name() << "=" << std::setprecision(16) << resolvedValue);
00560                                         // If it's verbose, print its value
00561                                         if (iProp.isVerbose())
00562                                                 mLogNoticeLn("**VERBOSE** " << iProp.name() << " = " << std::setprecision(16) << resolvedValue);
00563                                 }
00564                                 else
00565                                         mLogErrorLn("Constant \"" << iProp.name() << "\" was redefined with different value " << resolvedValue << "!");
00566                                 //printf("[DEBUG] Found constant with name \"%s\" and value \"%g\"\n", iProp.name().c_str(), resolvedValue);
00567                         }
00568                         catch (mu::Parser::exception_type &e)
00569                         {
00570                                 // Define it as a string constant, using the constants and string constants defined so far.
00571                                 // Check if constant was defined before
00572                                 std::map<std::string, std::string>::iterator strConst = mStringConstants.find(iProp.name());
00573                                 if ((strConst == mStringConstants.end()) && (parser.GetConst().find(iProp.name()) == parser.GetConst().end()))
00574                                 {
00575                                         mStringConstants[iProp.name()] = replaceStringConstants(replaceConstants(iProp.value(), &parser));
00576                                         // The following log message acts as a 'soft warning' (info) to the user in case
00577                                         // an expression should resolve to a float, but doesn't due to a typo.
00578                                         mLogInfoLn("Defined string constant \"" << iProp.name() << "\"");
00579                                 }
00580                                 else
00581                                         // If it is redefined with the same value, it's ok. Otherwise, throw error
00582                                         if (strConst->second != iProp.value())
00583                                                 mLogErrorLn("Constant \"" << iProp.name() << "\" was redefined with different value: " << iProp.value());
00584                         }
00585                 }
00586         }
00587         else
00588         {
00589                 //printf("no constants section found\n");
00590         }
00591 
00592         // Define registered strings that will be ignored by the math parser
00593         CConfigSection stringsSection = root().section(CONST_ConfStringsSectionName);
00594         if (!stringsSection.isNull())
00595         {
00596                 for (CConfigProperty iProp = stringsSection.firstProperty(); !iProp.isNull(); iProp = iProp.nextProperty())
00597                 {
00598                         if ((iProp.name() == "s") || (iProp.name() == "string"))
00599                                 mRegisteredStrings.push_back(iProp.value());
00600                         else if ((iProp.name() == "n") || (iProp.name() == "node"))
00601                                 mNodesExcludedFromParsing.push_back(iProp.value());
00602                         else
00603                                 mLogErrorLn("Strings section contains item of unknown type <" << iProp.name() << ">. Either use <s> or <string> for strings, and <n> or <node> for trusted node names.");
00604                 }
00605         }
00606         else
00607                 mLogNoticeLn("You did not specify a <strings> section with validated strings occurring in your configuration file. You may encounter numerous parser warnings.");
00608 
00609         // We register the constants and strings sections too, because they don't have to be parsed
00610         mNodesExcludedFromParsing.push_back(CONST_ConfConstantsSectionName);
00611         mNodesExcludedFromParsing.push_back(CONST_ConfStringsSectionName);
00612 
00613         // Start resolving expressions by processing the root node
00614         return resolveExpressionsInSection(root(), &parser);
00615 }
00616 
00617 bool CConfiguration::isRegisteredString(const std::string& str)
00618 {
00619         for (unsigned int i=0; i<mRegisteredStrings.size(); i++)
00620                 if (mRegisteredStrings[i] == str)
00621                         return true;
00622 
00623         return false;
00624 }
00625 
00626 bool CConfiguration::shouldParseNode(const std::string& nodeName)
00627 {
00628         for (unsigned int i=0; i<mNodesExcludedFromParsing.size(); i++)
00629                 if (mNodesExcludedFromParsing[i] == nodeName)
00630                         return false;
00631 
00632         return true;
00633 }


threemxl
Author(s):
autogenerated on Thu Jun 6 2019 21:10:52