Skip to content

Commit

Permalink
Use getopts for parsing commandline arguments (#17)
Browse files Browse the repository at this point in the history
* Read only config file from command line

* Use getopts for parsing variables

This commit adds getopts to handle commandline variables

* Handle empty options with errors
  • Loading branch information
Jaeyoung-Lim authored Oct 13, 2020
1 parent ac3f387 commit 263da94
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 22 deletions.
8 changes: 7 additions & 1 deletion include/configuration_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,23 @@
#include <tinyxml.h>
#include <Eigen/Eigen>

enum class ArgResult {
Success, Help, Error
};

class ConfigurationParser {
public:

ConfigurationParser() = default;
~ConfigurationParser() = default;
bool ParseEnvironmentVariables();
bool ParseConfigFile(const std::string& path);
bool ParseArgV(int argc, char* const argv[]);
ArgResult ParseArgV(int argc, char* const argv[]);
inline bool isHeadless() { return _headless; }
inline std::shared_ptr<TiXmlHandle> XmlHandle() { return _config; }
inline std::string getInitScriptPath() { return _init_script_path; }
inline std::string getModelName() { return _model_name; }
static void PrintHelpMessage(char *argv[]);

private:
TiXmlDocument _doc;
Expand Down
48 changes: 31 additions & 17 deletions src/configuration_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,32 +40,40 @@

#include "configuration_parser.h"

#include <getopt.h>

bool ConfigurationParser::ParseEnvironmentVariables() {
if (const char* headless_char = std::getenv("HEADLESS")) {
_headless = !std::strcmp(headless_char, "1");
}
return true;
}

bool ConfigurationParser::ParseArgV(int argc, char* const argv[]) {
// TODO: Parse HITL Variables
if (argc < 5) {
std::cout << "This is a JSBSim integration for PX4 SITL/HITL simulations" << std::endl;
std::cout << " Usage: " << argv[0] << "<aircraft_path> <aircraft> <config> <scene> <headless>" << std::endl;
std::cout << " <aircraft_path>: Aircraft directory path which the <aircraft> definition is located e.g. "
"`models/Rascal`"
<< std::endl;
std::cout << " <aircraft>: Aircraft file to use inside the <aircraft_path> e.g. Rascal110-JSBSim"
<< std::endl;
std::cout << " <config>: Simulation config file name under the `configs` directory e.g. rascal" << std::endl;
std::cout << " <scene>: Location / scene where the vehicle should be spawned in e.g. LSZH" << std::endl;
return false;
}
ArgResult ConfigurationParser::ParseArgV(int argc, char* const argv[]) {
static const struct option options[] = {
{"scene", required_argument, nullptr, 's'},
};

// TODO: Switch to getopt
_init_script_path = std::string(argv[4]);
int c;
while ((c = getopt_long(argc, argv, "s:h", options, nullptr)) >= 0) {
switch (c) {
case 'h': {
return ArgResult::Help;
break;
}
case 's': {
_init_script_path = std::string(optarg);
break;
}
case '?':
default: {
std::cout << "Unknown Options" << std::endl;
return ArgResult::Error;
}
}
}

return true;
return ArgResult::Success;
}

bool ConfigurationParser::ParseConfigFile(const std::string& path) {
Expand All @@ -87,3 +95,9 @@ bool ConfigurationParser::ParseConfigFile(const std::string& path) {
return true;
}

void ConfigurationParser::PrintHelpMessage(char *argv[]) {
std::cout << argv[0] << " aircraft [options]\n\n"
<< " aircraft Aircraft config file name e.g. rascal"
<< " -h | --help Print available options\n"
<< " -s | --scene Location / scene where the vehicle should be spawned in e.g. LSZH\n";
}
23 changes: 19 additions & 4 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,29 @@
#include "jsbsim_bridge.h"

int main(int argc, char *argv[]) {
// Path to config file
std::string path = std::string(JSBSIM_ROOT_DIR) + "/configs/" + std::string(argv[3]) + ".xml";

// Parse Configurations
ConfigurationParser config;
if (argc > 1) {
// Path to config file
std::string path = std::string(JSBSIM_ROOT_DIR) + "/configs/" + std::string(argv[1]) + ".xml";
config.ParseConfigFile(path);
}
switch (config.ParseArgV(argc, argv)) {
case ArgResult::Success : {
break;
}
case ArgResult::Help : {
ConfigurationParser::PrintHelpMessage(argv);
return 0;
}
default:
case ArgResult::Error : {
ConfigurationParser::PrintHelpMessage(argv);
return 1;
}
}
config.ParseEnvironmentVariables();
config.ParseArgV(argc, argv);
config.ParseConfigFile(path);

// Configure JSBSim
JSBSim::FGFDMExec *fdmexec = new JSBSim::FGFDMExec();
Expand Down

0 comments on commit 263da94

Please sign in to comment.