Initial commit of Christof's H5PartMerge

This commit is contained in:
2008-01-05 13:52:05 +00:00
parent c356139f6b
commit 16615a96ba
5 changed files with 1572 additions and 0 deletions
+4
View File
@@ -78,6 +78,10 @@ test/H5test.cc -text
test/H5testF.f -text
test/H5testFpar.f90 -text
test/Makefile.am -text
tools/H5PartMerge/H5merge.cpp -text
tools/H5PartMerge/make.sh -text
tools/H5PartMerge/optparse.cpp -text
tools/H5PartMerge/optparse.h -text
tools/Makefile.am -text
tools/README -text
tools/h5pAttrib.cc -text
File diff suppressed because it is too large Load Diff
+3
View File
@@ -0,0 +1,3 @@
g++ -c -g optparse.cpp
g++ -c -g H5merge.cpp -I$HOME/include -DUSE_BOOST
g++ -g -o H5merge0.1 H5merge.o optparse.o -L$HOME/lib -lH5Part -lhdf5 -lz -lm
+309
View File
@@ -0,0 +1,309 @@
/*
* Implementation of optparse.h
*
* Roman Geus, 2005
*
*/
#include <iostream>
#include <sstream>
#include "optparse.h"
using namespace std;
namespace optparse {
/********************** Option **********************/
Option::Option (string shrt, string lng, string dest,
string hlp, action_t act, string dfault, type_t type, string allowed_args)
: action (act),
shrt_flag (shrt),
lng_flag (lng),
help (hlp),
destination (dest),
dfault_(dfault),
type_(type),
allowed_args_(allowed_args)
{}
Option::~Option () {}
bool
Option::is_allowed(std::string argument) {
// Test type
// FIXME: implement that
// Test allowed values
if (allowed_args_ == "")
return true;
size_t pos_begin = 0;
do {
size_t pos_comma = allowed_args_.find(',', pos_begin);
if (pos_comma == string::npos)
pos_comma = allowed_args_.size();
if (allowed_args_.substr(pos_begin, pos_comma-pos_begin) == argument)
return true;
pos_begin = pos_comma + 1;
} while(pos_begin < allowed_args_.size());
return false;
}
/******************** OptionParser *******************/
OptionParser::OptionParser (string usage)
: use_msg (usage)
{ }
OptionParser::~OptionParser () {}
void
OptionParser::add_option(string shrt_flag, string lng_flag, string destination,
string help, action_t act, type_t type, string dfault,
string allowed_values)
{
Option option(shrt_flag, lng_flag, destination, help, act, dfault, type, allowed_values);
/* Add the option to our list of options. */
opts.push_back(option);
/* Set the default value for this option, this not only allows you to
* set default values but insures that every option's destination will
* be in our dictionary, even if the value is only "".
*/
set_option(option, dfault);
}
string OptionParser::get_option(std::string option_name) {
string arg(options[option_name]);
size_t colon_pos = arg.find(':');
return arg.substr(0, colon_pos);
}
void
OptionParser::parse_args (int argc, char **argv) {
/* Walk through the arguments and sort them into options
* or arguments.
*/
for (int i = 1; i < argc; i++) {
/* If we start with a '-' we're probably a <flag><value> pair
* so we need to figure out which option it is. find_opt() is
* where the real work is done.
*/
if (argv[i][0] == '-')
if (argv[i][1] == '-')
find_opt_long(argc, argv, i);
else
find_opt_short(argc, argv, i);
/* If we're looking at an argument (i.e. a value with no flag who's
* meaning is determined by position) just append it into the
* arguments list.
*/
else
arguments.insert(arguments.end(), argv[i]);
}
}
void
OptionParser::help (ostream& os) {
const size_t WORD_WRAP = 50; // max width of last column
// Determine column width for short options
size_t shrt_flag_max_len = 0;
for (size_t i=0; i < opts.size(); ++ i) {
stringstream buf;
buf << opts[i].shrt_flag;
if (opts[i].shrt_flag != "" && opts[i].action == STORE)
buf << " " << type2string(opts[i].type_);
if (buf.str().size() > shrt_flag_max_len)
shrt_flag_max_len = buf.str().size();
}
// Determine column width for long options
size_t lng_flag_max_len = 0;
for (size_t i=0; i < opts.size(); ++ i) {
stringstream buf;
buf << opts[i].lng_flag;
if (opts[i].action == STORE)
buf << "=" << type2string(opts[i].type_);
if (buf.str().size() > lng_flag_max_len)
lng_flag_max_len = buf.str().size();
}
os << use_msg << endl;
for (size_t i=0; i < opts.size(); ++ i) {
stringstream line;
line << " ";
// short option column
stringstream shrt_buf;
shrt_buf << opts[i].shrt_flag;
if (opts[i].shrt_flag != "" && opts[i].action == STORE)
shrt_buf << " " << type2string(opts[i].type_);
line << ' ' << shrt_buf.str();
for (size_t k = 0; k < shrt_flag_max_len-shrt_buf.str().size()+2; ++ k)
line << ' ';
// long option column
stringstream buf;
buf << opts[i].lng_flag;
if (opts[i].action == STORE)
buf << "=" << type2string(opts[i].type_);
line << buf.str();
for (size_t k = 0; k < lng_flag_max_len-buf.str().size()+4; ++ k)
line << ' ';
// help column
os << line.str();
size_t help_col = line.str().size();
line.str("");
line << opts[i].help;
bool is_allowed = opts[i].allowed_args_ != "";
bool is_default = opts[i].action == STORE && opts[i].dfault_ != "";
if (is_allowed || is_default) {
line << " (";
if (is_allowed) {
line << "possible values=";
size_t pos_begin = 0;
size_t pos_comma = opts[i].allowed_args_.find(',', pos_begin);
while (pos_comma != string::npos) {
line << '\'' << opts[i].allowed_args_.substr(pos_begin, pos_comma-pos_begin) << "\',";
pos_begin = pos_comma + 1;
pos_comma = opts[i].allowed_args_.find(',', pos_begin);
}
line << '\'' << opts[i].allowed_args_.substr(pos_begin) << '\'';
if (is_default)
line << ", ";
}
if (is_default)
line << "default=\'" << opts[i].dfault_ << "\'";
line << ')';
}
// split over several lines
size_t begin_pos = 0;
size_t last_pos = 0;
size_t next_pos;
do {
next_pos = line.str().find_first_of(" ,", last_pos+1);
if (next_pos == string::npos)
next_pos = line.str().size()-1;
if (last_pos == line.str().size()-1 || (next_pos+1 - begin_pos > WORD_WRAP && last_pos > begin_pos)) {
if (begin_pos != 0)
for (size_t k = 0; k < help_col+2; ++ k)
os << ' ';
os << line.str().substr(begin_pos, last_pos+1 - begin_pos) << endl;
begin_pos = last_pos+1;
last_pos = begin_pos;
} else
last_pos = next_pos;
} while (begin_pos != line.str().size());
}
}
void
OptionParser::find_opt_short(int argc, char **argv, int &index) {
/* Step through our list of known options. */
for (size_t i = 0; i < opts.size(); i++) {
/* Uses the overridden == operator for the Options class
* to compare argv[index] to the flags of each Option.
*/
if (opts[i].shrt_flag == (string)argv[index]) {
switch (opts[i].action) {
case STORE_FALSE:
set_option(opts[i], "0");
break;
case STORE_TRUE:
set_option(opts[i], "1");
break;
case STORE:
/* Set the value and return if we've found a match. */
if (index >= argc-1)
throw OptionError(argv[index], "Missing option argument");
set_option(opts[i], argv[index+1]);
index++;
break;
default:
break;
};
return;
}
}
/* If we haven't found a match this is not a known argument. */
throw OptionError(argv[index], "Unknown option");
}
void
OptionParser::find_opt_long(int argc, char **argv, int &index) {
// Split option and argument at "="
string option;
string argument;
string arg_str(argv[index]);
size_t equal_pos = arg_str.find('=');
if (equal_pos != string::npos) {
option = arg_str.substr(0, equal_pos);
argument = arg_str.substr(equal_pos+1, string::npos);
} else
option = arg_str;
/* Step through our list of known options. */
for (size_t i = 0; i < opts.size(); i++) {
if (opts[i].lng_flag == option) {
switch (opts[i].action) {
case STORE_FALSE:
if (argument != "")
throw OptionError(option, "No argument expected for this option");
set_option(opts[i], "0");
break;
case STORE_TRUE:
if (argument != "")
throw OptionError(option, "No argument expected for this option");
set_option(opts[i], "1");
break;
case STORE:
if (argument == "")
throw OptionError(option, "Missing option argument");
set_option(opts[i], argument);
break;
default:
break;
};
return;
}
}
/* If we haven't found a match this is not a known argument. */
throw OptionError(option, "Unknown option");
}
void OptionParser::set_option(Option& option, std::string argument) {
if (option.is_allowed(argument))
options[option.destination] = argument;
else
throw OptionError("", "Invalid argument for option");
}
string OptionParser::type2string(type_t type) {
if (type == STRING)
return string("STRING");
else if (type == DOUBLE)
return string("DOUBLE");
else if (type == INT)
return string("INT");
else if (type == BOOL)
return string("BOOL");
else
return "";
}
template<> bool OptionParser::get<bool>(std::string option_name)
{
return get_option(option_name) == "1";
}
} // namespace optparse
+180
View File
@@ -0,0 +1,180 @@
/*
* optparse.h
*
* An option parser for C++ modeled after the optparse Python
* module. Create an instance of OptionParser in your program
* and you can add options to it then call the method
* parse_args with argc and argv and it will parse them. The
* '-h' and '--help' options are built in, they print the
* usage message.
*
* W. Evan Sheehan <evan_sheehan@nrel.gov>
*
*/
#ifndef OPTPARSE_H
#define OPTPARSE_H
#include <map>
#include <vector>
#include <string>
#include <sstream>
#include <stdexcept>
namespace optparse {
/**
* Action type.
* Use this type to determine what we're storing, naming
* convention is the same as the optparse python module.
* Even with STORE_FALSE and STORE_TRUE the values are
* going to be stored as strings, false is "0" true is "1"
* so you can just atoi() the value and use that for tests.
*/
typedef enum {STORE_FALSE=0, STORE_TRUE, STORE} action_t;
/**
* Option argument type.
* Defines expected option argument type.
*/
typedef enum {STRING=0, BOOL, INT, DOUBLE} type_t;
/** Option for OptionParser */
class Option {
public:
Option (std::string shrt, std::string lng, std::string dest,
std::string hlp, action_t act, std::string dfault, type_t type,
std::string allowed_args);
~Option ();
/**
* Validate option argument.
* Test if argument is valid for the option. The argument must be valid w.r.t.
* to type_ and allowed_values_.
* @param argument Argument to be tested.
* @return true if argument is valid.
*/
bool is_allowed(std::string argument);
action_t action; // define what we store
std::string shrt_flag; // short flag, something like -o
std::string lng_flag; // long flag, something like --outfile
std::string help; // help message about the option
std::string destination; // the key used to store this option in the parser.
/**
* Default value. An empty string means no default value exist.
*/
std::string dfault_;
/**
* Expected type the argument of this option should have.
* Only relevant for STORE action.
* Used for generating the usage string.
*/
type_t type_;
std::string allowed_args_; //!< Comma-separated list of allowed option arguments.
};
class OptionError : public std::runtime_error {
public:
OptionError(std::string option, std::string error_msg)
: std::runtime_error("") {
std::ostringstream str;
str << "OptionParser error: option: " << option << ", cause: " << error_msg;
msg_ = str.str();
}
virtual ~OptionError() throw() {}
/**
* Human-readable error message.
* @return Pointer to error message.
*/
virtual const char* what() const throw() { return msg_.c_str(); }
protected:
std::string msg_;
};
/** Option parser. */
class OptionParser {
public:
OptionParser (std::string usage="");
virtual ~OptionParser ();
/**
* Add an option to the parser.
* @param shrt_flag Short option name, like e.g. "-q".
* @param lng_flag Long option name, like e.g. "--quiet"
* @param destination Key under which the option argument is stored in the dictionary.
* @param help Help string for generating the usage info.
* @param act Action, one of STORE, STORE_TRUE, STORE_FALSE.
* @param type Type info of the expected option argument. One of INT, DOUBLE, STRING, BOOL.
* @param dfault Default value. Value stored in the dictionary if the option is not given.
* @param allowed_values List of possible option values.
* A string of comma-separated allowed values. An empty string means
* that any value is allowed.
*/
void add_option (std::string shrt_flag, std::string lng_flag,
std::string destination, std::string help="", action_t act=STORE,
type_t type=STRING, std::string dfault="",
std::string allowed_values="");
/**
* Get option argument.
* @param option_name Name of option, as given in "destination" parameter of "add_option".
* @return Option argument with type appendix removed.
*/
std::string get_option(std::string option_name);
template<typename T> T get(std::string option_name);
/* Parse the commandline args. */
void parse_args (int argc, char **argv);
/**
* Write usage info to stream.
* The usage info includes a formatted list of all options the parser knows about,
* including the help string, expected argument type and default value.
* @param os Output stream the usage info is written to.
*/
void help (std::ostream& os);
/**
* Convert type_t type to human-readable string.
* This is used for generating the usage string and also in
* TypeOptionParser to encode the argument type in the options dictionary.
* @see help
* @param type Type.
* @return Converted string.
*/
std::string type2string(type_t type);
/**
* Type of "options" dictionary.
*/
typedef std::map<std::string, std::string> options_type;
options_type options; //!< Dictionary of options. Use options[key] to access.
std::vector<std::string> arguments; //!< List of positional arguments.
protected:
/**
* Set option in dictionary.
* Function the parser uses to store an option argument or a default value in
* options dictionary. Can be overridden in a subclass to store additional info.
* @param option Option object.
* @param argument Option argument to store.
*/
virtual void set_option(Option& option, std::string argument);
private:
std::string use_msg; //!< Usage message.
std::vector<Option> opts; //!< List of options the parser knows about.
/* Helper for finding which Option (if any) argv[index] matches. */
void find_opt_short(int argc, char **argv, int &index);
void find_opt_long(int argc, char **argv, int &index);
};
template<typename T> T OptionParser::get(std::string option_name)
{
std::string s = get_option(option_name);
std::istringstream strin(s);
T t;
strin >> t;
return t;
}
} // namespace optparse
#endif