00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "ArExport.h"
00027 #include "ariaOSDef.h"
00028 #include "ArConfig.h"
00029 #include "ArArgumentBuilder.h"
00030 #include "ArLog.h"
00031
00032
00033
00034 #define ARDEBUG_CONFIG
00035
00036 #if (defined(ARDEBUG_CONFIG))
00037
00038 #define IFDEBUG(code) {code;}
00039 #else
00040 #define IFDEBUG(code)
00041 #endif
00042
00043
00044
00045
00046 #if (defined(_DEBUG) && defined(ARDEBUG_CONFIG2))
00047 #define IFDEBUG2(code) {code;}
00048 #else
00049 #define IFDEBUG2(code)
00050 #endif
00051
00052
00060 AREXPORT ArConfig::ArConfig(const char *baseDirectory,
00061 bool noBlanksBetweenParams,
00062 bool ignoreBounds,
00063 bool failOnBadSection,
00064 bool saveUnknown) :
00065 myRobotName(""),
00066 myConfigName(""),
00067 myLogPrefix("ArConfig: "),
00068
00069 myProcessFileCBList(),
00070 myNoBlanksBetweenParams(noBlanksBetweenParams),
00071 myBaseDirectory(),
00072 myParser(NULL),
00073 mySections(),
00074 mySectionsToParse(NULL),
00075 myParserCB(this, &ArConfig::parseArgument),
00076 mySectionCB(this, &ArConfig::parseSection),
00077 myUnknownCB(this, &ArConfig::parseUnknown)
00078 {
00079
00080
00081
00082
00083
00084 addParserHandlers();
00085
00086 myArgumentParser = NULL;
00087 mySaveUnknown = saveUnknown;
00088 setBaseDirectory(baseDirectory);
00089 myIgnoreBounds = ignoreBounds;
00090 myFailOnBadSection = failOnBadSection;
00091 myProcessFileCallbacksLogLevel = ArLog::Verbose;
00092 myUsingSections = false;
00093 mySectionBroken = false;
00094 mySectionIgnored = false;
00095 myDuplicateParams = false;
00096
00097 myParserCB.setName("ArConfig::parseArgument");
00098 mySectionCB.setName("ArConfig::parseSection");
00099 myUnknownCB.setName("ArConfig::parseUnknown");
00100
00101 mySection = "";
00102 }
00103
00104 AREXPORT ArConfig::~ArConfig()
00105 {
00106 clearSections();
00107 }
00108
00109
00110 AREXPORT ArConfig::ArConfig(const ArConfig &config) :
00111 myRobotName(""),
00112 myConfigName(""),
00113 myLogPrefix("ArConfig: "),
00114
00115 myProcessFileCBList(),
00116 myNoBlanksBetweenParams(config.myNoBlanksBetweenParams),
00117 myBaseDirectory(),
00118 myParser(NULL),
00119 mySections(),
00120 myParserCB(this, &ArConfig::parseArgument),
00121 mySectionCB(this, &ArConfig::parseSection),
00122 myUnknownCB(this, &ArConfig::parseUnknown)
00123 {
00124 myArgumentParser = NULL;
00125 setBaseDirectory(config.getBaseDirectory());
00126 myIgnoreBounds = config.myIgnoreBounds;
00127 myFailOnBadSection = config.myFailOnBadSection;
00128 myProcessFileCallbacksLogLevel = config.myProcessFileCallbacksLogLevel;
00129 mySectionBroken = config.mySectionBroken;
00130 mySectionIgnored = config.mySectionIgnored;
00131 mySection = config.mySection;
00132 myUsingSections = config.myUsingSections;
00133 myDuplicateParams = config.myDuplicateParams;
00134
00135
00136 std::list<ArConfigSection *>::const_iterator it;
00137 for (it = config.mySections.begin();
00138 it != config.mySections.end();
00139 it++)
00140 {
00141 mySections.push_back(new ArConfigSection(*(*it)));
00142 }
00143 copySectionsToParse(config.mySectionsToParse);
00144
00145 myParserCB.setName("ArConfig::parseArgument");
00146 mySectionCB.setName("ArConfig::parseSection");
00147 myUnknownCB.setName("ArConfig::parseUnknown");
00148
00149 myParser.remHandler(&myParserCB);
00150 myParser.remHandler(&mySectionCB);
00151 myParser.remHandler(&myUnknownCB);
00152 addParserHandlers();
00153
00154 }
00155
00156
00157 AREXPORT ArConfig &ArConfig::operator=(const ArConfig &config)
00158 {
00159 if (this != &config) {
00160
00161
00162 IFDEBUG2(ArLog::log(ArLog::Verbose,
00163 "%soperator= (from %s) begins",
00164 myLogPrefix.c_str(),
00165 config.myLogPrefix.c_str()));
00166
00167
00168
00169
00170
00171
00172
00173 myArgumentParser = NULL;
00174 setBaseDirectory(config.getBaseDirectory());
00175 myNoBlanksBetweenParams = config.myNoBlanksBetweenParams;
00176 myIgnoreBounds = config.myIgnoreBounds;
00177 myFailOnBadSection = config.myFailOnBadSection;
00178 mySection = config.mySection;
00179 mySectionBroken = config.mySectionBroken;
00180 mySectionIgnored = config.mySectionIgnored;
00181 myUsingSections = config.myUsingSections;
00182 myDuplicateParams = config.myDuplicateParams;
00183 mySections.clear();
00184 std::list<ArConfigSection *>::const_iterator it;
00185 for (it = config.mySections.begin();
00186 it != config.mySections.end();
00187 it++)
00188 {
00189 mySections.push_back(new ArConfigSection(*(*it)));
00190 }
00191
00192 copySectionsToParse(config.mySectionsToParse);
00193
00194 myParser.remHandler(&myParserCB);
00195 myParser.remHandler(&mySectionCB);
00196 myParser.remHandler(&myUnknownCB);
00197 addParserHandlers();
00198
00199 IFDEBUG2(ArLog::log(ArLog::Verbose,
00200 "%soperator= (from %s) ends",
00201 myLogPrefix.c_str(),
00202 config.myLogPrefix.c_str()));
00203 }
00204 return *this;
00205
00206 }
00207
00216 AREXPORT void ArConfig::setConfigName(const char *configName,
00217 const char *robotName)
00218 {
00219 myConfigName = ((configName != NULL) ? configName : "");
00220 myRobotName = ((robotName != NULL) ? robotName : "");
00221 myLogPrefix = "";
00222
00223 if (!myRobotName.empty()) {
00224 myLogPrefix = myRobotName + ": ";
00225 }
00226 myLogPrefix += "ArConfig";
00227
00228 if (!myConfigName.empty()) {
00229 myLogPrefix += " (" + myConfigName + ")";
00230 }
00231
00232 myLogPrefix += ": ";
00233 }
00234
00235 AREXPORT void ArConfig::log(bool isSummary)
00236 {
00237 std::list<ArConfigArg> *params = NULL;
00238
00239 ArLog::log(ArLog::Normal,
00240 "%slog",
00241 myLogPrefix.c_str());
00242
00243 for (std::list<ArConfigSection *>::const_iterator it = mySections.begin();
00244 it != mySections.end();
00245 it++)
00246 {
00247 params = (*it)->getParams();
00248
00249 if (params == NULL) {
00250 ArLog::log(ArLog::Normal, " Section %s has NULL params",
00251 (*it)->getName());
00252
00253 continue;
00254 }
00255
00256 if (isSummary) {
00257 ArLog::log(ArLog::Normal, " Section %s has %i params",
00258 (*it)->getName(), params->size());
00259 continue;
00260 }
00261
00262 ArLog::log(ArLog::Normal, " Section %s:",
00263 (*it)->getName());
00264
00265 for (std::list<ArConfigArg>::iterator pit = params->begin(); pit != params->end(); pit++)
00266 {
00267 (*pit).log();
00268 }
00269
00270 }
00271
00272 ArLog::log(ArLog::Normal,
00273 "%send",
00274 myLogPrefix.c_str());
00275
00276 }
00277
00278
00279 AREXPORT void ArConfig::clearSections(void)
00280 {
00281 IFDEBUG2(ArLog::log(ArLog::Verbose,
00282 "%sclearSections() begin",
00283 myLogPrefix.c_str()));
00284
00285 while (mySections.begin() != mySections.end())
00286 {
00287 delete mySections.front();
00288 mySections.pop_front();
00289 }
00290
00291 delete mySectionsToParse;
00292 mySectionsToParse = NULL;
00293
00294 IFDEBUG2(ArLog::log(ArLog::Verbose,
00295 "%sclearSections() end",
00296 myLogPrefix.c_str()));
00297
00298 }
00299
00300 AREXPORT void ArConfig::clearAll(void)
00301 {
00302 clearSections();
00303 myProcessFileCBList.clear();
00304 }
00305
00306 void ArConfig::addParserHandlers(void)
00307 {
00308 std::list<ArConfigSection *>::const_iterator it;
00309 std::list<ArConfigArg> *params;
00310 std::list<ArConfigArg>::iterator pit;
00311
00312 if (!myParser.addHandlerWithError("section", &mySectionCB)) {
00313 IFDEBUG(ArLog::log(ArLog::Verbose,
00314 "%sCould not add section parser (probably unimportant)",
00315 myLogPrefix.c_str()));
00316 }
00317 for (it = mySections.begin();
00318 it != mySections.end();
00319 it++)
00320 {
00321 params = (*it)->getParams();
00322 if (params == NULL)
00323 continue;
00324 for (pit = params->begin(); pit != params->end(); pit++)
00325 {
00326 if (!myParser.addHandlerWithError((*pit).getName(), &myParserCB)) {
00327 IFDEBUG(ArLog::log(ArLog::Verbose,
00328 "%sCould not add keyword %s (probably unimportant)",
00329 myLogPrefix.c_str(),
00330 (*pit).getName()));
00331 }
00332 }
00333 }
00334
00335
00336 if (!myParser.addHandlerWithError(NULL, &myUnknownCB)) {
00337 IFDEBUG(ArLog::log(ArLog::Verbose,
00338 "%sCould not add unknown param parser (probably unimportant)",
00339 myLogPrefix.c_str()));
00340 }
00341 }
00342
00347 AREXPORT void ArConfig::setSectionComment(const char *sectionName,
00348 const char *comment)
00349 {
00350 ArConfigSection *section = findSection(sectionName);
00351
00352 if (section == NULL)
00353 {
00354 ArLog::log(ArLog::Verbose, "%sMaking new section '%s' (for comment)",
00355 myLogPrefix.c_str(), sectionName);
00356
00357 section = new ArConfigSection(sectionName, comment);
00358 mySections.push_back(section);
00359 }
00360 else
00361 section->setComment(comment);
00362 }
00363
00364
00369 AREXPORT bool ArConfig::addSectionFlags(const char *sectionName,
00370 const char *flags)
00371 {
00372 ArConfigSection *section = findSection(sectionName);
00373
00374 if (section == NULL)
00375 {
00376 ArLog::log(ArLog::Verbose, "%sMaking new section '%s' (flags)",
00377 myLogPrefix.c_str(), sectionName);
00378 section = new ArConfigSection(sectionName);
00379 section->addFlags(flags);
00380
00381 mySections.push_back(section);
00382 }
00383 else
00384 section->addFlags(flags);
00385 return true;
00386 }
00387
00392 AREXPORT bool ArConfig::remSectionFlag(const char *sectionName,
00393 const char *flag)
00394 {
00395 ArConfigSection *section = findSection(sectionName);
00396
00397 if (section == NULL)
00398 return false;
00399
00400 section->remFlag(flag);
00401 return true;
00402 }
00403
00410 AREXPORT bool ArConfig::addParam(const ArConfigArg &arg,
00411 const char *sectionName,
00412 ArPriority::Priority priority,
00413 const char *displayHint)
00414 {
00415 ArConfigSection *section = findSection(sectionName);
00416
00417
00418 if (section == NULL)
00419 {
00420 ArLog::log(ArLog::Verbose, "ArConfigArg %s: Making new section '%s' (for param)",
00421 myLogPrefix.c_str(), sectionName);
00422 section = new ArConfigSection(sectionName);
00423 mySections.push_back(section);
00424 }
00425
00426 std::list<ArConfigArg> *params = section->getParams();
00427
00428 if (params == NULL)
00429 {
00430 ArLog::log(ArLog::Terse, "%sSomething has gone hideously wrong in ArConfig::addParam",
00431 myLogPrefix.c_str());
00432 return false;
00433 }
00434
00435 if (arg.getType() == ArConfigArg::SEPARATOR &&
00436 ( !params->empty() && params->back().getType() == ArConfigArg::SEPARATOR) )
00437 {
00438
00439 return true;
00440 }
00441
00442
00443 std::list<ArConfigSection *>::iterator sectionIt;
00444
00445 for (sectionIt = mySections.begin();
00446 sectionIt != mySections.end();
00447 sectionIt++)
00448 {
00449
00450
00451
00452 if (strlen(arg.getName()) > 0 &&
00453 (*sectionIt)->findParam(arg.getName()) != NULL &&
00454 strcasecmp((*sectionIt)->getName(), section->getName()) != 0)
00455 {
00456 ArLog::log(ArLog::Verbose,
00457 "%sParameter %s duplicated in section %s and %s",
00458 myLogPrefix.c_str(),
00459 arg.getName(), (*sectionIt)->getName(), section->getName());
00460 myDuplicateParams = true;
00461 }
00462 }
00463
00464
00465
00466 if (!myParser.addHandlerWithError(arg.getName(), &myParserCB))
00467 {
00468 IFDEBUG(ArLog::log(ArLog::Verbose, "%sCould not add parameter '%s' to file parser, probably already there.",
00469 myLogPrefix.c_str(), arg.getName()));
00470
00471 }
00472
00473
00474 section->remStringHolder(arg.getName());
00475
00476
00477
00478 params->push_back(arg);
00479 params->back().setConfigPriority(priority);
00480 params->back().setDisplayHint(displayHint);
00481 params->back().setIgnoreBounds(myIgnoreBounds);
00482
00483 IFDEBUG2(ArLog::log(ArLog::Verbose, "%sAdded parameter '%s' to section '%s'",
00484 myLogPrefix.c_str(), arg.getName(), section->getName()));
00485
00486 return true;
00487 }
00488
00495 AREXPORT bool ArConfig::addComment(const char *comment, const char *sectionName,
00496 ArPriority::Priority priority)
00497 {
00498 return addParam(ArConfigArg(comment), sectionName, priority);
00499 }
00500
00501
00502
00516 AREXPORT bool ArConfig::parseSection(ArArgumentBuilder *arg,
00517 char *errorBuffer,
00518 size_t errorBufferLen)
00519 {
00520 if (myFailOnBadSection && errorBuffer != NULL)
00521 errorBuffer[0] = '\0';
00522
00523 std::list<ArConfigSection *>::iterator sectionIt;
00524 ArConfigSection *section = NULL;
00525
00526 if (myFailOnBadSection && errorBuffer != NULL)
00527 errorBuffer[0] = '\0';
00528 for (sectionIt = mySections.begin();
00529 sectionIt != mySections.end();
00530 sectionIt++)
00531 {
00532 section = (*sectionIt);
00533 if (ArUtil::strcasecmp(section->getName(), arg->getFullString()) == 0)
00534 {
00535 bool isParseSection = true;
00536 if (mySectionsToParse != NULL) {
00537 isParseSection = false;
00538 for (std::list<std::string>::iterator sIter = mySectionsToParse->begin();
00539 sIter != mySectionsToParse->end();
00540 sIter++) {
00541 std::string sp = *sIter;
00542 if (ArUtil::strcasecmp(section->getName(), sp.c_str()) == 0) {
00543 isParseSection = true;
00544 break;
00545 }
00546 }
00547
00548 }
00549
00550 if (isParseSection) {
00551
00552 ArLog::log(ArLog::Verbose, "%sConfig switching to section '%s'",
00553 myLogPrefix.c_str(),
00554 arg->getFullString());
00555
00556
00557 mySection = arg->getFullString();
00558 mySectionBroken = false;
00559 mySectionIgnored = false;
00560 myUsingSections = true;
00561 return true;
00562 }
00563 else {
00564
00565 ArLog::log(ArLog::Verbose, "%signoring section '%s'",
00566 myLogPrefix.c_str(),
00567 arg->getFullString());
00568
00569
00570 mySection = arg->getFullString();
00571 mySectionBroken = false;
00572 mySectionIgnored = true;
00573 myUsingSections = true;
00574 return true;
00575
00576 }
00577 }
00578 }
00579
00580
00581 if (myFailOnBadSection)
00582 {
00583 mySection = "";
00584 mySectionBroken = true;
00585 mySectionIgnored = false;
00586 snprintf(errorBuffer, errorBufferLen, "ArConfig: Could not find section '%s'",
00587 arg->getFullString());
00588
00589 ArLog::log(ArLog::Terse,
00590 "%sCould not find section '%s', failing",
00591 myLogPrefix.c_str(),
00592 arg->getFullString());
00593 return false;
00594 }
00595 else
00596 {
00597 if (mySaveUnknown)
00598 {
00599 ArLog::log(ArLog::Verbose, "%smaking new section '%s' to save unknown",
00600 myLogPrefix.c_str(), arg->getFullString());
00601 mySection = arg->getFullString();
00602 mySectionBroken = false;
00603 mySectionIgnored = false;
00604 section = new ArConfigSection(arg->getFullString());
00605 mySections.push_back(section);
00606 }
00607 else
00608 {
00609 mySection = "";
00610 mySectionBroken = false;
00611 mySectionIgnored = true;
00612 ArLog::log(ArLog::Normal,
00613 "%sIgnoring section '%s'",
00614 myLogPrefix.c_str(),
00615 arg->getFullString());
00616 }
00617 return true;
00618 }
00619 }
00620
00635 AREXPORT bool ArConfig::parseArgument(ArArgumentBuilder *arg,
00636 char *errorBuffer,
00637 size_t errorBufferLen)
00638 {
00639 std::list<ArConfigSection *>::iterator sectionIt;
00640 std::list<ArConfigArg>::iterator paramIt;
00641 ArConfigSection *section = NULL;
00642 std::list<ArConfigArg> *params = NULL;
00643 ArConfigArg *param = NULL;
00644 int valInt = 0;
00645 double valDouble = 0;
00646 bool valBool = false;
00647 bool ret = true;
00648
00649 if (mySectionBroken)
00650 {
00651 ArLog::log(ArLog::Verbose, "%sSkipping parameter %s because section broken",
00652 myLogPrefix.c_str(),
00653 arg->getExtraString());
00654 if (myFailOnBadSection)
00655 {
00656 snprintf(errorBuffer, errorBufferLen,
00657 "Failed because broken config section");
00658 return false;
00659 }
00660 else
00661 {
00662 return true;
00663 }
00664 }
00665 else if (mySectionIgnored) {
00666 return true;
00667 }
00668
00669
00670 if (myDuplicateParams && myUsingSections && mySection.size() <= 0)
00671 {
00672 snprintf(errorBuffer, errorBufferLen,
00673 "%s not in section, client needs an upgrade",
00674 arg->getExtraString());
00675
00676 ArLog::log(ArLog::Normal,
00677 "%s%s not in a section, client needs an upgrade",
00678 myLogPrefix.c_str(),
00679 arg->getExtraString());
00680 return false;
00681 }
00682
00683
00684 bool found = false;
00685
00686 if (errorBuffer != NULL)
00687 errorBuffer[0] = '\0';
00688 for (sectionIt = mySections.begin();
00689 sectionIt != mySections.end();
00690 sectionIt++)
00691 {
00692 section = (*sectionIt);
00693
00694
00695
00696
00697
00698
00699 if (ArUtil::strcasecmp(mySection, section->getName()))
00700 continue;
00701 params = section->getParams();
00702
00703 for (paramIt = params->begin(); paramIt != params->end(); paramIt++)
00704 {
00705 if (strcasecmp((*paramIt).getName(), arg->getExtraString()) == 0)
00706 {
00707
00708 found = true;
00709 param = &(*paramIt);
00710 if (param->getType() != ArConfigArg::STRING &&
00711 param->getType() != ArConfigArg::FUNCTOR &&
00712 arg->getArg(0) == NULL)
00713 {
00714 IFDEBUG(ArLog::log(ArLog::Verbose, "%sparameter '%s' has no argument.",
00715 myLogPrefix.c_str(),
00716 param->getName()));
00717 continue;
00718 }
00719 if ((param->getType() == ArConfigArg::DESCRIPTION_HOLDER) ||
00720 (param->getType() == ArConfigArg::SEPARATOR))
00721 {
00722
00723 }
00724
00725 else if (param->getType() == ArConfigArg::INT)
00726 {
00727
00728 if (!arg->isArgInt(0))
00729 {
00730 ArLog::log(ArLog::Terse,
00731 "%sparameter '%s' is an integer parameter but was given non-integer argument of '%s'",
00732 myLogPrefix.c_str(), param->getName(), arg->getArg(0));
00733 ret = false;
00734 if (errorBuffer != NULL)
00735 snprintf(errorBuffer, errorBufferLen, "%s is an integer parameter but was given non-integer argument of '%s'", param->getName(), arg->getArg(0));
00736 continue;
00737 }
00738 valInt = arg->getArgInt(0);
00739 if (param->setInt(valInt, errorBuffer, errorBufferLen))
00740 {
00741 IFDEBUG2(ArLog::log(ArLog::Verbose, "%sSet parameter '%s' to '%d'",
00742 myLogPrefix.c_str(), param->getName(), valInt));
00743 continue;
00744 }
00745 else
00746 {
00747 ArLog::log(ArLog::Verbose, "%sCould not set parameter '%s' to '%d'",
00748 myLogPrefix.c_str(), param->getName(), valInt);
00749 ret = false;
00750 continue;
00751 }
00752 }
00753 else if (param->getType() == ArConfigArg::DOUBLE)
00754 {
00755
00756 if (!arg->isArgDouble(0))
00757 {
00758 ArLog::log(ArLog::Terse, "%sparameter '%s' is a double parameter but was given non-double argument of '%s'",
00759 myLogPrefix.c_str(), param->getName(), arg->getArg(0));
00760 if (errorBuffer != NULL)
00761 snprintf(errorBuffer, errorBufferLen, "%s is a double parameter but was given non-double argument of '%s'", param->getName(), arg->getArg(0));
00762
00763 ret = false;
00764 continue;
00765 }
00766 valDouble = arg->getArgDouble(0);
00767 if (param->setDouble(valDouble, errorBuffer, errorBufferLen))
00768 {
00769 IFDEBUG2(ArLog::log(ArLog::Verbose, "%sSet parameter '%s' to '%.10f'",
00770 myLogPrefix.c_str(), param->getName(), valDouble));
00771 continue;
00772 }
00773 else
00774 {
00775 ArLog::log(ArLog::Verbose, "%sCould not set parameter '%s' to '%.10f'",
00776 myLogPrefix.c_str(), param->getName(), valDouble);
00777 ret = false;
00778 continue;
00779 }
00780 }
00781 else if (param->getType() == ArConfigArg::BOOL)
00782 {
00783
00784 if (!arg->isArgBool(0))
00785 {
00786 ArLog::log(ArLog::Terse, "%sparameter '%s' is a bool parameter but was given non-bool argument of '%s'",
00787 myLogPrefix.c_str(), param->getName(), arg->getArg(0));
00788 ret = false;
00789 if (errorBuffer != NULL)
00790 snprintf(errorBuffer, errorBufferLen, "%s is a bool parameter but was given non-bool argument of '%s'", param->getName(), arg->getArg(0));
00791 continue;
00792 }
00793 valBool = arg->getArgBool(0);
00794 if (param->setBool(valBool, errorBuffer, errorBufferLen))
00795 {
00796 IFDEBUG2(ArLog::log(ArLog::Verbose, "%sSet parameter '%s' to %s",
00797 myLogPrefix.c_str(), param->getName(), valBool ? "true" : "false" ));
00798 continue;
00799 }
00800 else
00801 {
00802 ArLog::log(ArLog::Verbose, "%sCould not set parameter '%s' to %s",
00803 myLogPrefix.c_str(), param->getName(), valBool ? "true" : "false" );
00804 ret = false;
00805 continue;
00806 }
00807 }
00808 else if (param->getType() == ArConfigArg::STRING)
00809 {
00810 if (param->setString(arg->getFullString()))
00811 {
00812 IFDEBUG2(ArLog::log(ArLog::Verbose, "%sSet parameter string '%s' to '%s'",
00813 myLogPrefix.c_str(),
00814 param->getName(), param->getString()));
00815 continue;
00816 }
00817 else
00818 {
00819 ArLog::log(ArLog::Verbose, "%sCould not set string parameter '%s' to '%s'",
00820 myLogPrefix.c_str(),
00821 param->getName(), param->getString());
00822 if (errorBuffer != NULL && errorBuffer[0] == '\0')
00823 snprintf(errorBuffer, errorBufferLen, "%s could not be set to '%s'.", param->getName(), arg->getFullString());
00824
00825 ret = false;
00826 continue;
00827 }
00828 }
00829 else if (param->getType() == ArConfigArg::FUNCTOR)
00830 {
00831 if (param->setArgWithFunctor(arg))
00832 {
00833 IFDEBUG2(ArLog::log(ArLog::Verbose, "%sSet arg '%s' with '%s'",
00834 myLogPrefix.c_str(), param->getName(), arg->getFullString()));
00835 continue;
00836 }
00837 else
00838 {
00839 ArLog::log(ArLog::Verbose, "ArConfig: Could not set parameter '%s' to '%s'",
00840 myLogPrefix.c_str(),
00841 param->getName(), arg->getFullString());
00842
00843 if (errorBuffer != NULL && errorBuffer[0] == '\0')
00844 snprintf(errorBuffer, errorBufferLen, "%s could not be set to '%s'.", param->getName(), arg->getFullString());
00845 ret = false;
00846 continue;
00847 }
00848 }
00849 else
00850 {
00851 ArLog::log(ArLog::Terse, "%sHave no argument type for config '%s' in section, got string '%s', in section '%s'.",
00852 myLogPrefix.c_str(), arg->getExtraString(), arg->getFullString(), mySection.c_str());
00853 }
00854 }
00855 }
00856 }
00857
00858 if (!found)
00859 {
00860 ArArgumentBuilder unknown;
00861 unknown.add(arg->getExtraString());
00862 unknown.add(arg->getFullString());
00863 return parseUnknown(&unknown, errorBuffer, errorBufferLen);
00864 }
00865 return ret;
00866 }
00867
00881 AREXPORT bool ArConfig::parseUnknown(ArArgumentBuilder *arg,
00882 char *errorBuffer,
00883 size_t errorBufferLen)
00884 {
00885 if (arg->getArgc() < 1)
00886 {
00887 IFDEBUG(ArLog::log(ArLog::Verbose, "%sEmpty arg in section '%s', ignoring it",
00888 myLogPrefix.c_str(), mySection.c_str()));
00889 return true;
00890 }
00891 if (mySaveUnknown)
00892 {
00893 if (arg->getArgc() < 2)
00894 {
00895 ArLog::log(ArLog::Verbose, "%sNo arg for param '%s' in section '%s', saving it anyways",
00896 myLogPrefix.c_str(), arg->getArg(0), mySection.c_str());
00897 addParam(ArConfigArg(arg->getArg(0), ""),
00898 mySection.c_str());
00899 }
00900 else
00901 {
00902 ArLog::log(ArLog::Verbose, "%sUnknown '%s %s' in section '%s', saving it",
00903 myLogPrefix.c_str(), arg->getArg(0), arg->getArg(1), mySection.c_str());
00904 addParam(ArConfigArg(arg->getArg(0), arg->getArg(1)),
00905 mySection.c_str());
00906 }
00907 }
00908 else
00909 {
00910 ArLog::log(ArLog::Verbose, "%sUnknown '%s' in section '%s', ignoring it",
00911 myLogPrefix.c_str(), arg->getFullString(), mySection.c_str());
00912 }
00913 return true;
00914 }
00932 AREXPORT bool ArConfig::parseFile(const char *fileName,
00933 bool continueOnErrors,
00934 bool noFileNotFoundMessage,
00935 char *errorBuffer,
00936 size_t errorBufferLen,
00937 std::list<std::string> *sectionsToParse)
00938 {
00939 bool ret = true;
00940
00941 if(fileName)
00942 myFileName = fileName;
00943 else
00944 myFileName = "";
00945
00946 if (errorBuffer != NULL)
00947 errorBuffer[0] = '\0';
00948
00949 delete mySectionsToParse;
00950 mySectionsToParse = NULL;
00951
00952 copySectionsToParse(sectionsToParse);
00953
00954
00955 ret = myParser.parseFile(fileName, continueOnErrors, noFileNotFoundMessage);
00956
00957
00958 if (errorBuffer != NULL && errorBuffer[0] != '\0')
00959 {
00960 errorBuffer = NULL;
00961 errorBufferLen = 0;
00962 }
00963
00964
00965
00966
00967 if (myArgumentParser != NULL && (ret || continueOnErrors))
00968 ret = parseArgumentParser(myArgumentParser, continueOnErrors,
00969 errorBuffer, errorBufferLen) && ret;
00970
00971
00972 if (errorBuffer != NULL && errorBuffer[0] != '\0')
00973 {
00974 errorBuffer = NULL;
00975 errorBufferLen = 0;
00976 }
00977
00978
00979
00980
00981 if (ret || continueOnErrors)
00982 ret = callProcessFileCallBacks(continueOnErrors, errorBuffer,
00983 errorBufferLen) && ret;
00984
00985
00986 if (errorBuffer != NULL && errorBuffer[0] != '\0')
00987 {
00988 errorBuffer = NULL;
00989 errorBufferLen = 0;
00990 }
00991
00992
00993 delete mySectionsToParse;
00994 mySectionsToParse = NULL;
00995
00996
00997 return ret;
00998 }
00999
01015 AREXPORT bool ArConfig::writeFile(const char *fileName,
01016 bool append,
01017 std::set<std::string> *alreadyWritten,
01018 bool writePriorities,
01019 std::list<std::string> *sectionsToWrite)
01020 {
01021 FILE *file;
01022
01023 std::set<std::string> writtenSet;
01024 std::set<std::string> *written;
01025 if (alreadyWritten != NULL)
01026 written = alreadyWritten;
01027 else
01028 written = &writtenSet;
01029
01030
01031
01032 std::string realFileName;
01033 if (fileName[0] == '/' || fileName[0] == '\\')
01034 {
01035 realFileName = fileName;
01036 }
01037 else
01038 {
01039 realFileName = myBaseDirectory;
01040 realFileName += fileName;
01041 }
01042
01043 std::string mode;
01044
01045 if (append)
01046 mode = "a";
01047 else
01048 mode = "w";
01049
01050 if ((file = fopen(realFileName.c_str(), mode.c_str())) == NULL)
01051 {
01052 ArLog::log(ArLog::Terse, "%sCannot open file '%s' for writing",
01053 myLogPrefix.c_str(), realFileName.c_str());
01054 return false;
01055 }
01056
01057 bool firstSection = true;
01058 std::list<ArConfigSection *>::iterator sectionIt;
01059 ArConfigSection *section = NULL;
01060
01061
01062
01063 if ( ((section = findSection("")) != NULL) &&
01064 (sectionsToWrite == NULL) )
01065 {
01066 if (!firstSection)
01067 fprintf(file, "\n");
01068 firstSection = false;
01069 writeSection(section, file, written, writePriorities);
01070 }
01071
01072
01073 for (sectionIt = mySections.begin();
01074 sectionIt != mySections.end();
01075 sectionIt++)
01076 {
01077 section = (*sectionIt);
01078 if (strcmp(section->getName(), "") == 0)
01079 continue;
01080
01081 if (sectionsToWrite != NULL) {
01082 bool isSectionFound = false;
01083 for (std::list<std::string>::iterator swIter = sectionsToWrite->begin();
01084 swIter != sectionsToWrite->end();
01085 swIter++) {
01086 std::string sp = *swIter;
01087 if (ArUtil::strcasecmp(section->getName(), sp.c_str()) == 0) {
01088 isSectionFound = true;
01089 break;
01090 }
01091 }
01092
01093 if (!isSectionFound) {
01094 continue;
01095 }
01096
01097 }
01098
01099 if (!firstSection)
01100 fprintf(file, "\n");
01101 firstSection = false;
01102
01103 writeSection(section, file, written, writePriorities);
01104 }
01105 fclose(file);
01106 return true;
01107 }
01108
01109 AREXPORT void ArConfig::writeSection(ArConfigSection *section, FILE *file,
01110 std::set<std::string> *alreadyWritten,
01111 bool writePriorities)
01112 {
01113
01114 char line[1024];
01115
01116 char startLine[128];
01117 bool commented = false;
01118 unsigned int startCommentColumn = 25;
01119
01120 std::list<ArArgumentBuilder *>::const_iterator argIt;
01121 const std::list<ArArgumentBuilder *> *argList = NULL;
01122
01123
01124 std::list<ArConfigArg>::iterator paramIt;
01125 std::list<ArConfigArg> *params = NULL;
01126 ArConfigArg *param = NULL;
01127
01129 alreadyWritten->clear();
01130
01131 if (section->getName() != NULL && strlen(section->getName()) > 0)
01132 {
01133
01134 fprintf(file, "Section %s\n", section->getName());
01135 }
01136 sprintf(line, "; ");
01137 if (section->getComment() != NULL && strlen(section->getComment()) > 0)
01138 {
01139 ArArgumentBuilder descr;
01140 descr.add(section->getComment());
01141 for (unsigned int i = 0; i < descr.getArgc(); i++)
01142 {
01143
01144
01145 if (strlen(line) + strlen(descr.getArg(i)) > 78)
01146 {
01147 fprintf(file, "%s\n", line);
01148 sprintf(line, "; ");
01149 sprintf(line, "%s %s", line, descr.getArg(i));
01150 }
01151
01152 else
01153 {
01154 sprintf(line, "%s %s", line, descr.getArg(i));
01155 }
01156 }
01157
01158 fprintf(file, "%s\n", line);
01159 }
01160
01161 params = section->getParams();
01162
01163 for (paramIt = params->begin(); paramIt != params->end(); paramIt++)
01164 {
01165 commented = false;
01166 param = &(*paramIt);
01167
01168 if (param->getType() == ArConfigArg::SEPARATOR) {
01169 continue;
01170 }
01171
01172 if (alreadyWritten != NULL &&
01173 param->getType() != ArConfigArg::DESCRIPTION_HOLDER &&
01174 alreadyWritten->find(param->getName()) != alreadyWritten->end())
01175 continue;
01176 else if (alreadyWritten != NULL &&
01177 param->getType() != ArConfigArg::DESCRIPTION_HOLDER)
01178 {
01179 alreadyWritten->insert(param->getName());
01180 }
01181
01182
01183
01184 if (param->getType() == ArConfigArg::FUNCTOR)
01185 {
01186
01187 sprintf(line, "; ");
01188 if (param->getDescription() != NULL &&
01189 strlen(param->getDescription()) > 0)
01190 {
01191 ArArgumentBuilder descr;
01192 descr.add(param->getDescription());
01193 for (unsigned int i = 0; i < descr.getArgc(); i++)
01194 {
01195
01196
01197 if (strlen(line) + strlen(descr.getArg(i)) > 78)
01198 {
01199 fprintf(file, "%s\n", line);
01200 sprintf(line, "; ");
01201 sprintf(line, "%s %s", line, descr.getArg(i));
01202 }
01203
01204 else
01205 {
01206 sprintf(line, "%s %s", line, descr.getArg(i));
01207 }
01208 }
01209
01210 fprintf(file, "%s\n", line);
01211 }
01212
01213 argList = param->getArgsWithFunctor();
01214 if (argList != NULL)
01215 for (argIt = argList->begin(); argIt != argList->end(); argIt++)
01216 {
01217
01218 if (strchr(param->getName(), ' ') != NULL ||
01219 strchr(param->getName(), '\t') != NULL)
01220 fprintf(file, "\"%s\" %s\n", param->getName(),
01221 (*argIt)->getFullString());
01222 else
01223 fprintf(file, "%s %s\n", param->getName(),
01224 (*argIt)->getFullString());
01225 }
01226
01227
01228 continue;
01229 }
01230
01231
01232
01233 if (param->getType() == ArConfigArg::STRING_HOLDER)
01234 {
01235 fprintf(file, "%s %s\n", param->getName(), param->getString());
01236
01237 if (!myNoBlanksBetweenParams)
01238 fprintf(file, "\n");
01239 continue;
01240 }
01241
01242
01243 if (strchr(param->getName(), ' ') != NULL ||
01244 strchr(param->getName(), '\t') != NULL)
01245 sprintf(line, "\"%s\"", param->getName());
01246 else
01247 sprintf(line, "%s", param->getName());
01248 if (param->getType() == ArConfigArg::INT)
01249 {
01250 sprintf(line, "%s %d", line, param->getInt());
01251 }
01252 else if (param->getType() == ArConfigArg::DOUBLE)
01253 {
01254 sprintf(line, "%s %g", line, param->getDouble());
01255 }
01256 else if (param->getType() == ArConfigArg::STRING)
01257 {
01258 sprintf(line, "%s %s", line, param->getString());
01259 }
01260 else if (param->getType() == ArConfigArg::BOOL)
01261 {
01262 sprintf(line, "%s %s", line, param->getBool() ? "true" : "false");
01263 }
01264 else if (param->getType() == ArConfigArg::DESCRIPTION_HOLDER)
01265 {
01266 if (strlen(param->getDescription()) == 0)
01267 {
01268 fprintf(file, "\n");
01269 continue;
01270 }
01271 }
01272 else
01273 {
01274 ArLog::log(ArLog::Terse, "%sno argument type", myLogPrefix.c_str());
01275 }
01276
01277 if (param->getType() == ArConfigArg::DESCRIPTION_HOLDER)
01278 sprintf(startLine, "; ");
01279 else
01280 sprintf(startLine, "%%-%ds;", startCommentColumn);
01281
01282
01283 if (strlen(line) >= startCommentColumn)
01284 sprintf(line, "%-s ;", line);
01285
01286 else
01287 sprintf(line, startLine, line);
01288
01289 if (param->getType() == ArConfigArg::INT)
01290 {
01291 if (param->getMinInt() != INT_MIN && param->getMaxInt() != INT_MAX)
01292 {
01293 sprintf(line, "%s range [%d, %d], ", line,
01294 param->getMinInt(), param->getMaxInt());
01295 }
01296 else if (param->getMinInt() != INT_MIN)
01297 sprintf(line, "%s minumum %d, ", line, param->getMinInt());
01298 else if (param->getMaxInt() != INT_MAX)
01299 sprintf(line, "%s maximum %d, ", line, param->getMaxInt());
01300 }
01301 if (param->getType() == ArConfigArg::DOUBLE)
01302 {
01303 if (param->getMinDouble() != -HUGE_VAL &&
01304 param->getMaxDouble() != HUGE_VAL)
01305 sprintf(line, "%s range [%g, %g], ", line, param->getMinDouble(),
01306 param->getMaxDouble());
01307 else if (param->getMinDouble() != -HUGE_VAL)
01308 sprintf(line, "%s minimum %g, ", line,
01309 param->getMinDouble());
01310 else if (param->getMaxDouble() != HUGE_VAL)
01311 sprintf(line, "%s Maximum %g, ", line,
01312 param->getMaxDouble());
01313 }
01314
01315
01316 if (param->getDescription() != NULL &&
01317 strlen(param->getDescription()) > 0)
01318 {
01319 ArArgumentBuilder descr;
01320 descr.add(param->getDescription());
01321 for (unsigned int i = 0; i < descr.getArgc(); i++)
01322 {
01323
01324
01325 if (strlen(line) + strlen(descr.getArg(i)) > 78)
01326 {
01327 fprintf(file, "%s\n", line);
01328 sprintf(line, startLine, "");
01329 sprintf(line, "%s %s", line, descr.getArg(i));
01330 }
01331
01332 else
01333 {
01334 sprintf(line, "%s %s", line, descr.getArg(i));
01335 }
01336 }
01337
01338 fprintf(file, "%s\n", line);
01339 }
01340
01341 else
01342 fprintf(file, "%s\n", line);
01343
01344 if (writePriorities)
01345 {
01346 sprintf(line, startLine, "");
01347 fprintf(file, "%s Priority: %s\n", line,
01348 ArPriority::getPriorityName(param->getConfigPriority()));
01349 }
01350
01351 if (!myNoBlanksBetweenParams)
01352 fprintf(file, "\n");
01353 }
01354 }
01355
01356 AREXPORT const char *ArConfig::getBaseDirectory(void) const
01357 {
01358 return myBaseDirectory.c_str();
01359 }
01360
01361 AREXPORT void ArConfig::setBaseDirectory(const char *baseDirectory)
01362 {
01363 if (baseDirectory != NULL && strlen(baseDirectory) > 0)
01364 myBaseDirectory = baseDirectory;
01365 else
01366 myBaseDirectory = "";
01367
01368 myParser.setBaseDirectory(baseDirectory);
01369 }
01370
01371 AREXPORT const char *ArConfig::getFileName(void) const
01372 {
01373 return myFileName.c_str();
01374 }
01375
01392 AREXPORT void ArConfig::addProcessFileCB(ArRetFunctor<bool> *functor,
01393 int priority)
01394 {
01395 myProcessFileCBList.insert(
01396 std::pair<int, ProcessFileCBType *>(-priority,
01397 new ProcessFileCBType(functor)));
01398 }
01399
01403 AREXPORT void ArConfig::remProcessFileCB(ArRetFunctor<bool> *functor)
01404 {
01405 std::multimap<int, ProcessFileCBType *>::iterator it;
01406 ProcessFileCBType *cb;
01407
01408 for (it = myProcessFileCBList.begin(); it != myProcessFileCBList.end(); ++it)
01409 {
01410 if ((*it).second->haveFunctor(functor))
01411 {
01412 cb = (*it).second;
01413 myProcessFileCBList.erase(it);
01414 delete cb;
01415 remProcessFileCB(functor);
01416 return;
01417 }
01418 }
01419 }
01420
01444 AREXPORT void ArConfig::addProcessFileWithErrorCB(
01445 ArRetFunctor2<bool, char *, size_t> *functor,
01446 int priority)
01447 {
01448 myProcessFileCBList.insert(
01449 std::pair<int, ProcessFileCBType *>(-priority,
01450 new ProcessFileCBType(functor)));
01451 }
01452
01456 AREXPORT void ArConfig::remProcessFileCB(
01457 ArRetFunctor2<bool, char *, size_t> *functor)
01458 {
01459 std::multimap<int, ProcessFileCBType *>::iterator it;
01460 ProcessFileCBType *cb;
01461
01462 for (it = myProcessFileCBList.begin(); it != myProcessFileCBList.end(); ++it)
01463 {
01464 if ((*it).second->haveFunctor(functor))
01465 {
01466 cb = (*it).second;
01467 myProcessFileCBList.erase(it);
01468 delete cb;
01469 remProcessFileCB(functor);
01470 }
01471 }
01472 }
01473
01474 AREXPORT bool ArConfig::callProcessFileCallBacks(bool continueOnErrors,
01475 char *errorBuffer,
01476 size_t errorBufferLen)
01477 {
01478 bool ret = true;
01479 std::multimap<int, ProcessFileCBType *>::iterator it;
01480 ProcessFileCBType *callback;
01481 ArLog::LogLevel level = myProcessFileCallbacksLogLevel;
01482
01483
01484 mySection = "";
01485
01486
01487
01488
01489
01490 if (errorBuffer != NULL && errorBufferLen > 0)
01491 errorBuffer[0] = '\0';
01492
01493 ArLog::log(level, "%sProcessing file", myLogPrefix.c_str());
01494 for (it = myProcessFileCBList.begin();
01495 it != myProcessFileCBList.end();
01496 ++it)
01497 {
01498 callback = (*it).second;
01499 if (callback->getName() != NULL && callback->getName()[0] != '\0')
01500 ArLog::log(level, "%sProcessing functor '%s' (%d)",
01501 myLogPrefix.c_str(),
01502 callback->getName(), -(*it).first);
01503 else
01504 ArLog::log(level, "%sProcessing unnamed functor (%d)",
01505 myLogPrefix.c_str(),
01506 -(*it).first);
01507 if (!(*it).second->call(errorBuffer, errorBufferLen))
01508 {
01509
01510
01511
01512
01513 if (errorBuffer != NULL && errorBuffer[0] != '\0')
01514 {
01515 errorBuffer = NULL;
01516 errorBufferLen = 0;
01517 }
01518 ret = false;
01519 if (!continueOnErrors)
01520 {
01521 if (callback->getName() != NULL && callback->getName()[0] != '\0')
01522 ArLog::log(ArLog::Normal, "ArConfig: Failed, stopping because the '%s' process file callback failed",
01523 callback->getName());
01524 else
01525 ArLog::log(ArLog::Normal, "ArConfig: Failed, stopping because unnamed process file callback failed");
01526 break;
01527 }
01528 else
01529 {
01530 if (callback->getName() != NULL && callback->getName()[0] != '\0')
01531 ArLog::log(ArLog::Normal, "ArConfig: Failed but continuing, the '%s' process file callback failed",
01532 callback->getName());
01533 else
01534 ArLog::log(ArLog::Normal, "ArConfig: Failed but continuing, an unnamed process file callback failed");
01535 }
01536
01537 }
01538 }
01539 if (ret || continueOnErrors)
01540 {
01541 ArLog::log(level, "%sProcessing with own processFile",
01542 myLogPrefix.c_str());
01543 if (!processFile())
01544 ret = false;
01545 }
01546 ArLog::log(level, "%sDone processing file, ret is %s", myLogPrefix.c_str(),
01547 ArUtil::convertBool(ret));
01548
01549 return ret;
01550 }
01551
01552
01553 AREXPORT std::list<ArConfigSection *> *ArConfig::getSections(void)
01554 {
01555 return &mySections;
01556 }
01557
01558 AREXPORT void ArConfig::setNoBlanksBetweenParams(bool noBlanksBetweenParams)
01559 {
01560 myNoBlanksBetweenParams = noBlanksBetweenParams;
01561 }
01562
01563 AREXPORT bool ArConfig::getNoBlanksBetweenParams(void)
01564 {
01565 return myNoBlanksBetweenParams;
01566 }
01567
01573 AREXPORT void ArConfig::useArgumentParser(ArArgumentParser *parser)
01574 {
01575 myArgumentParser = parser;
01576 }
01577
01578 AREXPORT bool ArConfig::parseArgumentParser(ArArgumentParser *parser,
01579 bool continueOnError,
01580 char *errorBuffer,
01581 size_t errorBufferLen)
01582 {
01583 std::list<ArConfigSection *>::iterator sectionIt;
01584 std::list<ArConfigArg>::iterator paramIt;
01585 ArConfigSection *section = NULL;
01586 ArConfigArg *param = NULL;
01587 std::list<ArConfigArg> *params = NULL;
01588
01589 bool ret;
01590 size_t i;
01591 std::string strArg;
01592 std::string strUndashArg;
01593 ArArgumentBuilder builder;
01594 bool plainMatch;
01595
01596 for (i = 0; i < parser->getArgc(); i++)
01597 {
01598 if (parser->getArg(i) == NULL)
01599 {
01600 ArLog::log(ArLog::Terse, "%sset up wrong (parseArgumentParser broken).",
01601 myLogPrefix.c_str());
01602 if (errorBuffer != NULL)
01603 strncpy(errorBuffer,
01604 "ArConfig set up wrong (parseArgumentParser broken).",
01605 errorBufferLen);
01606 return false;
01607 }
01608 strArg = parser->getArg(i);
01609 if (parser->getArg(i)[0] == '-')
01610 strUndashArg += &parser->getArg(i)[1];
01611 else
01612 strUndashArg = "";
01613
01614 for (sectionIt = mySections.begin();
01615 sectionIt != mySections.end();
01616 sectionIt++)
01617 {
01618 section = (*sectionIt);
01619 params = section->getParams();
01620
01621 for (paramIt = params->begin(); paramIt != params->end(); paramIt++)
01622 {
01623 param = &(*paramIt);
01624
01625
01626
01627
01628
01629
01630 if (strlen(param->getName()) > 0 &&
01631 ((plainMatch = ArUtil::strcasecmp(param->getName(),strArg)) == 0 ||
01632 ArUtil::strcasecmp(param->getName(), strUndashArg) == 0))
01633 {
01634 if (plainMatch == 0)
01635 builder.setExtraString(strArg.c_str());
01636 else
01637 builder.setExtraString(strUndashArg.c_str());
01638 if (i+1 < parser->getArgc())
01639 {
01640 builder.add(parser->getArg(i+1));
01641 parser->removeArg(i+1);
01642 }
01643 parser->removeArg(i);
01644
01645
01646 std::string oldSection = mySection;
01647 bool oldSectionBroken = mySectionBroken;
01648 bool oldSectionIgnored = mySectionIgnored;
01649 bool oldUsingSections = myUsingSections;
01650 bool oldDuplicateParams = myDuplicateParams;
01651 mySection = section->getName();
01652 mySectionBroken = false;
01653 mySectionIgnored = false;
01654 myUsingSections = true;
01655 myDuplicateParams = false;
01656 ret = parseArgument(&builder, errorBuffer, errorBufferLen);
01657 mySection = oldSection;
01658 mySectionBroken = oldSectionBroken;
01659 mySectionIgnored = oldSectionIgnored;
01660 myUsingSections = oldUsingSections;
01661 myDuplicateParams = oldDuplicateParams;
01662
01663
01664
01665 if (ret || continueOnError)
01666 {
01667
01668 return ret && parseArgumentParser(parser, continueOnError,
01669 errorBuffer, errorBufferLen);
01670 }
01671 else
01672 return false;
01673 }
01674 }
01675 }
01676 }
01677
01678 return true;
01679 }
01680
01681 AREXPORT ArConfigSection *ArConfig::findSection(const char *sectionName) const
01682 {
01683 ArConfigSection *section = NULL;
01684 ArConfigSection *tempSection = NULL;
01685
01686 for (std::list<ArConfigSection *>::const_iterator sectionIt = mySections.begin();
01687 sectionIt != mySections.end();
01688 sectionIt++)
01689 {
01690 tempSection = (*sectionIt);
01691 if (ArUtil::strcasecmp(tempSection->getName(), sectionName) == 0)
01692 {
01693 section = tempSection;
01694 }
01695 }
01696 return section;
01697
01698 }
01699
01700 void ArConfig::copySectionsToParse(std::list<std::string> *from)
01701 {
01702 mySectionsToParse = NULL;
01703 if (from != NULL) {
01704 mySectionsToParse = new std::list<std::string>();
01705 for (std::list<std::string>::const_iterator spIter = from->begin();
01706 spIter != from->end();
01707 spIter++) {
01708 mySectionsToParse->push_back(*spIter);
01709 }
01710 }
01711
01712 }
01713
01714
01715
01716 AREXPORT void ArConfig::clearAllValueSet(void)
01717 {
01718 std::list<ArConfigSection *> *sections;
01719 ArConfigSection *section;
01720 std::list<ArConfigSection *>::iterator sectionIt;
01721
01722 std::list<ArConfigArg> *params;
01723 ArConfigArg *param;
01724 std::list<ArConfigArg>::iterator paramIt;
01725
01726 sections = getSections();
01727 for (sectionIt = sections->begin();
01728 sectionIt != sections->end();
01729 sectionIt++)
01730 {
01731 section = (*sectionIt);
01732 params = section->getParams();
01733 for (paramIt = params->begin(); paramIt != params->end(); paramIt++)
01734 {
01735 param = &(*paramIt);
01736 param->clearValueSet();
01737 }
01738 }
01739 }
01740
01741 AREXPORT void ArConfig::removeAllUnsetValues(void)
01742 {
01743 std::list<ArConfigSection *> *sections;
01744 ArConfigSection *section;
01745 std::list<ArConfigSection *>::iterator sectionIt;
01746
01747 std::list<ArConfigArg> *params;
01748 ArConfigArg *param;
01749 std::list<ArConfigArg>::iterator paramIt;
01750 std::list<std::list<ArConfigArg>::iterator> removeParams;
01751 std::list<std::list<ArConfigArg>::iterator>::iterator removeParamsIt;
01752
01753 sections = getSections();
01754 for (sectionIt = sections->begin();
01755 sectionIt != sections->end();
01756 sectionIt++)
01757 {
01758 section = (*sectionIt);
01759 params = section->getParams();
01760 for (paramIt = params->begin(); paramIt != params->end(); paramIt++)
01761 {
01762 param = &(*paramIt);
01763 if (!param->isValueSet() &&
01764 param->getType() != ArConfigArg::SEPARATOR &&
01765 param->getType() != ArConfigArg::STRING_HOLDER &&
01766 param->getType() != ArConfigArg:: DESCRIPTION_HOLDER)
01767 {
01768 removeParams.push_back(paramIt);
01769 }
01770 }
01771 while ((removeParamsIt = removeParams.begin()) != removeParams.end())
01772 {
01773 ArLog::log(ArLog::Verbose,
01774 "%s:removeAllUnsetValues: Removing %s:%s",
01775 myLogPrefix.c_str(),
01776 section->getName(), (*(*removeParamsIt)).getName());
01777 section->getParams()->erase((*removeParamsIt));
01778 removeParams.pop_front();
01779 }
01780 }
01781 }
01782
01783
01784 AREXPORT ArConfigSection::ArConfigSection(const char *name,
01785 const char *comment)
01786 {
01787 myName = name;
01788 if (comment != NULL)
01789 myComment = comment;
01790 else
01791 myComment = "";
01792 myFlags = new ArArgumentBuilder(512, '|');
01793 }
01794
01795
01796 AREXPORT ArConfigSection::ArConfigSection(const ArConfigSection §ion)
01797 {
01798 myName = section.myName;
01799 myComment = section.myComment;
01800 myFlags = new ArArgumentBuilder(512, '|');
01801 myFlags->add(section.myFlags->getFullString());
01802
01803 for (std::list<ArConfigArg>::const_iterator it = section.myParams.begin();
01804 it != section.myParams.end();
01805 it++)
01806 {
01807 myParams.push_back(*it);
01808 }
01809 }
01810
01811 AREXPORT ArConfigSection &ArConfigSection::operator=(const ArConfigSection §ion)
01812 {
01813 if (this != §ion)
01814 {
01815
01816 myName = section.getName();
01817 myComment = section.getComment();
01818 delete myFlags;
01819 myFlags = new ArArgumentBuilder(512, '|');
01820 myFlags->add(section.myFlags->getFullString());
01821
01822 for (std::list<ArConfigArg>::const_iterator it = section.myParams.begin();
01823 it != section.myParams.end();
01824 it++)
01825 {
01826 myParams.push_back(*it);
01827 }
01828 }
01829 return *this;
01830 }
01831
01832
01833
01834 AREXPORT ArConfigSection::~ArConfigSection()
01835 {
01836 delete myFlags;
01837 }
01838
01839
01840
01841 AREXPORT ArConfigArg *ArConfigSection::findParam(const char *paramName)
01842 {
01843 ArConfigArg *param = NULL;
01844 ArConfigArg *tempParam = NULL;
01845
01846 for (std::list<ArConfigArg>::iterator pIter = myParams.begin();
01847 pIter != myParams.end();
01848 pIter++)
01849 {
01850
01851 tempParam = &(*pIter);
01852
01853 if (tempParam->getType() == ArConfigArg::STRING_HOLDER)
01854 continue;
01855 if (ArUtil::strcasecmp(tempParam->getName(), paramName) == 0)
01856 {
01857 param = tempParam;
01858 }
01859 }
01860 return param;
01861
01862 }
01863
01864
01865 AREXPORT bool ArConfigSection::remStringHolder(const char *paramName)
01866 {
01867 ArConfigArg *tempParam = NULL;
01868
01869 for (std::list<ArConfigArg>::iterator pIter = myParams.begin();
01870 pIter != myParams.end();
01871 pIter++)
01872 {
01873
01874 tempParam = &(*pIter);
01875
01876 if (tempParam->getType() != ArConfigArg::STRING_HOLDER ||
01877 paramName == NULL || paramName[0] == '\0')
01878 continue;
01879 if (ArUtil::strcasecmp(tempParam->getName(), paramName) == 0)
01880 {
01881 myParams.erase(pIter);
01882 remStringHolder(paramName);
01883 return true;
01884 }
01885 }
01886 return false;
01887 }
01888
01889 AREXPORT bool ArConfigSection::hasFlag(const char *flag) const
01890 {
01891 size_t i;
01892 for (i = 0; i < myFlags->getArgc(); i++)
01893 {
01894 if (strcmp(myFlags->getArg(i), flag) == 0)
01895 {
01896 return true;
01897 }
01898 }
01899 return false;
01900 }
01901
01902 AREXPORT bool ArConfigSection::remFlag(const char *flag)
01903 {
01904 size_t i;
01905 for (i = myFlags->getArgc(); i < myFlags->getArgc(); i++)
01906 {
01907 if (strcmp(myFlags->getArg(i), flag) == 0)
01908 {
01909 myFlags->removeArg(i);
01910 return true;
01911 }
01912 }
01913
01914 return false;
01915 }
01916