#include #include #include #include #include #include #include #include #include OptionsParserError::OptionsParserError( const std::string& errorMessage, const OptionParser& parser ) : std::invalid_argument(errorMessage + "\n" + parser.getUsage()) { } const char* OptionsParserError::what() const noexcept { return std::invalid_argument::what(); } JustPrintUsageNoError::JustPrintUsageNoError(const OptionParser& parser) : message(parser.getUsage()) { } const char* JustPrintUsageNoError::what() const noexcept { return message.c_str(); } struct option OptionParser::longOptions[] = { {"dapspec", required_argument, 0, 's'}, {"spec", required_argument, 0, 's'}, {"dapfile", required_argument, 0, 'd'}, {"api-lib", required_argument, 0, 'a'}, {"apilib", required_argument, 0, 'a'}, {"api", required_argument, 0, 'a'}, {"lib", required_argument, 0, 'a'}, {"api-lib-path", required_argument, 0, 'p'}, {"apipath", required_argument, 0, 'p'}, {"libpath", required_argument, 0, 'p'}, {"verbose", no_argument, 0, 'v'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; void OptionParser::parseArguments(int argc, char *argv[], char **envp) { (void)envp; int opt; int optionIndex = 0; argv0 = argv[0]; optind = 1; // Reset optind to 1 before parsing opterr = 0; while ((opt = getopt_long( argc, argv, "s:d:a:p:vh?", longOptions, &optionIndex)) != -1) { switch (opt) { case 's': if (!dapSpecs.empty()) { dapSpecs += "||"; } dapSpecs += std::string(optarg); break; case 'd': dapSpecFiles.push_back(optarg); break; case 'a': senseApiLibs.push_back(optarg); break; case 'p': { struct stat info; if (stat(optarg, &info) != 0 || !(info.st_mode & S_IFDIR)) { throw OptionsParserError( std::string(__func__) + " - The specified path is not a " "directory: " + optarg, *this); } senseApiLibPath.push_back(optarg); break; } case 'v': verbose = true; break; case 'h': throw JustPrintUsageNoError(*this); case '?': throw OptionsParserError( std::string(__func__) + " - Invalid argument encountered: " + std::string(argv[optind - 1]), *this); } } } std::string OptionParser::getUsage() const { return "Usage: " + argv0 + " [-s|--dapspec|--spec ] " "[-d|--dapfile ] " "[-a|--api-lib|--apilib|--api|--lib ] " "[-p|--api-lib-path|--apipath|--libpath ] " "[-v|--verbose] " "[-h|--help]\n\n" "Example DAP spec:\n" " -s '+edev|my-cam|video-qualeiface|v4l2-video(fps-hz=30)|v4l2()|/dev/video0'"; } std::string OptionParser::stringifyOptions(void) const { std::ostringstream oss; if (verbose) { oss << "Verbose mode is on" << std::endl; } oss << "DAP Specs: " << dapSpecs << std::endl; oss << "DAP Spec Files: "; for (const auto& file : dapSpecFiles) { oss << file << " "; } oss << std::endl; oss << "Stim Buff API Library Paths: "; for (const auto& path : senseApiLibPath) { oss << path << " "; } oss << std::endl; oss << "Stim Buff API Libraries: "; for (const auto& lib : senseApiLibs) { oss << lib << " "; } oss << std::endl; return oss.str(); }