*** empty log message ***
[h316.git] / pc-tools / ldc2 / src / configuration_manager.cpp
CommitLineData
ad324d29 1#include "argument_reader.hh"
2#include <stdio.h>
3
4/*!
5 *\brief Constructor.
6 *
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.
10 */
11argument_reader::argument_reader(string name){
040533c5 12 app_name=name;
ad324d29 13}
14
15
16/*!
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>
29 */
30void argument_reader::add_param (string shortname, string longname,
040533c5 31 string description,
32 bool allow_cmdline,
33 bool allow_conffile,
34 int * status,
ad324d29 35 string * target, string placeholder){
36
37 if(status!=NULL) opt_v.insert(opt_v.end(),
38 opt_t(shortname,longname, description,
39 status,target,placeholder)
40 );
41}
42
43
44/*!
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.
51 *
52 *\note Arguments are filled in the order of adding them to the
53 * argument reader.
54 * There would be no other way to determine the order.
55 */
56void 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));
59}
60
61
62/*!
63 *\Read in the args passed to main().
64 *\returns empty vector on success or the error messages to be output.
65 */
66vector<string> argument_reader::read_args(int argc, char ** args){
67 vector<string> result;
68 vector<string> argv;
69 for (char ** akt=args; *akt ;akt++) argv.insert(argv.end(),string(*akt));
70
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
73
74 // Look for long argument
75 if ((akt_p->substr(0,2)=="--")&&(free_parms_count==0)){
76 int found=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){
79 found=1;
80 *(parm_p->status)=1;
81 if (parm_p->target){
82 if (akt_p->length()>2+parm_p->longname.length()){
83 *(parm_p->target)=akt_p->substr(2+parm_p->longname.length());
84
85 } else // Word not long enough
86 if (akt_p+1<argv.end()) { // If next word existend
87 *(parm_p->status)=1;
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!");
92 }
93 } // arg needed
94 }
95 } // search for loop
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)){
99 int stop_char_loop=0;
100 for (unsigned int pos=1; pos<akt_p->length()&& !stop_char_loop ;pos++){
101 int found=0;
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]){
104 found=1;
105 (*parm_p->status)=1;
106 if (parm_p->target){ // Need argument
107 if (akt_p->length()>pos+1){
108 *(parm_p->target)=akt_p->substr(pos+1);
109 stop_char_loop=1;
110 } else { // Word not long enough
111 if (akt_p+1<argv.end()) { // If next word existend
112 *(parm_p->target)=*(++akt_p);
113 stop_char_loop=1;
114 } else { // No next word :-(
115 result.insert(result.end(),
116 "Parameter --"+parm_p->longname+parm_p->placeholder+" needs an Argument!");
117 }
118 }
119 } // arg needed
120 } //if match
121 } //args loop
122 if (!found) result.insert(result.end(),"Unknown switch: "+akt_p->substr(pos,1));
123 } // char loop
124 }// switch found
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;
129 }
130 free_parms_count++;
131 }
132 } //looking for not -- args
133 } // argv loop
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(),"");
138 }
139 return result;
140}
141
142/*!
143 *\brief Generate help.
144 *\arg target Reference to a vector<string> to which lots of helpful
145 * strings are appended.
146 */
147void 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;
153 addstr+="]";
154 if (line.length()+addstr.length()>79){
155 target.insert(target.end(),line);
156 line=string(7+app_name.length(),' ');
157 }
158 line+=addstr;
159 }
160
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(),' ');
165 }
166 line+=" ["+parm_p->placeholder+"]";
167 }
168 target.insert(target.end(),line);
169
170 /*******************************/
171
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);
181 }
182
183 for (vector<arg_t>::iterator parm_p=arg_v.begin();parm_p<arg_v.end();parm_p++){
184 string st2;
185 line=parm_p->description;
186 st2+=" "+parm_p->placeholder;
187 left.insert(left.end(),st2);
188 right.insert(right.end(),line);
189 }
190
191 if (opt_v.size()){
192 target.insert(target.end(),"");
193 target.insert(target.end(),"Options:");
194 }
195
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]);
202 nl+=" "+right[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);
207 }
208 target.insert(target.end(),nl);
209 }
210
211 if (arg_v.size()){
212 target.insert(target.end(),"");
213 target.insert(target.end(),"Arguments:");
214 }
215
216 max_width=0;
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]);
222 nl+=" "+right[c];
223
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);
229 }
230
231 target.insert(target.end(),nl);
232 }
233 target.insert(target.end(),"");
234}
235
236/*!
237 *\brief Generate help.
238 *\return A vector containing many helpful strings for the user.
239 */
240vector<string> argument_reader::get_help(){
241 vector<string> result;
242 get_help(result);
243 return result;
244}
245
246
247/**************************************************/
248
249argument_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;
252 longname=n_longname;
253 description=n_description;
254 status=n_status;
255 target=n_target;
256 placeholder=n_placeholder;
257 if (status) *status=0;
258}
259
260argument_reader::arg_t::arg_t( string n_placeholder, string n_description,
261 int * n_status, string * n_target){
262 description=n_description;
263 status=n_status;
264 target=n_target;
265 placeholder=n_placeholder;
266 if (status) *status=0;
267}