static int parseOption(int argc, char** argv) { if (argc <= 1) { optHelp(argc, argv); return 0; // unreachable } // argv[i] is the current processing argument from command line int i = 1; while (i < argc) { const unsigned left_argc = argc - i - 1; if (argv[i][0] == '-') { // Find the corresponding OptionInfo object unsigned opt_idx = 0; while (opt_idx < NUM_OPTIONS) { if (::strcmp(&argv[i][1], Options[opt_idx].option_name) == 0) { const struct OptionInfo *cur_option = &Options[opt_idx]; if (left_argc < cur_option->min_option_argc) { fprintf(stderr, "%s: '%s' requires at least %u arguments", argv[0], cur_option->option_name, cur_option->min_option_argc); return 1; } int result = cur_option->process(left_argc, &argv[i]); if (result >= 0) { // consume the used arguments i += result; } else { // error occurs return 1; } break; } ++opt_idx; } if (opt_idx >= NUM_OPTIONS) { fprintf(stderr, "%s: unrecognized option '%s'", argv[0], argv[i]); return 1; } } else { if (InFile == NULL) { optSetInput(left_argc, &argv[i]); } else { fprintf(stderr, "%s: only a single input file is allowed currently.", argv[0]); return 1; } } i++; } return 0; }
int Application::run(int argc, const char* const* const argv) { // Set up general options options::Option optHelp("h", "Print usage information and exit"); opts.addOption(optHelp); // Register an observer for printing the usage when -h is supplied. // Note that we use an observer for this instead of checking manually (right after opts.parse()) if optHelp was used, because other observers might perform actions which are undesired if -h has been passed. This is why helpObserver is the first observer we register. options::HelpObserver helpObserver(*this, optHelp); opts.registerObserver(helpObserver); options::Option optVersion("version", "Print version number and exit"); opts.addOption(optVersion); options::VersionObserver versionObserver(*this, optVersion); opts.registerObserver(versionObserver); options::SingleValueOption optDepth("depth", "d", "Print only item sets of depth at most <d>"); opts.addOption(optDepth); options::MultiValueOption optEdge("e", "edge", "Predicate <edge> declares (hyper)edges"); opts.addOption(optEdge); options::SingleValueOption optInputFile("f", "file", "Read problem instance from <file> (stdin by default)"); opts.addOption(optInputFile); opts.addOption(optNoCounting); opts.addOption(optNoPruning); opts.addOption(optPrintDecomposition); options::SingleValueOption optGraphMlOut("graphml-out", "file", "Write the decomposition in the GraphML format to <file>"); opts.addOption(optGraphMlOut); options::SingleValueOption optSeed("seed", "n", "Initialize random number generator with seed <n>"); opts.addOption(optSeed); // Set up module selection options opts.addOption(optDecomposer, MODULE_SECTION); decomposer::Dummy dummyDecomposer(*this); decomposer::TreeDecomposer treeDecomposer(*this, true); decomposer::GraphMl graphMlDecomposer(*this); opts.addOption(optSolver, MODULE_SECTION); solver::dummy::SolverFactory dummySolverFactory(*this); solver::clasp::SolverFactory claspSolverFactory(*this, true); solver::asp::SolverFactory aspSolverFactory(*this); opts.addOption(optPrinter, MODULE_SECTION); printer::Quiet quietPrinter(*this); printer::Progress progressPrinter(*this, true); printer::DebugHumanReadable humanReadableDebugPrinter(*this); printer::DebugMachineReadable machineReadableDebugPrinter(*this); time_t seed = time(0); // Parse command line try { opts.parse(argc, argv); opts.checkConditions(); if(optSeed.isUsed()) seed = strToInt(optSeed.getValue(), "Invalid random seed"); if(optDepth.isUsed()) depth = strToInt(optDepth.getValue(), "Invalid depth"); if(!optEdge.isUsed()) throw std::runtime_error("Option -e must be supplied at least once"); } catch(...) { printUsage(); throw; } srand(seed); assert(decomposer); assert(solverFactory); // Get (hyper-)edge predicate names parser::Driver::Predicates edgePredicates(optEdge.getValues().begin(), optEdge.getValues().end()); // Store the problem instance in a string // FIXME This should only be done for solvers that need it. if(optInputFile.isUsed()) { std::ifstream inputFile(optInputFile.getValue()); if(!inputFile) throw std::runtime_error("Could not open input file"); std::ostringstream inputStringStream; inputStringStream << inputFile.rdbuf(); inputString = inputStringStream.str(); } else { std::ostringstream inputStringStream; inputStringStream << std::cin.rdbuf(); inputString = inputStringStream.str(); } // Parse instance inputHypergraph = parser::Driver(inputString, edgePredicates).parse(); // Decompose instance DecompositionPtr decomposition = decomposer->decompose(inputHypergraph); if(optGraphMlOut.isUsed()) { std::ofstream graphMlFile(optGraphMlOut.getValue().c_str()); decomposition->printGraphMl(graphMlFile); if(!graphMlFile) throw std::runtime_error("Could not write GraphML output"); } printer->decomposerResult(*decomposition); // Solve ItemTreePtr rootItree = decomposition->getSolver().compute(); printer->result(rootItree); return rootItree ? 10 : 20; }