f9241c173d12cd9c86f4f984a6ce6b1a2506a8fb
[h316.git] / pc-tools / ldc2 / src / configuration_manager.cpp
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 */
11 argument_reader::argument_reader(string name){
12 app_name=app_name;
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 */
30 void argument_reader::add_param (string shortname, string longname,
31 string description, int * status,
32 string * target, string placeholder){
33
34 if(status!=NULL) opt_v.insert(opt_v.end(),
35 opt_t(shortname,longname, description,
36 status,target,placeholder)
37 );
38 }
39
40
41 /*!
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.
48 *
49 *\note Arguments are filled in the order of adding them to the
50 * argument reader.
51 * There would be no other way to determine the order.
52 */
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));
56 }
57
58
59 /*!
60 *\Read in the args passed to main().
61 *\returns empty vector on success or the error messages to be output.
62 */
63 vector<string> argument_reader::read_args(int argc, char ** args){
64 vector<string> result;
65 vector<string> argv;
66 for (char ** akt=args; *akt ;akt++) argv.insert(argv.end(),string(*akt));
67
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
70
71 // Look for long argument
72 if ((akt_p->substr(0,2)=="--")&&(free_parms_count==0)){
73 int found=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){
76 found=1;
77 *(parm_p->status)=1;
78 if (parm_p->target){
79 if (akt_p->length()>2+parm_p->longname.length()){
80 *(parm_p->target)=akt_p->substr(2+parm_p->longname.length());
81
82 } else // Word not long enough
83 if (akt_p+1<argv.end()) { // If next word existend
84 *(parm_p->status)=1;
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!");
89 }
90 } // arg needed
91 }
92 } // search for loop
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)){
96 int stop_char_loop=0;
97 for (unsigned int pos=1; pos<akt_p->length()&& !stop_char_loop ;pos++){
98 int found=0;
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]){
101 found=1;
102 (*parm_p->status)=1;
103 if (parm_p->target){ // Need argument
104 if (akt_p->length()>pos+1){
105 *(parm_p->target)=akt_p->substr(pos+1);
106 stop_char_loop=1;
107 } else { // Word not long enough
108 if (akt_p+1<argv.end()) { // If next word existend
109 *(parm_p->target)=*(++akt_p);
110 stop_char_loop=1;
111 } else { // No next word :-(
112 result.insert(result.end(),
113 "Parameter --"+parm_p->longname+parm_p->placeholder+" needs an Argument!");
114 }
115 }
116 } // arg needed
117 } //if match
118 } //args loop
119 if (!found) result.insert(result.end(),"Unknown switch: "+akt_p->substr(pos,1));
120 } // char loop
121 }// switch found
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;
126 }
127 free_parms_count++;
128 }
129 } //looking for not -- args
130 } // argv loop
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(),"");
135 }
136 return result;
137 }
138
139 /*!
140 *\brief Generate help.
141 *\arg target Reference to a vector<string> to which lots of helpful
142 * strings are appended.
143 */
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;
150 addstr+="]";
151 if (line.length()+addstr.length()>79){
152 target.insert(target.end(),line);
153 line=string(7+app_name.length(),' ');
154 }
155 line+=addstr;
156 }
157
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(),' ');
162 }
163 line+=" ["+parm_p->placeholder+"]";
164 }
165 target.insert(target.end(),line);
166
167 /*******************************/
168
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);
178 }
179
180 for (vector<arg_t>::iterator parm_p=arg_v.begin();parm_p<arg_v.end();parm_p++){
181 string st2;
182 line=parm_p->description;
183 st2+=" "+parm_p->placeholder;
184 left.insert(left.end(),st2);
185 right.insert(right.end(),line);
186 }
187
188 if (opt_v.size()){
189 target.insert(target.end(),"");
190 target.insert(target.end(),"Options:");
191 }
192
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]);
199 nl+=" "+right[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);
204 }
205 target.insert(target.end(),nl);
206 }
207
208 if (arg_v.size()){
209 target.insert(target.end(),"");
210 target.insert(target.end(),"Arguments:");
211 }
212
213 max_width=0;
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]);
219 nl+=" "+right[c];
220
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);
226 }
227
228 target.insert(target.end(),nl);
229 }
230 target.insert(target.end(),"");
231 }
232
233 /*!
234 *\brief Generate help.
235 *\return A vector containing many helpful strings for the user.
236 */
237 vector<string> argument_reader::get_help(){
238 vector<string> result;
239 get_help(result);
240 return result;
241 }
242
243
244 /**************************************************/
245
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;
249 longname=n_longname;
250 description=n_description;
251 status=n_status;
252 target=n_target;
253 placeholder=n_placeholder;
254 if (status) *status=0;
255 }
256
257 argument_reader::arg_t::arg_t( string n_placeholder, string n_description,
258 int * n_status, string * n_target){
259 description=n_description;
260 status=n_status;
261 target=n_target;
262 placeholder=n_placeholder;
263 if (status) *status=0;
264 }