mirror of
https://github.com/pdf2htmlEX/pdf2htmlEX.git
synced 2024-12-22 04:50:09 +00:00
finish arg parsing
This commit is contained in:
parent
c957140642
commit
03779406b8
@ -9,6 +9,7 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <cassert>
|
||||
|
||||
#include "ArgParser.h"
|
||||
|
||||
@ -25,6 +26,8 @@ ArgParser::~ArgParser(void)
|
||||
{
|
||||
for(auto iter = arg_entries.begin(); iter != arg_entries.end(); ++iter)
|
||||
delete (*iter);
|
||||
for(auto iter = optional_arg_entries.begin(); iter != optional_arg_entries.end(); ++iter)
|
||||
delete (*iter);
|
||||
}
|
||||
|
||||
ArgParser & ArgParser::add(const char * optname, const char * description, ArgParserCallBack callback)
|
||||
@ -80,19 +83,27 @@ void ArgParser::parse(int argc, char ** argv) const
|
||||
{
|
||||
r = getopt_long(argc, argv, &optstring.front(), &longopts.front(), &idx);
|
||||
if(r == -1)
|
||||
return;
|
||||
if(r == ':')
|
||||
break;
|
||||
assert(r != ':');
|
||||
if(r == '?')
|
||||
{
|
||||
ostringstream sout;
|
||||
sout << "Missing argument for option ";
|
||||
if(r < 256)
|
||||
sout << "-" << (char)(opt_map[optopt]->shortname);
|
||||
else
|
||||
sout << "--" << opt_map[optopt]->name;
|
||||
sout << endl;
|
||||
throw sout.str();
|
||||
assert(optopt < 256);
|
||||
throw string() + ((opt_map.find(optopt) == opt_map.end()) ? "Unknown option: -" : "Missing argument for option -") + (char)optopt;
|
||||
}
|
||||
cerr << r << ' ' << idx << ' ' << (optarg ? optarg : "") << endl;
|
||||
|
||||
auto iter = opt_map.find(r);
|
||||
assert(iter != opt_map.end());
|
||||
iter->second->parse(optarg);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int i = optind;
|
||||
auto iter = optional_arg_entries.begin();
|
||||
while((i < argc) && (iter != optional_arg_entries.end()))
|
||||
{
|
||||
(*(iter++))->parse(argv[i++]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ class ArgParser
|
||||
public:
|
||||
~ArgParser(void);
|
||||
|
||||
typedef void (*ArgParserCallBack) (void);
|
||||
typedef void (*ArgParserCallBack) (const char * arg);
|
||||
|
||||
/*
|
||||
* optname: name of the argment, should be provided as --optname
|
||||
@ -44,7 +44,7 @@ private:
|
||||
std::string name;
|
||||
std::string description;
|
||||
bool need_arg;
|
||||
virtual void parse (void) const = 0;
|
||||
virtual void parse (const char * arg) const = 0;
|
||||
virtual void show_usage (std::ostream & out) const = 0;
|
||||
};
|
||||
|
||||
@ -54,7 +54,7 @@ private:
|
||||
public:
|
||||
ArgEntry(const char * name, T * location, const Tv & deafult_value, ArgParserCallBack callback, const char * description);
|
||||
|
||||
virtual void parse (void) const;
|
||||
virtual void parse (const char * arg) const;
|
||||
virtual void show_usage (std::ostream & out) const;
|
||||
|
||||
private:
|
||||
@ -63,14 +63,18 @@ private:
|
||||
ArgParserCallBack callback;
|
||||
};
|
||||
|
||||
std::vector<ArgEntryBase *> arg_entries;
|
||||
std::vector<ArgEntryBase *> arg_entries, optional_arg_entries;
|
||||
static const int arg_col_width;
|
||||
};
|
||||
|
||||
template<class T, class Tv>
|
||||
ArgParser & ArgParser::add(const char * optname, T * location, const Tv & default_value, const char * description, ArgParserCallBack callback)
|
||||
{
|
||||
arg_entries.push_back(new ArgEntry<T, Tv>(optname, location, default_value, callback, description));
|
||||
// use "" in case nullptr is provided
|
||||
if((!optname) || (!optname[0]))
|
||||
optional_arg_entries.push_back(new ArgEntry<T, Tv>("", location, default_value, callback, ""));
|
||||
else
|
||||
arg_entries.push_back(new ArgEntry<T, Tv>(optname, location, default_value, callback, description));
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -87,8 +91,21 @@ ArgParser::ArgEntry<T, Tv>::ArgEntry(const char * name, T * location, const Tv &
|
||||
}
|
||||
|
||||
template<class T, class Tv>
|
||||
void ArgParser::ArgEntry<T, Tv>::parse(void) const
|
||||
{ }
|
||||
void ArgParser::ArgEntry<T, Tv>::parse(const char * arg) const
|
||||
{
|
||||
if(need_arg)
|
||||
{
|
||||
if(!arg)
|
||||
throw std::string("Missing argument of option: --") + name;
|
||||
|
||||
std::istringstream sin(arg);
|
||||
if(!(sin >> (*location)))
|
||||
throw std::string("Cannot parse argment of option: --") + name;
|
||||
}
|
||||
|
||||
if(callback)
|
||||
(*callback)(arg);
|
||||
}
|
||||
|
||||
// helper
|
||||
template<class T>
|
||||
|
@ -31,7 +31,7 @@ using namespace std;
|
||||
Param param;
|
||||
ArgParser argparser;
|
||||
|
||||
void show_usage_and_exit(void)
|
||||
void show_usage_and_exit(const char * dummy = nullptr)
|
||||
{
|
||||
cerr << "pdftohtmlEX version " << PDF2HTMLEX_VERSION << endl;
|
||||
cerr << endl;
|
||||
@ -81,6 +81,8 @@ void parse_options (int argc, char **argv)
|
||||
|
||||
.add("debug", ¶m.debug, 0, "output debug information")
|
||||
.add("clean-tmp", ¶m.clean_tmp, 1, "clean temporary files after processing")
|
||||
.add("", ¶m.input_filename, "", "")
|
||||
.add("", ¶m.output_filename, "", "")
|
||||
;
|
||||
|
||||
try
|
||||
@ -100,7 +102,8 @@ int main(int argc, char **argv)
|
||||
parse_options(argc, argv);
|
||||
if (param.input_filename == "")
|
||||
{
|
||||
show_usage_and_exit();
|
||||
cerr << "Missing input filename" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
//prepare the directories
|
||||
|
Loading…
Reference in New Issue
Block a user