9 static const char rcsid[] __attribute__((used)) =
"$Id: CommandLine.cpp 1653 2016-02-28 19:54:59Z sella $";
11 #include "CommandLine.h"
12 #include "CommandLineOption.h"
24 using namespace sella::util;
26 CommandLine::CommandLine(
int argc,
char **argv)
throw () :
36 CommandLine::CommandLine(
const CommandLine ©)
throw () :
41 argument(copy.argument),
46 CommandLine::~CommandLine() throw () {
48 this->argument.clear();
53 this->argc = other.argc;
54 this->argv = other.argv;
56 this->option = other.option;
57 this->argument = other.argument;
59 this->width = other.width;
65 void CommandLine::add(
char opt,
const std::string &option,
const std::string &usage,
const std::string &label,
const std::string &value)
throw () {
69 void CommandLine::add(
char opt,
const std::string &option,
const std::string &usage,
const std::string &label,
long value,
long min,
long max)
throw () {
73 if (min != MINLONG &&value < min) {
75 }
else if (max != MINLONG &&value > max) {
79 snprintf(buf,
sizeof(buf),
"%lu", value);
86 if (this->width < option.getTags().size()) {
87 this->width = option.getTags().size();
90 this->option.push_back(option);
93 void CommandLine::add(
const std::string &argument,
const std::string &usage)
throw () {
94 if (this->width < (argument.size() + 4)) {
95 this->width = argument.size() + 4;
98 this->argument.push_back(std::pair<std::string, std::string>(argument, usage));
101 void CommandLine::usage(FILE *stream,
int result)
const throw () {
103 left.resize(this->width,
' ');
106 if (this->option.size() > 0) {
107 fprintf(stream,
"\nUSAGE: %s [OPTIONS]", this->argv[0]);
109 fprintf(stream,
"\nUSAGE: %s", this->argv[0]);
112 for (
auto iter = this->argument.cbegin(); iter != this->argument.cend(); iter++) {
113 fprintf(stream,
" %s", iter->first.c_str());
117 if (this->argument.size() > 0) {
118 fprintf(stream,
"\n ARGUMENTS\n");
121 for (
auto iter = this->argument.cbegin(); iter != this->argument.cend(); iter++) {
122 std::string argument(iter->first);
123 argument.insert(0, 4,
' ');
124 argument.resize(this->width,
' ');
126 fprintf(stream,
"%s %s\n", argument.c_str(), iter->second.c_str());
130 if (this->option.size() > 0) {
131 fprintf(stream,
"\n OPTIONS\n");
134 for (
auto iter = this->option.cbegin(); iter != this->option.cend(); iter++) {
135 std::string tags(iter->getTags());
137 if (tags.size() > 0) {
138 tags.resize(this->width,
' ');
141 fprintf(stream,
"%s %s\n", tags.c_str(), iter->getUsage().c_str());
143 if (iter->getValue().size() > 0) {
144 fprintf(stream,
"%s [DEFAULT: %s]\n", left.c_str(), iter->getValue().c_str());
147 if (iter->getValue().size() > 0) {
148 fprintf(stream,
"%s %s (default: %s)\n", tags.c_str(), iter->getUsage().c_str(), iter->getValue().c_str());
150 fprintf(stream,
"%s %s\n", tags.c_str(), iter->getUsage().c_str());
154 fprintf(stream,
"\n");
158 fprintf(stream,
"\n");
164 std::map<std::string, std::string> CommandLine::parse(FILE *stream)
const throw () {
165 std::map<std::string, std::string> result;
166 std::map<char, std::string> lookup;
168 std::vector<struct option> long_option;
175 for (
auto iter = this->option.cbegin(); iter != this->option.cend(); iter++) {
176 if (iter->getTags().size() > 0) {
177 long_option.push_back(this->build(iter->getOpt(), iter->getOption(), iter->getArgumented()));
178 option.append(this->tag(iter->getOpt(), iter->getArgumented()));
180 if (iter->getValue().size() > 0) {
181 result[iter->getOption()] = iter->getValue();
184 lookup[iter->getOpt()] = iter->getOption();
188 long_option.push_back(this->build(0, std::string(), 0));
191 while ((c = getopt_long(this->argc, this->argv, option.c_str(), &(long_option[0]), &index)) >= 0) {
192 if (lookup.find(c) != lookup.end()) {
194 result[lookup[c]] = std::string(optarg);
196 result[lookup[c]] = std::string();
199 this->usage(stream, -1);
204 if (argc != (optind + (
int)(this->argument.size()))) {
205 this->usage(stream, -2);
207 for (
auto iter = this->argument.cbegin(); iter != this->argument.cend(); iter++) {
208 result[iter->first] = argv[optind++];
212 return std::map<std::string, std::string>(result);
215 struct option
CommandLine::build(char tag, const std::string &name, bool argument) const throw () {
216 struct option option = { (name.size() > 0) ? name.c_str() : NULL, (argument ==
true) ? 1 : 0, NULL, tag };
221 const std::string CommandLine::tag(
char tag,
bool argument)
const throw () {
224 if (((tag >=
'a') &&(tag <=
'z')) || ((tag >=
'A') &&(tag <=
'Z')) || ((tag >=
'0') &&(tag <=
'9'))) {
226 snprintf(buffer, 4,
"%c:", tag);
228 snprintf(buffer, 4,
"%c", tag);
234 return std::string(buffer);