Skip to content

Commit

Permalink
Use ProgramArgs for all kernels.
Browse files Browse the repository at this point in the history
  • Loading branch information
abellgithub committed Jan 28, 2016
1 parent b518702 commit a539147
Show file tree
Hide file tree
Showing 37 changed files with 506 additions and 644 deletions.
6 changes: 3 additions & 3 deletions apps/pdal.cpp
Expand Up @@ -246,11 +246,11 @@ int main(int argc, char* argv[])
// Dispatch execution to the kernel, passing all remaining args
if (isValidKernel)
{
int count(argc - 1); // remove the 1st argument
const char** args = const_cast<const char**>(&argv[1]);
int count(argc - 2); // remove 'pdal' and the kernel name
argv += 2;
void *kernel = PluginManager::createObject(fullname);
std::unique_ptr<Kernel> app(static_cast<Kernel *>(kernel));
return app->run(count, args, command);
return app->run(count, const_cast<char const **>(argv), command);
}

// Otherwise, process the remaining args to see if they are supported
Expand Down
24 changes: 10 additions & 14 deletions include/pdal/Kernel.hpp
Expand Up @@ -34,8 +34,6 @@

#pragma once

#include <pdal/KernelSupport.hpp>
#include <pdal/pdal_export.hpp>

#ifdef PDAL_COMPILER_MSVC
# pragma warning(push)
Expand All @@ -53,6 +51,9 @@
#include <string>
#include <vector>

#include <pdal/KernelSupport.hpp>
#include <pdal/util/ProgramArgs.hpp>

namespace po = boost::program_options;

namespace pdal
Expand Down Expand Up @@ -91,8 +92,7 @@ class PDAL_DLL Kernel
Stage& makeWriter(const std::string& outputFile, Stage& parent);

public:
// implement this, with calls to addOptionSet()
virtual void addSwitches() {}
virtual void addSwitches(ProgramArgs& args) {}

// implement this, to do sanity checking of cmd line
// will throw if the user gave us bad options
Expand All @@ -104,7 +104,6 @@ class PDAL_DLL Kernel

void addSwitchSet(po::options_description* options);
void addHiddenSwitchSet(po::options_description* options);
void addPositionalSwitch(const char* name, int max_count);
void setCommonOptions(Options &options);

void setProgressShellCommand(std::vector<std::string> const& command)
Expand Down Expand Up @@ -150,30 +149,27 @@ class PDAL_DLL Kernel
bool argumentSpecified(const std::string& name);

bool m_usestdin;
int m_argc;
const char** m_argv;
Log m_log;

private:
int innerRun();
void parseSwitches();
void outputHelp();
void outputVersion();
void addBasicSwitchSet();
void addBasicSwitches(ProgramArgs& args);
void collectExtraOptions();

int do_switches();
int do_startup();
int do_execution();
int do_shutdown();
void doSwitches(int argc, const char *argv[], ProgramArgs& args);
int doStartup();
int doExecution();
int doShutdown();

static bool test_parseOption(std::string o, std::string& stage,
std::string& option, std::string& value);

bool m_isDebug;
uint32_t m_verboseLevel;
bool m_showHelp;
std::string m_showOptions;
bool m_showOptions;
bool m_showVersion;
bool m_showTime;
std::string m_appName;
Expand Down
100 changes: 75 additions & 25 deletions include/pdal/util/ProgramArgs.hpp
Expand Up @@ -23,6 +23,7 @@
#pragma once

#include <map>
#include <queue>

#include <pdal/util/Utils.hpp>

Expand All @@ -38,14 +39,27 @@ class arg_error
std::string m_error;
};

