Esempio n. 1
0
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;
}
Esempio n. 2
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;
}