void Kernel::doSwitches(int argc, const char *argv[], ProgramArgs& args) { StringList stringArgs; OptionsMap& stageOptions = m_manager.stageOptions(); // Scan the argument vector for extra stage options. Pull them out and // stick them in the list. Let the ProgramArgs handle everything else. // NOTE: This depends on the format being "option=value" rather than // "option value". This is what we've always expected, so no problem, // but it would be better to be more flexible. for (int i = 0; i < argc; ++i) { std::string stageName, opName, value; if (parseOption(argv[i], stageName, opName, value)) { Option op(opName, value); stageOptions[stageName].add(op); } else stringArgs.push_back(argv[i]); } try { addBasicSwitches(args); // parseSimple allows us to scan for the help option without // raising exception about missing arguments and so on. args.parseSimple(stringArgs); addSwitches(args); if (!m_showHelp) { args.reset(); args.parse(stringArgs); } } catch (arg_error& e) { throw pdal_error(e.m_error); } }
int App::execute(StringList& cmdArgs, LogPtr& log) { ProgramArgs args; addArgs(args); try { args.parseSimple(cmdArgs); } catch (arg_val_error const& e) { Utils::printError(e.what()); return -1; } log.reset(new Log("PDAL", m_log, m_logtiming)); if (m_logLevel != LogLevel::None) log->setLevel(m_logLevel); else if (m_debug) log->setLevel(LogLevel::Debug); log->get(LogLevel::Debug) << "Debugging..." << std::endl; PluginManager<Stage>::setLog(log); PluginManager<Kernel>::setLog(log); #ifndef _WIN32 if (m_debug) { signal(SIGSEGV, [](int sig) { logPtr->get(LogLevel::Debug) << "Segmentation fault (signal 11)\n"; StringList lines = Utils::backtrace(); for (const auto& l : lines) logPtr->get(LogLevel::Debug) << l << std::endl; exit(1); }); } #endif m_command = Utils::tolower(m_command); if (!m_command.empty()) { int ret = 0; std::string name("kernels." + m_command); Kernel *kernel = PluginManager<Kernel>::createObject(name); if (kernel) { if (m_help) cmdArgs.push_back("--help"); // This shouldn't throw. If it does, it's something awful, so // not cleaning up seems inconsequential. log->setLeader("pdal " + m_command); ret = kernel->run(cmdArgs, log); delete kernel; // IMPORTANT - The kernel must be destroyed before GDAL // drivers are unregistered or GDAL will attempt to destroy // resources more than once, resulting in a crash. gdal::unregisterDrivers(); } else log->get(LogLevel::Error) << "Command '" << m_command << "' not recognized" << std::endl << std::endl; return ret; } if (m_showVersion) outputVersion(); else if (m_showDrivers) outputDrivers(); else if (m_showOptions.size()) { if (m_showOptions == "all") outputOptions(); else outputOptions(m_showOptions, m_out); } else outputHelp(args); return 0; }