class BaseArg
class Arg
{
protected:
BaseArg(const std::string& longname, const std::string& shortname,
Arg(const std::string& longname, const std::string& shortname,
const std::string& description) : m_longname(longname),
m_shortname(shortname), m_description(description), m_set(false)
m_shortname(shortname), m_description(description), m_set(false),
m_hidden(false), m_positional(false)
{}

public:
void setHidden(bool hidden = true)
{ m_hidden = true; }
virtual void setPositional()
{ m_positional = true; }
bool set() const
{ return m_set; }
bool positional() const
{ return m_positional; }
std::string name() const
{ return m_longname; }

public:
virtual bool needsValue() const
{ return true; }
Expand All @@ -58,15 +72,17 @@ class BaseArg
std::string m_description;
std::string m_rawVal;
bool m_set;
bool m_hidden;
bool m_positional;
};

template <typename T>
class Arg : public BaseArg
class TArg : public Arg
{
public:
Arg(const std::string& longname, const std::string& shortname,
TArg(const std::string& longname, const std::string& shortname,
const std::string& description, T& variable, T def) :
BaseArg(longname, shortname, description), m_var(variable),
Arg(longname, shortname, description), m_var(variable),
m_defaultVal(def)
{ m_var = m_defaultVal; }

Expand All @@ -93,6 +109,7 @@ class Arg : public BaseArg
{
m_var = m_defaultVal;
m_set = false;
m_hidden = false;
}

private:
Expand All @@ -101,12 +118,12 @@ class Arg : public BaseArg
};

template <>
class Arg<bool> : public BaseArg
class TArg<bool> : public Arg
{
public:
Arg(const std::string& longname, const std::string& shortname,
TArg(const std::string& longname, const std::string& shortname,
const std::string& description, bool& variable, bool def) :
BaseArg(longname, shortname, description), m_val(variable),
Arg(longname, shortname, description), m_val(variable),
m_defaultVal(def)
{}

Expand All @@ -128,6 +145,13 @@ class Arg<bool> : public BaseArg
{
m_val = m_defaultVal;
m_set = false;
m_hidden = false;
}
virtual void setPositional()
{
std::ostringstream oss;
oss << "Boolean argument '" << m_longname << "' can't be positional.";
throw arg_error(oss.str());
}

private:
Expand All @@ -138,14 +162,14 @@ class Arg<bool> : public BaseArg
class ProgramArgs
{
public:
void add(const std::string& name, const std::string description,
Arg *add(const std::string& name, const std::string description,
std::string& var, std::string def)
{
add<std::string>(name, description, var, def);
return add<std::string>(name, description, var, def);
}

template<typename T>
void add(const std::string& name, const std::string description, T& var,
Arg *add(const std::string& name, const std::string description, T& var,
T def = T())
{
// Arg names must be specified as "longname[,shortname]" where
Expand All @@ -161,12 +185,13 @@ class ProgramArgs
if (s.size() == 1)
s.push_back("");

BaseArg *arg = new Arg<T>(s[0], s[1], description, var, def);
Arg *arg = new TArg<T>(s[0], s[1], description, var, def);
if (s[0].size())
m_longargs[s[0]] = arg;
if (s[1].size())
m_shortargs[s[1]] = arg;
m_args.push_back(std::unique_ptr<BaseArg>(arg));
m_args.push_back(std::unique_ptr<Arg>(arg));
return arg;
}

void parse(int argc, char *argv[])
Expand All @@ -188,6 +213,25 @@ class ProgramArgs
std::string value((i != s.size() - 1) ? s[i + 1] : "-");
i += parseArg(arg, value);
}

// Go through things on the positional list looking for matches.
for (auto ai = m_args.begin(); ai != m_args.end(); ++ai)
{
Arg *arg = ai->get();
if (arg->positional() && !arg->set())
{
if (m_positional.empty())
{
std::ostringstream oss;

oss << "Missing value for positional argument '" <<
arg->name() << "'.";
throw arg_error(oss.str());
}
arg->setValue(m_positional.front());
m_positional.pop();
}
}
}

void reset()
Expand All @@ -197,15 +241,15 @@ class ProgramArgs
}

private:
BaseArg *findLongArg(const std::string& s)
Arg *findLongArg(const std::string& s)
{
auto si = m_longargs.find(s);
if (si != m_longargs.end())
return si->second;
return NULL;
}

BaseArg *findShortArg(char c)
Arg *findShortArg(char c)
{
std::string s(1, c);
auto si = m_shortargs.find(s);
Expand All @@ -216,18 +260,21 @@ class ProgramArgs

int parseArg(std::string& arg, std::string value)
{
if (arg.size() > 2 && arg[0] == '-' && arg[1] == '-')
if (arg.size() > 1 && arg[0] == '-' && arg[1] == '-')
return parseLongArg(arg, value);
else if (arg.size() > 1 && arg[0] == '-')
else if (arg.size() && arg[0] == '-')
return parseShortArg(arg, value);
m_unrecognized.push_back(arg);
m_positional.push(arg);
return 1;
}

int parseLongArg(std::string name, std::string value)
{
bool attachedValue = false;

if (name.size() == 2)
throw arg_error("No argument found following '--'.");

name = name.substr(2);

std::size_t pos = name.find_first_of("=");
Expand All @@ -240,7 +287,7 @@ class ProgramArgs
attachedValue = true;
}
}
BaseArg *arg = findLongArg(name);
Arg *arg = findLongArg(name);
if (!arg)
{
std::ostringstream oss;
Expand Down Expand Up @@ -272,7 +319,7 @@ class ProgramArgs
if (name.size() == 1)
throw arg_error("No argument found following '-'.");

BaseArg *arg = findShortArg(name[1]);
Arg *arg = findShortArg(name[1]);
if (!arg)
{
std::ostringstream oss;
Expand Down Expand Up @@ -306,10 +353,13 @@ class ProgramArgs
return cnt;
}

std::vector<std::unique_ptr<BaseArg>> m_args;
std::map<std::string, BaseArg *> m_shortargs;
std::map<std::string, BaseArg *> m_longargs;
std::vector<std::string> m_unrecognized;
std::vector<std::unique_ptr<Arg>> m_args;
std::map<std::string, Arg *> m_shortargs;
std::map<std::string, Arg *> m_longargs;

// Contains remaining arguments after positional argument have been
// processed.
std::queue<std::string> m_positional;
};

} // namespace pdal
Expand Down
45 changes: 13 additions & 32 deletions kernels/delta/DeltaKernel.cpp
Expand Up @@ -52,39 +52,20 @@ DeltaKernel::DeltaKernel() : m_3d(true), m_detail(false), m_allDims(false)
{}


void DeltaKernel::addSwitches()
void DeltaKernel::addSwitches(ProgramArgs& args)
{
namespace po = boost::program_options;

po::options_description* file_options =
new po::options_description("file options");

file_options->add_options()
("source", po::value<std::string>(&m_sourceFile),
"source file name")
("candidate", po::value<std::string>(&m_candidateFile),
"candidate file name")
("output", po::value<std::string>(&m_outputFile),
"output file name")
("2d", po::value<bool>(&m_3d)->zero_tokens()->implicit_value(false),
"only 2D comparisons/indexing")
("detail",
po::value<bool>(&m_detail)->zero_tokens()->implicit_value(true),
"Output deltas per-point")
("alldims",
po::value<bool>(&m_allDims)->zero_tokens()->implicit_value(true),
"Compute diffs for all dimensions (not just X,Y,Z)");
addSwitchSet(file_options);

po::options_description* processing_options =
new po::options_description("processing options");

processing_options->add_options();
addSwitchSet(processing_options);

addPositionalSwitch("source", 1);
addPositionalSwitch("candidate", 2);
addPositionalSwitch("output", 3);
Arg *arg;

arg = args.add("source", "source file name", m_sourceFile);
arg->setPositional();
arg = args.add("candidate", "candidate file name", m_candidateFile);
arg->setPositional();
arg = args.add("output", "output file name", m_outputFile);
arg->setPositional();
args.add("2d", "only 2D comparisons/indexing", m_3d, true);
args.add("detail", "Output deltas per-point", m_detail);
args.add("alldims", "Compute diffs for all dimensions (not just X,Y,Z)",
m_allDims);
}


Expand Down
2 changes: 1 addition & 1 deletion kernels/delta/DeltaKernel.hpp
Expand Up @@ -75,7 +75,7 @@ class PDAL_DLL DeltaKernel : public Kernel

private:
DeltaKernel();
void addSwitches();
void addSwitches(ProgramArgs& args);
PointViewPtr loadSet(const std::string& filename, PointTable& table);
MetadataNode dump(PointViewPtr& srcView, PointViewPtr& candView,
KD3Index& index, DimIndexMap& dims);
Expand Down

0 comments on commit a539147

Please sign in to comment.