File NPOptionManager.cxx
File List > core > NPOptionManager.cxx
Go to the documentation of this file
#include "NPOptionManager.h"
#include "NPException.h"
#include "NPFunction.h"
#include "NPInputParser.h"
#include "NPTerminalColor.h"
#include <cstdlib>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <sstream>
#include <vector>
namespace fs = std::filesystem;
using namespace nptool;
void OptionManager::ReadProjectConfigFile(std::string app_name) {
m_app_name = app_name;
if (app_name == "nptool")
return;
// find where is the project base directory
bool found_project_base = false;
fs::path root = ("/");
fs::path project_base = fs::current_path();
fs::path project_yaml("project.yaml");
fs::path project_install("install");
while (!(fs::exists(project_base / project_yaml) && fs::exists(project_base / project_yaml))) {
project_base = project_base.parent_path();
if (project_base == root) {
break;
}
}
if (project_base == root) {
nptool::message("yellow", "core", "OptionManager::ReadProjectConfigFile", "No project base directory found");
return;
}
nptool::message("green", "core", "OptionManager::ReadProjectConfigFile",
"Found project base directory: " + project_base.string());
// check if the file exist
std::string project_file = (project_base / project_yaml).string();
std::ifstream ProjectFile;
ProjectFile.open(project_file);
if (ProjectFile.is_open()) {
std::cout << "///// Loading Project Configuration: " << std::endl;
ProjectFile.close();
nptool::InputParser parser(project_file);
std::vector<BlockPtr> blocks = parser.GetAllBlocksWithToken("project");
unsigned int size = blocks.size();
for (unsigned int i = 0; i < size; i++) {
if (blocks[i]->HasToken("default flag")) {
ReadArgument(blocks[i]->GetString("default flag"));
}
if (app_name == "npconversion") {
if (blocks[i]->HasToken("conversion output")) {
m_ConversionOutputPath = blocks[i]->GetString("conversion output");
if (m_ConversionOutputPath.back() != '/')
m_ConversionOutputPath += "/";
}
if (blocks[i]->HasToken("default convertion flag")) {
ReadArgument(blocks[i]->GetString("default simulation flag"));
}
}
else if (app_name == "npanalysis") {
if (blocks[i]->HasToken("analysis output")) {
m_AnalysisOutputPath = blocks[i]->GetString("analysis output");
if (m_AnalysisOutputPath.back() != '/')
m_AnalysisOutputPath += "/";
}
if (blocks[i]->HasToken("default analysis flag")) {
ReadArgument(blocks[i]->GetString("default analysis flag"));
}
}
else if (app_name == "npsimulation") {
if (blocks[i]->HasToken("default simulation flag"))
ReadArgument(blocks[i]->GetString("default simulation flag"));
if (blocks[i]->HasToken("simulation output")) {
m_SimulationOutputPath = blocks[i]->GetString("simulation output");
if (m_SimulationOutputPath.back() != '/')
m_SimulationOutputPath += "/";
}
if (blocks[i]->HasToken("energy loss")) {
m_EnergyLossPath = blocks[i]->GetString("energy loss");
if (m_EnergyLossPath.back() != '/')
m_EnergyLossPath += "/";
}
}
else if (app_name == "nponline") {
if (blocks[i]->HasToken("default online flag")) {
ReadArgument(blocks[i]->GetString("default online flag"));
}
else if (blocks[i]->HasToken("online macro")) {
m_OnlineMacroPath = blocks[i]->GetString("online macro");
}
}
else {
if (blocks[i]->HasToken("default output")) {
m_DefaultOutputPath = blocks[i]->GetString("default output");
if (m_DefaultOutputPath.back() != '/')
m_DefaultOutputPath += "/";
}
}
}
}
}
void OptionManager::ReadArgument(int argc, char** argv) {
m_argc = argc;
m_argv = argv;
for (int i = 1; i < argc; i++) {
// argument start with a "-"
if (strncmp(argv[i], "-", 1) == 0) {
if (i == argc - 1) { // last element of argv
m_option[argv[i]] = "_void_";
m_used[argv[i]] = 0;
}
else if (strncmp(argv[i + 1], "-", 1) == 0) { // next argv element is a flag
m_option[argv[i]] = "_void_";
m_used[argv[i]] = 0;
}
else { // next argv element is an arg
m_option[argv[i]] = argv[i + 1];
m_used[argv[i]] = 0;
}
}
}
}
OptionManager::OptionManager(int argc, char** argv) {
// Start by reading the project configuration
ReadArgument(argc, argv);
}
OptionManager::OptionManager(std::string arg) { ReadArgument(arg); }
void OptionManager::ReadArgument(std::string arg) {
// add dummy string in front of arg string
arg.insert(0, "ignore ");
std::vector<char*> args;
std::stringstream iss(arg);
std::string token;
while (iss >> token) {
char* argument = new char[token.size() + 1];
copy(token.begin(), token.end(), argument);
argument[token.size()] = '\0';
args.push_back(argument);
}
args.push_back(0);
ReadArgument(args.size() - 1, &args[0]);
}
void OptionManager::DisplayHelp() {
// exit current program
exit(0);
}
bool nptool::OptionManager::HasFlag(std::string flag) {
auto it = m_option.find(flag);
if (it != m_option.end()) {
m_used[it->first] = 1;
return true;
}
else
return false;
}
std::string nptool::OptionManager::GetArg(std::string flag) {
auto it = m_option.find(flag);
if (it != m_option.end()) {
if (strcmp(it->second.c_str(), "_void_")) {
m_used[it->first] = 1;
return it->second;
}
else {
std::string msg = "Flag \"" + flag + "\" was provided with no <arg> ";
throw(nptool::Error("OptionManager", msg));
}
}
else {
std::string msg = "Requesting unvailable flag \"" + flag + "\"";
throw(nptool::Error("OptionManager", msg));
}
}
std::vector<std::string> nptool::OptionManager::GetVectorArg(std::string flag) {
auto it = m_option.find(flag);
std::vector<std::string> res;
if (it != m_option.end()) {
m_used[it->first] = 1;
while (auto pos = it->second.find_first_of(",")) {
// get the element
std::string element = it->second.substr(0, pos);
if (strcmp(element.c_str(), "_void_") == 0) {
std::string msg = "Flag " + flag + " was provided with no <arg> ";
throw(nptool::Error("OptionManager", msg));
}
// remove the element and "," separator
it->second.erase(0, pos + 1);
res.push_back(element);
if (it->second.empty() || pos == std::string::npos)
break;
}
}
else {
std::string msg = "Requesting unvailable flag " + flag;
throw(nptool::Error("OptionManager", msg));
}
return res;
}
int nptool::OptionManager::GetIntArg(std::string flag) { return atoi(GetArg(flag).c_str()); }
std::vector<std::string> nptool::OptionManager::ListIgnoredFlag() {
std::vector<std::string> res;
for (auto it = m_used.begin(); it != m_used.end(); it++) {
if (it->second == 0)
res.push_back(it->first);
}
return res;
}
unsigned int nptool::OptionManager::NumberOfFlags() { return m_option.size(); }
void nptool::OptionManager::PrintIgnoredFlag() {
std::vector<std::string> ignored = ListIgnoredFlag();
std::string msg = "list of ignored flag: ";
unsigned int size = ignored.size();
if (size) {
for (unsigned int i = 0; i < size; i++) {
msg += ignored[i] + " ";
}
}
if (size)
message("yellow", "core", "nptool::OptionManager", msg);
}