root/todo/tags/0.1.20/util/CommandArgs.cc

Revision 290, 4.9 kB (checked in by athomas, 4 years ago)

Initial import.

Line 
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 }
Note: See TracBrowser for help on using the browser.