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
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00040 #include <Beliefstate.h>
00041
00042
00043 namespace beliefstate {
00044 Beliefstate::Beliefstate(int argc, char** argv) {
00045 m_psPlugins = NULL;
00046 m_bRun = true;
00047 m_argc = argc;
00048 m_argv = argv;
00049 m_strWorkspaceDirectory = "";
00050 m_bTerminalWindowResize = false;
00051 m_bCommandLineOutput = true;
00052 m_strVersion = "0.7 iai";
00053
00054 this->setRedirectOutput(false);
00055
00056 this->setMessagePrefixLabel("core");
00057
00058 m_lstConfigFileLocations.push_back("");
00059 m_lstConfigFileLocations.push_back(this->resolveDirectoryTokens("${HOME}/.beliefstate/"));
00060 }
00061
00062 Beliefstate::~Beliefstate() {
00063 }
00064
00065 std::string Beliefstate::version() {
00066 return m_strVersion;
00067 }
00068
00069 Result Beliefstate::init(std::string strConfigFile) {
00070 Result resInit = defaultResult();
00071
00072
00073 m_psPlugins = new PluginSystem(m_argc, m_argv);
00074
00075 std::list<std::string> lstConfigFiles;
00076 for(std::string strLocation : m_lstConfigFileLocations) {
00077 std::string strLocationCleaned = strLocation;
00078 if(strLocationCleaned[strLocationCleaned.length() - 1] != '/') {
00079 strLocationCleaned += "/";
00080 }
00081
00082 strLocationCleaned += "config.cfg";
00083 lstConfigFiles.push_back(strLocationCleaned);
00084 }
00085
00086 if(strConfigFile != "") {
00087 lstConfigFiles.push_front(strConfigFile);
00088 }
00089
00090 bool bConfigLoaded = false;
00091 for(std::string strConfigFileCurrent : lstConfigFiles) {
00092 if(this->loadConfigFile(strConfigFileCurrent)) {
00093 this->info("Loaded config file '" + strConfigFileCurrent + "'.");
00094 bConfigLoaded = true;
00095
00096 break;
00097 }
00098 }
00099
00100 if(bConfigLoaded) {
00101
00102
00103 this->setRedirectOutput(true);
00104
00105
00106 ConfigSettings cfgsetCurrent = configSettings();
00107 m_psPlugins->setLoadDevelopmentPlugins(cfgsetCurrent.bLoadDevelopmentPlugins);
00108
00109
00110
00111 for(string strPluginName : m_lstPluginsToLoad) {
00112 Result rsResult = m_psPlugins->loadPluginLibrary(strPluginName, true);
00113
00114 if(!rsResult.bSuccess) {
00115 if(cfgsetCurrent.bFailedPluginsInvalidateStartup) {
00116 this->fail("Failed plugin load invalidates startup. Cancelling.");
00117 resInit.bSuccess = false;
00118 break;
00119 }
00120 } else {
00121 if(rsResult.piPlugin) {
00122 rsResult.piPlugin->setOnlyDisplayImportant(m_bOnlyDisplayImportant);
00123 }
00124 }
00125 }
00126 } else {
00127 this->fail("Failed to load a valid config file.");
00128 resInit.bSuccess = false;
00129 }
00130
00131
00132 if(this->workspaceDirectory() == "") {
00133 this->warn("The workspace directory could not be resolved. This might cause problems, especially when trying to load plugins. Please ensure that your environment is set up properly. If everything seems alright, consider to override the workspace-dependent paths in a custom file (i.e. ~/.beliefstate/config.cfg).");
00134 }
00135
00136 if(resInit.bSuccess) {
00137 m_lstGlobalEvents.push_back(defaultEvent("startup-complete"));
00138 }
00139
00140 return resInit;
00141 }
00142
00143 Result Beliefstate::deinit() {
00144 Result resInit = defaultResult();
00145
00146 if(m_psPlugins) {
00147 delete m_psPlugins;
00148 }
00149
00150 return resInit;
00151 }
00152
00153 bool Beliefstate::loadConfigFile(std::string strConfigFile) {
00154 if(this->fileExists(strConfigFile)) {
00155 libconfig::Config cfgConfig;
00156
00157 try {
00158 cfgConfig.readFile(strConfigFile.c_str());
00159
00160
00161
00162
00163
00164 bool bDisplayUnhandledEvents = true;
00165 bool bDisplayUnhandledServiceEvents = true;
00166 m_bOnlyDisplayImportant = false;
00167
00168 if(cfgConfig.exists("miscellaneous")) {
00169 libconfig::Setting &sMiscellaneous = cfgConfig.lookup("miscellaneous");
00170 sMiscellaneous.lookupValue("display-unhandled-events", bDisplayUnhandledEvents);
00171 sMiscellaneous.lookupValue("display-unhandled-service-events", bDisplayUnhandledServiceEvents);
00172 sMiscellaneous.lookupValue("workspace-directory", m_strWorkspaceDirectory);
00173 sMiscellaneous.lookupValue("command-line-output", m_bCommandLineOutput);
00174 sMiscellaneous.lookupValue("only-display-important-messages", m_bOnlyDisplayImportant);
00175
00176 if(!m_bCommandLineOutput) {
00177 this->setRedirectOutput(true);
00178 }
00179 }
00180
00181
00182 std::string strBaseDataDirectory = "";
00183 std::string strMongoDBHost = "";
00184 std::string strMongoDBDatabase = "";
00185 int nMongoDBPort = 27017;
00186 bool bUseMongoDB = false;
00187
00188 if(cfgConfig.exists("persistent-data-storage")) {
00189 libconfig::Setting &sPersistentDataStorage = cfgConfig.lookup("persistent-data-storage");
00190 sPersistentDataStorage.lookupValue("base-data-directory", strBaseDataDirectory);
00191 strBaseDataDirectory = this->resolveDirectoryTokens(strBaseDataDirectory);
00192
00193 sPersistentDataStorage.lookupValue("use-mongodb", bUseMongoDB);
00194
00195 if(bUseMongoDB) {
00196 if(cfgConfig.exists("persistent-data-storage.mongodb")) {
00197 libconfig::Setting &sMongoDB = cfgConfig.lookup("persistent-data-storage.mongodb");
00198 sMongoDB.lookupValue("host", strMongoDBHost);
00199 sMongoDB.lookupValue("port", nMongoDBPort);
00200 sMongoDB.lookupValue("database", strMongoDBDatabase);
00201 }
00202 }
00203 }
00204
00205
00206 std::string strExperimentNameMask = "";
00207 std::string strSymlinkName = "";
00208
00209 if(cfgConfig.exists("experiment-data")) {
00210 libconfig::Setting &sExperimentData = cfgConfig.lookup("experiment-data");
00211 sExperimentData.lookupValue("experiment-name-mask", strExperimentNameMask);
00212 sExperimentData.lookupValue("symlink-name", strSymlinkName);
00213 }
00214
00215
00216
00217 bool bSettingsOK = true;
00218
00219 if((bUseMongoDB == true && (strMongoDBHost == "" ||
00220 strMongoDBDatabase == "" ||
00221 nMongoDBPort == 0))) {
00222 this->fail("Error while loading MongoDB settings:");
00223 if(strMongoDBHost == "") {
00224 this->fail(" - MongoDB Host is empty");
00225 }
00226
00227 if(strMongoDBHost == "") {
00228 this->fail(" - MongoDB Database is empty");
00229 }
00230
00231 if(nMongoDBPort == 0) {
00232 this->fail(" - MongoDB Port is not set or '0' (which is invalid)");
00233 }
00234
00235 bSettingsOK = false;
00236 }
00237
00238 if(bSettingsOK == false) {
00239 return false;
00240 }
00241
00242 if(strSymlinkName == "" || strExperimentNameMask == "" || (strExperimentNameMask.find("%d") == string::npos && strExperimentNameMask.find("%s") == string::npos) || strBaseDataDirectory == "") {
00243 if(strBaseDataDirectory == "") {
00244 this->warn("The base data directory path is empty.");
00245 strBaseDataDirectory = this->resolveDirectoryTokens("${HOME}/bs_experimental_data");
00246 this->warn("Defaulting to: '" + strBaseDataDirectory + "'");
00247 }
00248
00249 if(strSymlinkName == "") {
00250 this->warn("The symlink name for experiments is empty.");
00251 strSymlinkName = "current-experiment";
00252 this->warn("Defaulting to: '" + strSymlinkName + "'");
00253 }
00254
00255 if(strExperimentNameMask == "") {
00256 this->warn("The experiment name mask is empty.");
00257 strExperimentNameMask = "exp-%d";
00258 this->warn("Defaulting to: '" + strExperimentNameMask + "'");
00259 } else if(strExperimentNameMask.find("%d") == string::npos && strExperimentNameMask.find("%s") == string::npos) {
00260 this->warn("The experiment name mask does not include the '\%d' or '\%s' escape sequence.");
00261 this->warn("It is currently: '" + strExperimentNameMask + "'");
00262 this->warn("This will cause your experiments to be overwritten. Be careful.");
00263 }
00264 }
00265
00266
00267 bool bLoadDevelopmentPlugins = false;
00268 bool bFailedPluginsInvalidateStartup = true;
00269 std::vector<std::string> vecPluginOutputColors;
00270 bool bSearchPathsSet = false;
00271
00272 if(cfgConfig.exists("plugins")) {
00273 libconfig::Setting &sPlugins = cfgConfig.lookup("plugins");
00274 sPlugins.lookupValue("load-development-plugins", bLoadDevelopmentPlugins);
00275 sPlugins.lookupValue("failed-plugins-invalidate-startup", bFailedPluginsInvalidateStartup);
00276
00277 if(cfgConfig.exists("plugins.load")) {
00278 libconfig::Setting &sPluginsLoad = cfgConfig.lookup("plugins.load");
00279 m_lstPluginsToLoad.clear();
00280
00281 for(int nI = 0; nI < sPluginsLoad.getLength(); nI++) {
00282 std::string strLoad = sPluginsLoad[nI];
00283
00284 m_lstPluginsToLoad.remove(strLoad);
00285 m_lstPluginsToLoad.push_back(strLoad);
00286 }
00287 }
00288
00289 if(cfgConfig.exists("plugins.search-paths")) {
00290 libconfig::Setting &sPluginsPaths = cfgConfig.lookup("plugins.search-paths");
00291
00292 for(int nI = 0; nI < sPluginsPaths.getLength(); nI++) {
00293 std::string strPath = sPluginsPaths[nI];
00294
00295 strPath = this->resolveDirectoryTokens(strPath);
00296 m_psPlugins->addPluginSearchPath(strPath);
00297
00298 bSearchPathsSet = true;
00299 }
00300 }
00301
00302 if(cfgConfig.exists("plugins.colors")) {
00303 libconfig::Setting &sPluginsColors = cfgConfig.lookup("plugins.colors");
00304
00305 for(int nI = 0; nI < sPluginsColors.getLength(); nI++) {
00306 std::string strColor = sPluginsColors[nI];
00307 vecPluginOutputColors.push_back(strColor);
00308 }
00309 }
00310
00311 if(cfgConfig.exists("plugins.individual-configurations")) {
00312 libconfig::Setting &sPluginsIndividualConfigurations = cfgConfig.lookup("plugins.individual-configurations");
00313
00314 for(int nI = 0; nI < sPluginsIndividualConfigurations.getLength(); nI++) {
00315 std::string strPluginName;
00316
00317 if(sPluginsIndividualConfigurations[nI].lookupValue("plugin", strPluginName)) {
00318 this->info("Loading per-plugin configuration for plugin '" + strPluginName + "'");
00319 CDesignator* cdConfig = getPluginConfig(strPluginName);
00320
00321 if(this->loadIndividualPluginConfigurationBranch(sPluginsIndividualConfigurations[nI], cdConfig, "", true) == false) {
00322 this->warn("Failed to load configuration for plugin '" + strPluginName + "'.");
00323 }
00324 } else {
00325 this->warn("No 'plugin'-field specified for individual plugin configuration.");
00326 }
00327 }
00328 }
00329 }
00330
00331
00332 if(bSearchPathsSet == false) {
00333 this->warn("You didn't specify any search paths. This will prevent the system");
00334 this->warn("from finding any plugins. A default will be assumed.");
00335 std::string strSP = this->resolveDirectoryTokens("$WORKSPACE/lib/");
00336 this->warn("Defaulting to: '" + strSP + "'");
00337
00338 m_psPlugins->addPluginSearchPath(strSP);
00339 }
00340
00341 if(vecPluginOutputColors.size() == 0) {
00342 this->warn("The plugin output colors are empty. This might cause display issues.");
00343
00344 vecPluginOutputColors.push_back("31");
00345 vecPluginOutputColors.push_back("32");
00346 vecPluginOutputColors.push_back("33");
00347 vecPluginOutputColors.push_back("34");
00348 vecPluginOutputColors.push_back("35");
00349 vecPluginOutputColors.push_back("36");
00350 vecPluginOutputColors.push_back("37");
00351
00352 std::string strColors = "";
00353 for(string strC : vecPluginOutputColors) {
00354 strColors += (strColors != "" ? ", " : "") + string("\033[0;") + strC + "m" + strC + "\033[0m";
00355 }
00356
00357 this->warn("Defaulting to: " + strColors);
00358 }
00359
00360
00361 ConfigSettings cfgsetCurrent = configSettings();
00362 cfgsetCurrent.bLoadDevelopmentPlugins = bLoadDevelopmentPlugins;
00363 cfgsetCurrent.bFailedPluginsInvalidateStartup = bFailedPluginsInvalidateStartup;
00364 cfgsetCurrent.bUseMongoDB = bUseMongoDB;
00365 cfgsetCurrent.strMongoDBHost = strMongoDBHost;
00366 cfgsetCurrent.nMongoDBPort = nMongoDBPort;
00367 cfgsetCurrent.strMongoDBDatabase = strMongoDBDatabase;
00368 cfgsetCurrent.strExperimentNameMask = strExperimentNameMask;
00369 cfgsetCurrent.strBaseDataDirectory = strBaseDataDirectory;
00370 cfgsetCurrent.strSymlinkName = strSymlinkName;
00371 cfgsetCurrent.bDisplayUnhandledEvents = bDisplayUnhandledEvents;
00372 cfgsetCurrent.bDisplayUnhandledServiceEvents = bDisplayUnhandledServiceEvents;
00373 cfgsetCurrent.vecPluginOutputColors = vecPluginOutputColors;
00374 cfgsetCurrent.bOnlyDisplayImportant = m_bOnlyDisplayImportant;
00375 setConfigSettings(cfgsetCurrent);
00376
00377 return true;
00378 } catch(libconfig::ParseException e) {
00379 std::stringstream sts;
00380 sts << e.getLine();
00381
00382 this->fail("Error while parsing config file '" + strConfigFile + "': " + e.getError() + ", on line " + sts.str());
00383 } catch(...) {
00384 this->fail("Undefined error while parsing config file '" + strConfigFile + "'");
00385 }
00386 }
00387
00388 return false;
00389 }
00390
00391 bool Beliefstate::loadIndividualPluginConfigurationBranch(libconfig::Setting &sBranch, CKeyValuePair* ckvpInto, std::string strConfigPath, bool bIgnorePluginField) {
00392 for(int nJ = 0; nJ < sBranch.getLength(); nJ++) {
00393 if(sBranch.getType() != libconfig::Setting::TypeGroup) {
00394 for(int nI = 0; nI < sBranch.getLength(); nI++) {
00395 std::stringstream sts;
00396 sts << nI;
00397
00398 this->info(" - " + strConfigPath + (strConfigPath == "" ? "" : "/") + sts.str());
00399 CKeyValuePair* ckvpChild = ckvpInto->addChild(sts.str());
00400
00401 switch(sBranch[nI].getType()) {
00402 case libconfig::Setting::TypeString: {
00403 std::string strContent = sBranch[nI];
00404 strContent = this->resolveDirectoryTokens(strContent);
00405 ckvpInto->setValue(sts.str(), strContent);
00406 } break;
00407
00408 case libconfig::Setting::TypeInt:
00409 case libconfig::Setting::TypeInt64: {
00410 int nContent = sBranch[nI];
00411 ckvpInto->setValue(sts.str(), nContent);
00412 } break;
00413
00414 case libconfig::Setting::TypeFloat: {
00415 int fContent = sBranch[nI];
00416 ckvpInto->setValue(sts.str(), fContent);
00417 } break;
00418
00419 case libconfig::Setting::TypeBoolean: {
00420 bool bContent = sBranch[nI];
00421 ckvpInto->setValue(sts.str(), bContent);
00422 } break;
00423 }
00424 }
00425 } else {
00426 std::string strConfigDetailName = sBranch[nJ].getName();
00427
00428 if(strConfigDetailName != "plugin" || !bIgnorePluginField) {
00429 this->info(" - " + strConfigPath + (strConfigPath == "" ? "" : "/") + strConfigDetailName);
00430
00431 switch(sBranch[strConfigDetailName].getType()) {
00432 case libconfig::Setting::TypeString: {
00433 std::string strContent;
00434 sBranch.lookupValue(strConfigDetailName, strContent);
00435 strContent = this->resolveDirectoryTokens(strContent);
00436 ckvpInto->setValue(strConfigDetailName, strContent);
00437 } break;
00438
00439 case libconfig::Setting::TypeInt:
00440 case libconfig::Setting::TypeInt64: {
00441 int nContent;
00442 sBranch.lookupValue(strConfigDetailName, nContent);
00443 ckvpInto->setValue(strConfigDetailName, nContent);
00444 } break;
00445
00446 case libconfig::Setting::TypeFloat: {
00447 int fContent;
00448 sBranch.lookupValue(strConfigDetailName, fContent);
00449 ckvpInto->setValue(strConfigDetailName, fContent);
00450 } break;
00451
00452 case libconfig::Setting::TypeBoolean: {
00453 bool bContent;
00454 sBranch.lookupValue(strConfigDetailName, bContent);
00455 ckvpInto->setValue(strConfigDetailName, bContent);
00456 } break;
00457
00458 case libconfig::Setting::TypeGroup: {
00459 CKeyValuePair* ckvpChild = ckvpInto->addChild(strConfigDetailName);
00460 libconfig::Setting& sBranchChild = sBranch[strConfigDetailName];
00461
00462 if(this->loadIndividualPluginConfigurationBranch(sBranchChild, ckvpChild, strConfigPath + (strConfigPath == "" ? "" : "/") + strConfigDetailName) == false) {
00463 return false;
00464 }
00465 } break;
00466
00467 case libconfig::Setting::TypeArray: {
00468 CKeyValuePair* ckvpChild = ckvpInto->addChild(strConfigDetailName);
00469 libconfig::Setting& sBranchChild = sBranch[strConfigDetailName];
00470
00471 if(this->loadIndividualPluginConfigurationBranch(sBranchChild, ckvpChild, strConfigPath + (strConfigPath == "" ? "" : "/") + strConfigDetailName) == false) {
00472 return false;
00473 }
00474 } break;
00475 }
00476 }
00477 }
00478 }
00479
00480 return true;
00481 }
00482
00483 bool Beliefstate::spreadEvent(Event evEvent) {
00484 if(m_psPlugins->spreadEvent(evEvent) == 0) {
00485 ConfigSettings cfgSet = configSettings();
00486 if(cfgSet.bDisplayUnhandledEvents) {
00487 this->warn("Unhandled event dropped: '" + evEvent.strEventName + "'");
00488
00489 if(evEvent.cdDesignator) {
00490
00491
00492 }
00493 }
00494
00495 if(!this->handleUnhandledEvent(evEvent)) {
00496 if(!evEvent.bPreempt) {
00497
00498 }
00499 }
00500
00501 return false;
00502 }
00503
00504 return true;
00505 }
00506
00507 void Beliefstate::spreadServiceEvent(ServiceEvent seServiceEvent) {
00508 if(m_psPlugins->spreadServiceEvent(seServiceEvent) == 0) {
00509
00510
00511 ConfigSettings cfgSet = configSettings();
00512
00513 if(cfgSet.bDisplayUnhandledServiceEvents) {
00514 this->warn("Unhandled service event ('" + seServiceEvent.strServiceName + "') dropped.");
00515
00516 if(seServiceEvent.cdDesignator) {
00517
00518
00519 }
00520 }
00521
00522
00523
00524
00525
00526
00527
00528 }
00529 }
00530
00531 bool Beliefstate::cycle() {
00532 bool bContinue = true;
00533
00534 if(m_bRun) {
00535 Result resCycle = m_psPlugins->cycle();
00536
00537
00538
00539 std::list<StatusMessage> lstCoreMessages = queuedMessages();
00540 for(StatusMessage smCurrent : lstCoreMessages) {
00541 resCycle.lstStatusMessages.push_back(smCurrent);
00542 }
00543
00544 for(StatusMessage smCurrent : resCycle.lstStatusMessages) {
00545 Event evEvent = defaultEvent("status-message");
00546 evEvent.msgStatusMessage = smCurrent;
00547 evEvent.bPreempt = false;
00548
00549 if(this->spreadEvent(evEvent)) {
00550 this->setRedirectOutput(true);
00551 }
00552 }
00553
00554 for(Event evtCurrent : m_lstGlobalEvents) {
00555 resCycle.lstEvents.push_back(evtCurrent);
00556 }
00557
00558 if(m_lstGlobalEvents.size() > 0) {
00559 m_lstGlobalEvents.clear();
00560 }
00561
00562 if(resCycle.bSuccess) {
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577 while(resCycle.lstEvents.size() > 0 || resCycle.lstServiceEvents.size() > 0) {
00578
00579
00580 int nSequenceNumber = 100000;
00581
00582
00583
00584
00585
00586 for(Event evEvent : resCycle.lstEvents) {
00587 if(evEvent.nSequenceNumber < nSequenceNumber) {
00588 nSequenceNumber = evEvent.nSequenceNumber;
00589 }
00590 }
00591
00592
00593 for(ServiceEvent seEvent : resCycle.lstServiceEvents) {
00594 if(seEvent.nSequenceNumber < nSequenceNumber) {
00595 nSequenceNumber = seEvent.nSequenceNumber;
00596 }
00597 }
00598
00599
00600 bool bWasSpread = false;
00601
00602 for(list<Event>::iterator itEvent = resCycle.lstEvents.begin();
00603 itEvent != resCycle.lstEvents.end(); itEvent++) {
00604 Event evEvent = *itEvent;
00605
00606 if(evEvent.nSequenceNumber == nSequenceNumber) {
00607
00608 this->spreadEvent(evEvent);
00609
00610
00611 if(evEvent.cdDesignator) {
00612 delete evEvent.cdDesignator;
00613 }
00614
00615 resCycle.lstEvents.erase(itEvent);
00616
00617 nSequenceNumber = evEvent.nSequenceNumber;
00618 bWasSpread = true;
00619
00620 break;
00621 }
00622 }
00623
00624 if(!bWasSpread) {
00625 for(list<ServiceEvent>::iterator itEvent = resCycle.lstServiceEvents.begin();
00626 itEvent != resCycle.lstServiceEvents.end(); itEvent++) {
00627 ServiceEvent seEvent = *itEvent;
00628
00629 if(seEvent.nSequenceNumber == nSequenceNumber) {
00630
00631 this->spreadServiceEvent(seEvent);
00632
00633
00634 if(seEvent.cdDesignator) {
00635 if(!seEvent.bPreserve) {
00636 delete seEvent.cdDesignator;
00637 }
00638 }
00639
00640 resCycle.lstServiceEvents.erase(itEvent);
00641
00642 nSequenceNumber = seEvent.nSequenceNumber;
00643 bWasSpread = true;
00644
00645 break;
00646 }
00647 }
00648 }
00649
00650 if(!bWasSpread) {
00651
00652
00653
00654 this->fail("Sequence number hazard! Restart and possibly recompile.");
00655 }
00656 }
00657
00658 resetSequenceNumbers();
00659
00660
00661 m_mtxTerminalResize.lock();
00662 bool bTerminalWindowResize = m_bTerminalWindowResize;
00663 m_bTerminalWindowResize = false;
00664 m_mtxTerminalResize.unlock();
00665
00666 if(bTerminalWindowResize) {
00667 Event evResize = defaultEvent("resize-terminal-window");
00668 this->spreadEvent(evResize);
00669 }
00670 }
00671 } else {
00672 bContinue = false;
00673
00674
00675 std::list<StatusMessage> lstCoreMessages = queuedMessages();
00676 for(StatusMessage smCurrent : lstCoreMessages) {
00677 Event evMessage = defaultEvent("status-message");
00678 evMessage.msgStatusMessage = smCurrent;
00679
00680 this->handleUnhandledEvent(evMessage);
00681 }
00682
00683
00684 m_lstGlobalEvents.push_back(defaultEvent("shutdown"));
00685 }
00686
00687 return bContinue;
00688 }
00689
00690 void Beliefstate::triggerShutdown() {
00691 m_bRun = false;
00692 }
00693
00694 void Beliefstate::triggerTerminalResize() {
00695 m_mtxTerminalResize.lock();
00696 m_bTerminalWindowResize = true;
00697 m_mtxTerminalResize.unlock();
00698 }
00699
00700 void Beliefstate::setBaseDataDirectory(std::string strBaseDataDirectory) {
00701 ConfigSettings cfgsetCurrent = configSettings();
00702 cfgsetCurrent.strBaseDataDirectory = strBaseDataDirectory;
00703 setConfigSettings(cfgsetCurrent);
00704 }
00705
00706 std::string Beliefstate::baseDataDirectory() {
00707 ConfigSettings cfgsetCurrent = configSettings();
00708 return cfgsetCurrent.strBaseDataDirectory;
00709 }
00710
00711 std::string Beliefstate::workspaceDirectory() {
00712 return m_strWorkspaceDirectory;
00713 }
00714
00715 std::string Beliefstate::homeDirectory() {
00716 std::string strHome = "";
00717
00718 char* cHome = getenv("HOME");
00719 if(cHome) {
00720 strHome = cHome;
00721 }
00722
00723 return strHome;
00724 }
00725
00726 std::string Beliefstate::resolveDirectoryTokens(std::string strSubject) {
00727
00728 std::list< std::pair<std::string, bool> > lstTokens;
00729
00730 size_t pos = 0;
00731 while((pos = strSubject.find("$", pos)) != string::npos) {
00732 size_t offset = 1;
00733
00734 if(pos < strSubject.size() - 1) {
00735 if(strSubject.at(pos + 1) != ' ') {
00736 std::string strToken = "";
00737 bool bInBrackets = false;
00738
00739 if(strSubject.at(pos + 1) == '{') {
00740 offset++;
00741 size_t pos_endbracket = strSubject.find("}", pos + 1);
00742
00743 if(pos_endbracket != string::npos) {
00744 strToken = strSubject.substr(pos + 2, pos_endbracket - (pos + 2));
00745 offset += 1 + pos_endbracket - (pos + 2);
00746 bInBrackets = true;
00747 } else {
00748
00749 }
00750 } else {
00751 size_t pos_space_or_end = strSubject.find_first_of(" /.~_-\\$", pos + 1);
00752 if(pos_space_or_end == string::npos) {
00753
00754 strToken = strSubject.substr(pos + 1);
00755 offset += pos + 1;
00756 } else {
00757
00758 strToken = strSubject.substr(pos + 1, pos_space_or_end - (pos + 1));
00759 offset += pos_space_or_end - (pos + 1);
00760 }
00761 }
00762
00763 if(strToken != "") {
00764 lstTokens.push_back(make_pair(strToken, bInBrackets));
00765 }
00766 }
00767 }
00768
00769 pos += offset;
00770 }
00771
00772 for(pair<string, bool> prToken : lstTokens) {
00773 std::string strToken = prToken.first;
00774 bool bInBrackets = prToken.second;
00775 std::string strToReplace = (bInBrackets ? "${" + strToken + "}" : "$" + strToken);
00776 std::string strReplacement = this->findTokenReplacement(strToken);
00777
00778 if(strReplacement == "") {
00779 this->warn("Failed to resolve directory token '" + strToken + "', asserting value \"\".");
00780 }
00781
00782 this->replaceStringInPlace(strSubject, strToReplace, strReplacement);
00783 }
00784
00785 return strSubject;
00786 }
00787
00788 std::string Beliefstate::findTokenReplacement(std::string strToken) {
00789 std::string strReplacement = "";
00790
00791 if(strToken == "HOME") {
00792 strReplacement = this->homeDirectory();
00793 }
00794
00795 return strReplacement;
00796 }
00797
00798 bool Beliefstate::handleUnhandledEvent(Event evEvent) {
00799 if(evEvent.strEventName == "status-message") {
00800 StatusMessage msgStatus = evEvent.msgStatusMessage;
00801
00802 if(m_bCommandLineOutput) {
00803 this->setRedirectOutput(false);
00804 } else {
00805 this->setRedirectOutput(true);
00806 }
00807
00808 return true;
00809 }
00810
00811 return false;
00812 }
00813
00814 std::string Beliefstate::findPrefixPath(std::string strPathList, std::string strMatchingSuffix, std::string strDelimiter) {
00815 std::string strPathReturn = "";
00816 size_t szLastPos = 0;
00817 size_t szCurrentPos = 0;
00818
00819 if(strPathList != "") {
00820 while(szLastPos != string::npos) {
00821 szCurrentPos = strPathList.find(strDelimiter, szLastPos + strDelimiter.length());
00822
00823 if(szCurrentPos != string::npos) {
00824 std::string strPath = strPathList.substr(szLastPos + (szLastPos != 0 ? strDelimiter.length() : 0), szCurrentPos - (szLastPos + (szLastPos == 0 ? 0 : strDelimiter.length())));
00825
00826 if(strPath.length() >= strMatchingSuffix.length()) {
00827 if(strPath.substr(strPath.length() - strMatchingSuffix.length()) == strMatchingSuffix) {
00828 strPathReturn = this->stripPostfix(strPath, strMatchingSuffix);
00829 break;
00830 }
00831 }
00832 }
00833
00834 szLastPos = szCurrentPos;
00835 }
00836 }
00837
00838 return strPathReturn;
00839 }
00840 }