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
,
31 string description
, int * status
,
32 string
* target
, string placeholder
){
34 if(status
!=NULL
) opt_v
.insert(opt_v
.end(),
35 opt_t(shortname
,longname
, description
,
36 status
,target
,placeholder
)
42 *\brief Add an accepted argument to the argument reader.
43 *\param placeholder Something like "<input-file>".
44 *\param description Text describing the argument.
45 *\param status A pointer to a status variable. Will be set to 0 immediately.
46 * If the argument is filled in, it will be set to 1.
47 *\param target A pointer to a c++ string where the argument goes to.
49 *\note Arguments are filled in the order of adding them to the
51 * There would be no other way to determine the order.
53 void argument_reader::add_argument(string placeholder
, string description
, int * status
, string
* target
){
54 if (target
!=NULL
) if(status
!=NULL
)
55 arg_v
.insert(arg_v
.end(),arg_t(placeholder
,description
,status
,target
));
60 *\Read in the args passed to main().
61 *\returns empty vector on success or the error messages to be output.
63 vector
<string
> argument_reader::read_args(int argc
, char ** args
){
64 vector
<string
> result
;
66 for (char ** akt
=args
; *akt
;akt
++) argv
.insert(argv
.end(),string(*akt
));
68 unsigned int free_parms_count
=0;
69 for (vector
<string
>::iterator akt_p
=argv
.begin()+1;akt_p
<argv
.end();akt_p
++){ //Argument loop
71 // Look for long argument
72 if ((akt_p
->substr(0,2)=="--")&&(free_parms_count
==0)){
74 for (vector
<opt_t
>::iterator parm_p
=opt_v
.begin();parm_p
<opt_v
.end();parm_p
++){
75 if (akt_p
->substr(2,parm_p
->longname
.length())==parm_p
->longname
){
79 if (akt_p
->length()>2+parm_p
->longname
.length()){
80 *(parm_p
->target
)=akt_p
->substr(2+parm_p
->longname
.length());
82 } else // Word not long enough
83 if (akt_p
+1<argv
.end()) { // If next word existend
85 *(parm_p
->target
)=*(++akt_p
);
86 } else { // No next word :-(
87 result
.insert(result
.end(),
88 "Parameter --"+parm_p
->longname
+parm_p
->placeholder
+" needs an Argument!");
93 if (!found
) result
.insert(result
.end(),"Unknown parameter: "+*akt_p
);
94 } else { // No -- param, now look for switches
95 if (((*akt_p
)[0]=='-')&&(free_parms_count
==0)){
97 for (unsigned int pos
=1; pos
<akt_p
->length()&& !stop_char_loop
;pos
++){
99 for (vector
<opt_t
>::iterator parm_p
=opt_v
.begin();parm_p
<opt_v
.end();parm_p
++){
100 if (parm_p
->shortname
[0]==(*akt_p
)[pos
]){
103 if (parm_p
->target
){ // Need argument
104 if (akt_p
->length()>pos
+1){
105 *(parm_p
->target
)=akt_p
->substr(pos
+1);
107 } else { // Word not long enough
108 if (akt_p
+1<argv
.end()) { // If next word existend
109 *(parm_p
->target
)=*(++akt_p
);
111 } else { // No next word :-(
112 result
.insert(result
.end(),
113 "Parameter --"+parm_p
->longname
+parm_p
->placeholder
+" needs an Argument!");
119 if (!found
) result
.insert(result
.end(),"Unknown switch: "+akt_p
->substr(pos
,1));
122 else{ // no switch found
123 if (free_parms_count
<arg_v
.size()){
124 *(arg_v
[free_parms_count
].target
)=*akt_p
;
125 *(arg_v
[free_parms_count
].status
)=1;
129 } //looking for not -- args
131 if (free_parms_count
>arg_v
.size()) result
.insert(result
.begin(),"Too many arguments!");
132 if (!result
.empty()){
133 result
.insert(result
.begin(),"Error!");
134 result
.insert(result
.begin(),"");
140 *\brief Generate help.
141 *\arg target Reference to a vector<string> to which lots of helpful
142 * strings are appended.
144 void argument_reader::get_help(vector
<string
> & target
){
145 target
.insert(target
.end(),"");
146 string line
="Usage: "+app_name
;
147 for (vector
<opt_t
>::iterator parm_p
=opt_v
.begin();parm_p
<opt_v
.end();parm_p
++){
148 string addstr
=" [-"+parm_p
->shortname
;
149 if (parm_p
->target
!=0) addstr
+=parm_p
->placeholder
;
151 if (line
.length()+addstr
.length()>79){
152 target
.insert(target
.end(),line
);
153 line
=string(7+app_name
.length(),' ');
158 for (vector
<arg_t
>::iterator parm_p
=arg_v
.begin();parm_p
<arg_v
.end();parm_p
++){
159 if (line
.length()+parm_p
->placeholder
.length()>79){
160 target
.insert(target
.end(),line
);
161 line
=string(7+app_name
.length(),' ');
163 line
+=" ["+parm_p
->placeholder
+"]";
165 target
.insert(target
.end(),line
);
167 /*******************************/
169 vector
<string
> left
,right
;
170 for (vector
<opt_t
>::iterator parm_p
=opt_v
.begin();parm_p
<opt_v
.end();parm_p
++){
171 line
=parm_p
->description
;
172 string st2
=" -"+parm_p
->shortname
;
173 if (parm_p
->target
)st2
+=" "+parm_p
->placeholder
;
174 st2
+=", --"+parm_p
->longname
;
175 if (parm_p
->target
)st2
+=parm_p
->placeholder
;
176 left
.insert(left
.end(),st2
);
177 right
.insert(right
.end(),line
);
180 for (vector
<arg_t
>::iterator parm_p
=arg_v
.begin();parm_p
<arg_v
.end();parm_p
++){
182 line
=parm_p
->description
;
183 st2
+=" "+parm_p
->placeholder
;
184 left
.insert(left
.end(),st2
);
185 right
.insert(right
.end(),line
);
189 target
.insert(target
.end(),"");
190 target
.insert(target
.end(),"Options:");
193 unsigned int max_width
=0;
194 for (unsigned int c
=0; c
<opt_v
.size();c
++)
195 if(left
[c
].length()>max_width
) max_width
=left
[c
].length();
196 for (unsigned int c
=0; c
<opt_v
.size();c
++){
197 string
nl(max_width
,' ');
198 nl
.replace(0,left
[c
].length(),left
[c
]);
200 while (nl
.length()>80){ // Too long???
201 int limit
=nl
.find_last_of(' ',80);
202 target
.insert(target
.end(),nl
.substr(0,limit
));
203 nl
=string(max_width
+2,' ')+nl
.substr(limit
+1);
205 target
.insert(target
.end(),nl
);
209 target
.insert(target
.end(),"");
210 target
.insert(target
.end(),"Arguments:");
214 for (unsigned int c
=opt_v
.size(); c
<opt_v
.size()+arg_v
.size();c
++)
215 if(left
[c
].length()>max_width
) max_width
=left
[c
].length();
216 for (unsigned int c
=opt_v
.size(); c
<opt_v
.size()+arg_v
.size();c
++){
217 string
nl(max_width
,' ');
218 nl
.replace(0,left
[c
].length(),left
[c
]);
221 while (nl
.length()>80){ // Too long???
222 int limit
=nl
.find_last_of(' ',80);
223 printf("limit:%i\n",limit
);
224 target
.insert(target
.end(),nl
.substr(0,limit
));
225 nl
=string(max_width
+2,' ')+nl
.substr(limit
+1);
228 target
.insert(target
.end(),nl
);
230 target
.insert(target
.end(),"");
234 *\brief Generate help.
235 *\return A vector containing many helpful strings for the user.
237 vector
<string
> argument_reader::get_help(){
238 vector
<string
> result
;
244 /**************************************************/
246 argument_reader::opt_t::opt_t(string n_shortname
, string n_longname
,string n_description
, int * n_status
,
247 string
* n_target
, string n_placeholder
){
248 shortname
=n_shortname
;
250 description
=n_description
;
253 placeholder
=n_placeholder
;
254 if (status
) *status
=0;
257 argument_reader::arg_t::arg_t( string n_placeholder
, string n_description
,
258 int * n_status
, string
* n_target
){
259 description
=n_description
;
262 placeholder
=n_placeholder
;
263 if (status
) *status
=0;