1 #include "argument_reader.hh"
7 * This constructor makes a new argument_reader ready to use.
8 *\arg name Name of the application as mentioned in the
9 * "Use: <appname> ..." help message.
11 argument_reader::argument_reader(string name
){
17 *\brief Add a new parameter to be searched for.
18 *\param shortname A character for the short form.
19 * For example the 'h' in -h
20 *\param longname The double dash longname. For example
21 * "input_file=" in --input_file= or
22 * "ignore_errors" in --ignore--errors
23 *\param description A detailed parameter description.
24 *\param status Pointer to an integer. Will be set to 1 if arg found.
25 *\target Pointer to a value should be read.
26 * If no value is needed, pass NULL.
27 *\placeholder A placeholder for the documentation.
28 * For example "<filename>" in -f<filename>
30 void argument_reader::add_param (string shortname
, string longname
,
35 string
* target
, string placeholder
){
37 if(status
!=NULL
) opt_v
.insert(opt_v
.end(),
38 opt_t(shortname
,longname
, description
,
39 status
,target
,placeholder
)
45 *\brief Add an accepted argument to the argument reader.
46 *\param placeholder Something like "<input-file>".
47 *\param description Text describing the argument.
48 *\param status A pointer to a status variable. Will be set to 0 immediately.
49 * If the argument is filled in, it will be set to 1.
50 *\param target A pointer to a c++ string where the argument goes to.
52 *\note Arguments are filled in the order of adding them to the
54 * There would be no other way to determine the order.
56 void argument_reader::add_argument(string placeholder
, string description
, int * status
, string
* target
){
57 if (target
!=NULL
) if(status
!=NULL
)
58 arg_v
.insert(arg_v
.end(),arg_t(placeholder
,description
,status
,target
));
63 *\Read in the args passed to main().
64 *\returns empty vector on success or the error messages to be output.
66 vector
<string
> argument_reader::read_args(int argc
, char ** args
){
67 vector
<string
> result
;
69 for (char ** akt
=args
; *akt
;akt
++) argv
.insert(argv
.end(),string(*akt
));
71 unsigned int free_parms_count
=0;
72 for (vector
<string
>::iterator akt_p
=argv
.begin()+1;akt_p
<argv
.end();akt_p
++){ //Argument loop
74 // Look for long argument
75 if ((akt_p
->substr(0,2)=="--")&&(free_parms_count
==0)){
77 for (vector
<opt_t
>::iterator parm_p
=opt_v
.begin();parm_p
<opt_v
.end();parm_p
++){
78 if (akt_p
->substr(2,parm_p
->longname
.length())==parm_p
->longname
){
82 if (akt_p
->length()>2+parm_p
->longname
.length()){
83 *(parm_p
->target
)=akt_p
->substr(2+parm_p
->longname
.length());
85 } else // Word not long enough
86 if (akt_p
+1<argv
.end()) { // If next word existend
88 *(parm_p
->target
)=*(++akt_p
);
89 } else { // No next word :-(
90 result
.insert(result
.end(),
91 "Parameter --"+parm_p
->longname
+parm_p
->placeholder
+" needs an Argument!");
96 if (!found
) result
.insert(result
.end(),"Unknown parameter: "+*akt_p
);
97 } else { // No -- param, now look for switches
98 if (((*akt_p
)[0]=='-')&&(free_parms_count
==0)){
100 for (unsigned int pos
=1; pos
<akt_p
->length()&& !stop_char_loop
;pos
++){
102 for (vector
<opt_t
>::iterator parm_p
=opt_v
.begin();parm_p
<opt_v
.end();parm_p
++){
103 if (parm_p
->shortname
[0]==(*akt_p
)[pos
]){
106 if (parm_p
->target
){ // Need argument
107 if (akt_p
->length()>pos
+1){
108 *(parm_p
->target
)=akt_p
->substr(pos
+1);
110 } else { // Word not long enough
111 if (akt_p
+1<argv
.end()) { // If next word existend
112 *(parm_p
->target
)=*(++akt_p
);
114 } else { // No next word :-(
115 result
.insert(result
.end(),
116 "Parameter --"+parm_p
->longname
+parm_p
->placeholder
+" needs an Argument!");
122 if (!found
) result
.insert(result
.end(),"Unknown switch: "+akt_p
->substr(pos
,1));
125 else{ // no switch found
126 if (free_parms_count
<arg_v
.size()){
127 *(arg_v
[free_parms_count
].target
)=*akt_p
;
128 *(arg_v
[free_parms_count
].status
)=1;
132 } //looking for not -- args
134 if (free_parms_count
>arg_v
.size()) result
.insert(result
.begin(),"Too many arguments!");
135 if (!result
.empty()){
136 result
.insert(result
.begin(),"Error!");
137 result
.insert(result
.begin(),"");
143 *\brief Generate help.
144 *\arg target Reference to a vector<string> to which lots of helpful
145 * strings are appended.
147 void argument_reader::get_help(vector
<string
> & target
){
148 target
.insert(target
.end(),"");
149 string line
="Usage: "+app_name
;
150 for (vector
<opt_t
>::iterator parm_p
=opt_v
.begin();parm_p
<opt_v
.end();parm_p
++){
151 string addstr
=" [-"+parm_p
->shortname
;
152 if (parm_p
->target
!=0) addstr
+=parm_p
->placeholder
;
154 if (line
.length()+addstr
.length()>79){
155 target
.insert(target
.end(),line
);
156 line
=string(7+app_name
.length(),' ');
161 for (vector
<arg_t
>::iterator parm_p
=arg_v
.begin();parm_p
<arg_v
.end();parm_p
++){
162 if (line
.length()+parm_p
->placeholder
.length()>79){
163 target
.insert(target
.end(),line
);
164 line
=string(7+app_name
.length(),' ');
166 line
+=" ["+parm_p
->placeholder
+"]";
168 target
.insert(target
.end(),line
);
170 /*******************************/
172 vector
<string
> left
,right
;
173 for (vector
<opt_t
>::iterator parm_p
=opt_v
.begin();parm_p
<opt_v
.end();parm_p
++){
174 line
=parm_p
->description
;
175 string st2
=" -"+parm_p
->shortname
;
176 if (parm_p
->target
)st2
+=" "+parm_p
->placeholder
;
177 st2
+=", --"+parm_p
->longname
;
178 if (parm_p
->target
)st2
+=parm_p
->placeholder
;
179 left
.insert(left
.end(),st2
);
180 right
.insert(right
.end(),line
);
183 for (vector
<arg_t
>::iterator parm_p
=arg_v
.begin();parm_p
<arg_v
.end();parm_p
++){
185 line
=parm_p
->description
;
186 st2
+=" "+parm_p
->placeholder
;
187 left
.insert(left
.end(),st2
);
188 right
.insert(right
.end(),line
);
192 target
.insert(target
.end(),"");
193 target
.insert(target
.end(),"Options:");
196 unsigned int max_width
=0;
197 for (unsigned int c
=0; c
<opt_v
.size();c
++)
198 if(left
[c
].length()>max_width
) max_width
=left
[c
].length();
199 for (unsigned int c
=0; c
<opt_v
.size();c
++){
200 string
nl(max_width
,' ');
201 nl
.replace(0,left
[c
].length(),left
[c
]);
203 while (nl
.length()>80){ // Too long???
204 int limit
=nl
.find_last_of(' ',80);
205 target
.insert(target
.end(),nl
.substr(0,limit
));
206 nl
=string(max_width
+2,' ')+nl
.substr(limit
+1);
208 target
.insert(target
.end(),nl
);
212 target
.insert(target
.end(),"");
213 target
.insert(target
.end(),"Arguments:");
217 for (unsigned int c
=opt_v
.size(); c
<opt_v
.size()+arg_v
.size();c
++)
218 if(left
[c
].length()>max_width
) max_width
=left
[c
].length();
219 for (unsigned int c
=opt_v
.size(); c
<opt_v
.size()+arg_v
.size();c
++){
220 string
nl(max_width
,' ');
221 nl
.replace(0,left
[c
].length(),left
[c
]);
224 while (nl
.length()>80){ // Too long???
225 int limit
=nl
.find_last_of(' ',80);
226 printf("limit:%i\n",limit
);
227 target
.insert(target
.end(),nl
.substr(0,limit
));
228 nl
=string(max_width
+2,' ')+nl
.substr(limit
+1);
231 target
.insert(target
.end(),nl
);
233 target
.insert(target
.end(),"");
237 *\brief Generate help.
238 *\return A vector containing many helpful strings for the user.
240 vector
<string
> argument_reader::get_help(){
241 vector
<string
> result
;
247 /**************************************************/
249 argument_reader::opt_t::opt_t(string n_shortname
, string n_longname
,string n_description
, int * n_status
,
250 string
* n_target
, string n_placeholder
){
251 shortname
=n_shortname
;
253 description
=n_description
;
256 placeholder
=n_placeholder
;
257 if (status
) *status
=0;
260 argument_reader::arg_t::arg_t( string n_placeholder
, string n_description
,
261 int * n_status
, string
* n_target
){
262 description
=n_description
;
265 placeholder
=n_placeholder
;
266 if (status
) *status
=0;