1
0
mirror of https://github.com/pdf2htmlEX/pdf2htmlEX.git synced 2024-07-07 18:30:34 +00:00

finish arg parsing

This commit is contained in:
Lu Wang 2012-09-10 22:22:01 +08:00
parent c957140642
commit 03779406b8
3 changed files with 50 additions and 19 deletions

View File

@ -9,6 +9,7 @@
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include <unordered_map> #include <unordered_map>
#include <cassert>
#include "ArgParser.h" #include "ArgParser.h"
@ -25,6 +26,8 @@ ArgParser::~ArgParser(void)
{ {
for(auto iter = arg_entries.begin(); iter != arg_entries.end(); ++iter) for(auto iter = arg_entries.begin(); iter != arg_entries.end(); ++iter)
delete (*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) 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); r = getopt_long(argc, argv, &optstring.front(), &longopts.front(), &idx);
if(r == -1) if(r == -1)
return; break;
if(r == ':') assert(r != ':');
if(r == '?')
{ {
ostringstream sout; ostringstream sout;
sout << "Missing argument for option "; assert(optopt < 256);
if(r < 256) throw string() + ((opt_map.find(optopt) == opt_map.end()) ? "Unknown option: -" : "Missing argument for option -") + (char)optopt;
sout << "-" << (char)(opt_map[optopt]->shortname);
else
sout << "--" << opt_map[optopt]->name;
sout << endl;
throw sout.str();
} }
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++]);
} }
} }
} }

View File

@ -19,7 +19,7 @@ class ArgParser
public: public:
~ArgParser(void); ~ArgParser(void);
typedef void (*ArgParserCallBack) (void); typedef void (*ArgParserCallBack) (const char * arg);
/* /*
* optname: name of the argment, should be provided as --optname * optname: name of the argment, should be provided as --optname
@ -44,7 +44,7 @@ private:
std::string name; std::string name;
std::string description; std::string description;
bool need_arg; 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; virtual void show_usage (std::ostream & out) const = 0;
}; };
@ -54,7 +54,7 @@ private:
public: public:
ArgEntry(const char * name, T * location, const Tv & deafult_value, ArgParserCallBack callback, const char * description); 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; virtual void show_usage (std::ostream & out) const;
private: private:
@ -63,14 +63,18 @@ private:
ArgParserCallBack callback; ArgParserCallBack callback;
}; };
std::vector<ArgEntryBase *> arg_entries; std::vector<ArgEntryBase *> arg_entries, optional_arg_entries;
static const int arg_col_width; static const int arg_col_width;
}; };
template<class T, class Tv> template<class T, class Tv>
ArgParser & ArgParser::add(const char * optname, T * location, const Tv & default_value, const char * description, ArgParserCallBack callback) 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; return *this;
} }
@ -87,8 +91,21 @@ ArgParser::ArgEntry<T, Tv>::ArgEntry(const char * name, T * location, const Tv &
} }
template<class T, class 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 // helper
template<class T> template<class T>

View File

@ -31,7 +31,7 @@ using namespace std;
Param param; Param param;
ArgParser argparser; ArgParser argparser;
void show_usage_and_exit(void) void show_usage_and_exit(const char * dummy = nullptr)
{ {
cerr << "pdftohtmlEX version " << PDF2HTMLEX_VERSION << endl; cerr << "pdftohtmlEX version " << PDF2HTMLEX_VERSION << endl;
cerr << endl; cerr << endl;
@ -81,6 +81,8 @@ void parse_options (int argc, char **argv)
.add("debug", &param.debug, 0, "output debug information") .add("debug", &param.debug, 0, "output debug information")
.add("clean-tmp", &param.clean_tmp, 1, "clean temporary files after processing") .add("clean-tmp", &param.clean_tmp, 1, "clean temporary files after processing")
.add("", &param.input_filename, "", "")
.add("", &param.output_filename, "", "")
; ;
try try
@ -100,7 +102,8 @@ int main(int argc, char **argv)
parse_options(argc, argv); parse_options(argc, argv);
if (param.input_filename == "") if (param.input_filename == "")
{ {
show_usage_and_exit(); cerr << "Missing input filename" << endl;
exit(EXIT_FAILURE);
} }
//prepare the directories //prepare the directories