| 1 |
#include "CommandArgs.h" |
|---|
| 2 |
CommandArgs::CommandArgs() { |
|---|
| 3 |
} |
|---|
| 4 |
|
|---|
| 5 |
CommandArgs::~CommandArgs() { |
|---|
| 6 |
} |
|---|
| 7 |
|
|---|
| 8 |
void CommandArgs::addArgument(int shortarg, string const &longarg, Parameter argument, string const &help) { |
|---|
| 9 |
Arg arg; |
|---|
| 10 |
|
|---|
| 11 |
arg.shortarg = shortarg; |
|---|
| 12 |
arg.argument = argument; |
|---|
| 13 |
arg.longarg = longarg; |
|---|
| 14 |
arg.help = help; |
|---|
| 15 |
|
|---|
| 16 |
args.push_back(arg); |
|---|
| 17 |
} |
|---|
| 18 |
|
|---|
| 19 |
void CommandArgs::setHelp(int shortarg, string const &help) { |
|---|
| 20 |
for (vector<CommandArgs::Arg>::iterator i = args.begin(); i != args.end(); i++) |
|---|
| 21 |
if ((*i).shortarg == shortarg) { |
|---|
| 22 |
(*i).help = help; |
|---|
| 23 |
return; |
|---|
| 24 |
} |
|---|
| 25 |
throw exception(string("couldn't set help for non-existent option '") + (char)shortarg + "'"); |
|---|
| 26 |
} |
|---|
| 27 |
|
|---|
| 28 |
bool CommandArgs::iterator::get() { |
|---|
| 29 |
if (!argv || arg >= argc) return false; |
|---|
| 30 |
|
|---|
| 31 |
_type = Unknown; |
|---|
| 32 |
_argument = 0; |
|---|
| 33 |
value = 0; |
|---|
| 34 |
// continuing existing short parameter list |
|---|
| 35 |
if (inshort) { |
|---|
| 36 |
char c = argv[arg][inshort]; |
|---|
| 37 |
|
|---|
| 38 |
for (vector<CommandArgs::Arg>::iterator i = cmdarg->args.begin(); i != cmdarg->args.end(); i++) { |
|---|
| 39 |
CommandArgs::Arg const &a = (*i); |
|---|
| 40 |
|
|---|
| 41 |
if (a.shortarg == c) { |
|---|
| 42 |
_type = Argument; |
|---|
| 43 |
|
|---|
| 44 |
// option with a parameter, but still more short args to go |
|---|
| 45 |
if (a.argument == Required && argv[arg][inshort + 1] != 0) { |
|---|
| 46 |
value = argv[arg] + inshort + 1; |
|---|
| 47 |
inshort = 0; |
|---|
| 48 |
_argument = c; |
|---|
| 49 |
arg++; |
|---|
| 50 |
return true; |
|---|
| 51 |
} else { |
|---|
| 52 |
inshort++; |
|---|
| 53 |
// next argument? |
|---|
| 54 |
if (argv[arg][inshort] == 0) { |
|---|
| 55 |
inshort = 0; |
|---|
| 56 |
arg++; |
|---|
| 57 |
// optional argument present? |
|---|
| 58 |
if (arg < argc && a.argument == Optional && argv[arg][0] != '-') { |
|---|
| 59 |
value = argv[arg]; |
|---|
| 60 |
arg++; |
|---|
| 61 |
} |
|---|
| 62 |
} |
|---|
| 63 |
_argument = c; |
|---|
| 64 |
if (a.argument == Required) { |
|---|
| 65 |
if (arg >= argc) |
|---|
| 66 |
throw exception(string("expected parameter to argument '-") + c + "'"); |
|---|
| 67 |
value = argv[arg++]; |
|---|
| 68 |
} |
|---|
| 69 |
_type = Argument; |
|---|
| 70 |
return true; |
|---|
| 71 |
} |
|---|
| 72 |
} |
|---|
| 73 |
} |
|---|
| 74 |
value = argv[arg++]; |
|---|
| 75 |
return true; |
|---|
| 76 |
} |
|---|
| 77 |
|
|---|
| 78 |
// check options |
|---|
| 79 |
if (argv[arg][0] == '-') { |
|---|
| 80 |
for (vector<CommandArgs::Arg>::iterator i = cmdarg->args.begin(); i != cmdarg->args.end(); i++) { |
|---|
| 81 |
CommandArgs::Arg a = (*i); |
|---|
| 82 |
|
|---|
| 83 |
// long arg? |
|---|
| 84 |
if (argv[arg][1] == '-') { |
|---|
| 85 |
if (!a.longarg.compare(argv[arg] + 2)) { |
|---|
| 86 |
_argument = a.shortarg; |
|---|
| 87 |
arg++; |
|---|
| 88 |
if (a.argument == Required) { |
|---|
| 89 |
if (arg >= argc) |
|---|
| 90 |
throw exception(string("expected parameter to argument '--") + a.longarg + "'"); |
|---|
| 91 |
value = argv[arg++]; |
|---|
| 92 |
} else // optional argument present? |
|---|
| 93 |
if (a.argument == Optional && arg < argc && argv[arg][0] != '-') { |
|---|
| 94 |
value = argv[arg]; |
|---|
| 95 |
arg++; |
|---|
| 96 |
} |
|---|
| 97 |
_type = Argument; |
|---|
| 98 |
return true; |
|---|
| 99 |
} |
|---|
| 100 |
// short arg? |
|---|
| 101 |
} else { |
|---|
| 102 |
if (a.shortarg == argv[arg][1]) { |
|---|
| 103 |
char c = argv[arg][1]; |
|---|
| 104 |
|
|---|
| 105 |
if (a.argument == Required && argv[arg][2] != 0) { |
|---|
| 106 |
_argument = c; |
|---|
| 107 |
_type = Argument; |
|---|
| 108 |
value = argv[arg] + 2; |
|---|
| 109 |
inshort = 0; |
|---|
| 110 |
arg++; |
|---|
| 111 |
return true; |
|---|
| 112 |
} else { |
|---|
| 113 |
inshort = 2; |
|---|
| 114 |
// next argument? |
|---|
| 115 |
if (argv[arg][inshort] == 0) { |
|---|
| 116 |
inshort = 0; |
|---|
| 117 |
arg++; |
|---|
| 118 |
// optional argument present? |
|---|
| 119 |
if (arg < argc && a.argument == Optional && argv[arg][0] != '-') { |
|---|
| 120 |
value = argv[arg]; |
|---|
| 121 |
arg++; |
|---|
| 122 |
} |
|---|
| 123 |
} |
|---|
| 124 |
_argument = c; |
|---|
| 125 |
if (a.argument == Required) { |
|---|
| 126 |
if (arg >= argc) |
|---|
| 127 |
throw exception(string("expected parameter to argument '") + c + "'"); |
|---|
| 128 |
value = argv[arg++]; |
|---|
| 129 |
} |
|---|
| 130 |
_type = Argument; |
|---|
| 131 |
return true; |
|---|
| 132 |
} |
|---|
| 133 |
} |
|---|
| 134 |
} |
|---|
| 135 |
} |
|---|
| 136 |
value = argv[arg++]; |
|---|
| 137 |
return true; |
|---|
| 138 |
} else { |
|---|
| 139 |
_type = Unknown; |
|---|
| 140 |
value = argv[arg++]; |
|---|
| 141 |
_argument = 0; |
|---|
| 142 |
} |
|---|
| 143 |
return true; |
|---|
| 144 |
} |
|---|
| 145 |
|
|---|
| 146 |
void CommandArgs::displayHelp(ostream &out, int termwidth) { |
|---|
| 147 |
unsigned max = 0; |
|---|
| 148 |
|
|---|
| 149 |
// calculate widest argument |
|---|
| 150 |
for (vector<CommandArgs::Arg>::iterator i = args.begin(); i != args.end(); i++) { |
|---|
| 151 |
Arg &arg = *i; |
|---|
| 152 |
string tmp; |
|---|
| 153 |
|
|---|
| 154 |
if (arg.help == "") continue; |
|---|
| 155 |
|
|---|
| 156 |
if (arg.shortarg > 0) { |
|---|
| 157 |
tmp += '-'; |
|---|
| 158 |
tmp += (char)arg.shortarg; |
|---|
| 159 |
} |
|---|
| 160 |
if (arg.longarg != "") { |
|---|
| 161 |
if (tmp != "") tmp += ", "; |
|---|
| 162 |
tmp += "--" + arg.longarg; |
|---|
| 163 |
} |
|---|
| 164 |
if (arg.argument == Required) { |
|---|
| 165 |
tmp += " ARG"; |
|---|
| 166 |
} else |
|---|
| 167 |
if (arg.argument == Optional) { |
|---|
| 168 |
tmp += " [ARG]"; |
|---|
| 169 |
} |
|---|
| 170 |
if (max < tmp.size()) max = tmp.size(); |
|---|
| 171 |
} |
|---|
| 172 |
|
|---|
| 173 |
for (vector<CommandArgs::Arg>::iterator i = args.begin(); i != args.end(); i++) { |
|---|
| 174 |
Arg &arg = *i; |
|---|
| 175 |
string tmp; |
|---|
| 176 |
|
|---|
| 177 |
if (arg.help == "") continue; |
|---|
| 178 |
|
|---|
| 179 |
if (arg.shortarg > 0) { |
|---|
| 180 |
tmp += '-'; |
|---|
| 181 |
tmp += (char)arg.shortarg; |
|---|
| 182 |
} |
|---|
| 183 |
if (arg.longarg != "") { |
|---|
| 184 |
if (tmp != "") tmp += ", "; |
|---|
| 185 |
tmp += "--" + arg.longarg; |
|---|
| 186 |
} |
|---|
| 187 |
if (arg.argument == Required) { |
|---|
| 188 |
tmp += " ARG"; |
|---|
| 189 |
} else |
|---|
| 190 |
if (arg.argument == Optional) { |
|---|
| 191 |
tmp += " [ARG]"; |
|---|
| 192 |
} |
|---|
| 193 |
out << tmp; |
|---|
| 194 |
str::wraptext(out, arg.help, max + 2, tmp.size(), termwidth); |
|---|
| 195 |
out << endl; |
|---|
| 196 |
} |
|---|
| 197 |
} |
|---|
| 198 |
string const &CommandArgs::iterator::longOption() const { |
|---|
| 199 |
assert(cmdarg); |
|---|
| 200 |
for (vector<CommandArgs::Arg>::iterator i = cmdarg->args.begin(); !(i == cmdarg->args.end()); ++i) |
|---|
| 201 |
if (_argument == (*i).shortarg) |
|---|
| 202 |
return (*i).longarg; |
|---|
| 203 |
throw exception("unknown option index '" + str::stringify(_argument) + "'"); |
|---|
| 204 |
} |
|---|