*** empty log message ***
[h316.git] / pc-tools / ldc2 / src / configuration_manager.cpp
CommitLineData
ca5fce3a 1#include "configuration_manager.hh"
ad324d29 2#include <stdio.h>
3
4/*!
5 *\brief Constructor.
6 *
ca5fce3a 7 * This constructor makes a new configuration_manager ready to use.
ad324d29 8 *\arg name Name of the application as mentioned in the
9 * "Use: <appname> ..." help message.
10 */
ca5fce3a 11configuration_manager::configuration_manager(string name){
040533c5 12 app_name=name;
ad324d29 13}
14
15
16/*!
ca5fce3a 17 *\brief Add a new configuration value to be searched for.
ad324d29 18 *\param shortname A character for the short form.
ca5fce3a 19 * For example the h in -h
ad324d29 20 *\param longname The double dash longname. For example
ca5fce3a 21 * input_file in --input_file= or
22 *\param description A detailed description of the value.
ad324d29 23 *\param status Pointer to an integer. Will be set to 1 if arg found.
ca5fce3a 24 *\target Pointer to to string to put the value in.
ad324d29 25 *\placeholder A placeholder for the documentation.
ca5fce3a 26 * For example <filename> in -f<filename>
ad324d29 27 */
ca5fce3a 28void configuration_manager::add_option_value (string shortname, string longname,
040533c5 29 string description,
30 bool allow_cmdline,
31 bool allow_conffile,
32 int * status,
ad324d29 33 string * target, string placeholder){
34
ca5fce3a 35 if(status!=NULL) option_values.insert(opt_v.end(),
36 opt_value_t(shortname,longname, description,
ad324d29 37 status,target,placeholder)
38 );
39}
40
41
42/*!
43 *\brief Add an accepted argument to the argument reader.
44 *\param placeholder Something like "<input-file>".
45 *\param description Text describing the argument.
46 *\param status A pointer to a status variable. Will be set to 0 immediately.
47 * If the argument is filled in, it will be set to 1.
48 *\param target A pointer to a c++ string where the argument goes to.
49 *
50 *\note Arguments are filled in the order of adding them to the
51 * argument reader.
52 * There would be no other way to determine the order.
53 */
ca5fce3a 54void configuration_manager::add_argument(string placeholder, string description, int * status, string * target){
ad324d29 55 if (target!=NULL) if(status!=NULL)
56 arg_v.insert(arg_v.end(),arg_t(placeholder,description,status,target));
57}
58
59
60/*!
61 *\Read in the args passed to main().
62 *\returns empty vector on success or the error messages to be output.
63 */
ca5fce3a 64vector<string> configuration_manager::read_args(int argc, char ** args){
ad324d29 65 vector<string> result;
66 vector<string> argv;
67 for (char ** akt=args; *akt ;akt++) argv.insert(argv.end(),string(*akt));
68
69 unsigned int free_parms_count=0;
70 for (vector<string>::iterator akt_p=argv.begin()+1;akt_p<argv.end();akt_p++){ //Argument loop
71
72 // Look for long argument
73 if ((akt_p->substr(0,2)=="--")&&(free_parms_count==0)){
74 int found=0;
75 for (vector<opt_t>::iterator parm_p=opt_v.begin();parm_p<opt_v.end();parm_p++){
76 if (akt_p->substr(2,parm_p->longname.length())==parm_p->longname){
77 found=1;
78 *(parm_p->status)=1;
79 if (parm_p->target){
80 if (akt_p->length()>2+parm_p->longname.length()){
81 *(parm_p->target)=akt_p->substr(2+parm_p->longname.length());
82
83 } else // Word not long enough
84 if (akt_p+1<argv.end()) { // If next word existend
85 *(parm_p->status)=1;
86 *(parm_p->target)=*(++akt_p);
87 } else { // No next word :-(
88 result.insert(result.end(),
89 "Parameter --"+parm_p->longname+parm_p->placeholder+" needs an Argument!");
90 }
91 } // arg needed
92 }
93 } // search for loop
94 if (!found) result.insert(result.end(),"Unknown parameter: "+*akt_p);
95 } else { // No -- param, now look for switches
96 if (((*akt_p)[0]=='-')&&(free_parms_count==0)){
97 int stop_char_loop=0;
98 for (unsigned int pos=1; pos<akt_p->length()&& !stop_char_loop ;pos++){
99 int found=0;
100 for (vector<opt_t>::iterator parm_p=opt_v.begin();parm_p<opt_v.end();parm_p++){
101 if (parm_p->shortname[0]==(*akt_p)[pos]){
102 found=1;
103 (*parm_p->status)=1;
104 if (parm_p->target){ // Need argument
105 if (akt_p->length()>pos+1){
106 *(parm_p->target)=akt_p->substr(pos+1);
107 stop_char_loop=1;
108 } else { // Word not long enough
109 if (akt_p+1<argv.end()) { // If next word existend
110 *(parm_p->target)=*(++akt_p);
111 stop_char_loop=1;
112 } else { // No next word :-(
113 result.insert(result.end(),
114 "Parameter --"+parm_p->longname+parm_p->placeholder+" needs an Argument!");
115 }
116 }
117 } // arg needed
118 } //if match
119 } //args loop
120 if (!found) result.insert(result.end(),"Unknown switch: "+akt_p->substr(pos,1));
121 } // char loop
122 }// switch found
123 else{ // no switch found
124 if (free_parms_count<arg_v.size()){
125 *(arg_v[free_parms_count].target)=*akt_p;
126 *(arg_v[free_parms_count].status)=1;
127 }
128 free_parms_count++;
129 }
130 } //looking for not -- args
131 } // argv loop
132 if (free_parms_count>arg_v.size()) result.insert(result.begin(),"Too many arguments!");
133 if (!result.empty()){
134 result.insert(result.begin(),"Error!");
135 result.insert(result.begin(),"");
136 }
137 return result;
138}
139
140/*!
141 *\brief Generate help.
142 *\arg target Reference to a vector<string> to which lots of helpful
143 * strings are appended.
144 */
ca5fce3a 145void configuration_manager::get_help(vector<string> & target){
ad324d29 146 target.insert(target.end(),"");
147 string line="Usage: "+app_name;
148 for (vector<opt_t>::iterator parm_p=opt_v.begin();parm_p<opt_v.end();parm_p++){
149 string addstr=" [-"+parm_p->shortname;
150 if (parm_p->target!=0) addstr+=parm_p->placeholder;
151 addstr+="]";
152 if (line.length()+addstr.length()>79){
153 target.insert(target.end(),line);
154 line=string(7+app_name.length(),' ');
155 }
156 line+=addstr;
157 }
158
159 for (vector<arg_t>::iterator parm_p=arg_v.begin();parm_p<arg_v.end();parm_p++){
160 if (line.length()+parm_p->placeholder.length()>79){
161 target.insert(target.end(),line);
162 line=string(7+app_name.length(),' ');
163 }
164 line+=" ["+parm_p->placeholder+"]";
165 }
166 target.insert(target.end(),line);
167
168 /*******************************/
169
170 vector<string> left,right;
171 for (vector<opt_t>::iterator parm_p=opt_v.begin();parm_p<opt_v.end();parm_p++){
172 line=parm_p->description;
173 string st2=" -"+parm_p->shortname;
174 if (parm_p->target)st2+=" "+parm_p->placeholder;
175 st2+=", --"+parm_p->longname;
176 if (parm_p->target)st2+=parm_p->placeholder;
177 left.insert(left.end(),st2);
178 right.insert(right.end(),line);
179 }
180
181 for (vector<arg_t>::iterator parm_p=arg_v.begin();parm_p<arg_v.end();parm_p++){
182 string st2;
183 line=parm_p->description;
184 st2+=" "+parm_p->placeholder;
185 left.insert(left.end(),st2);
186 right.insert(right.end(),line);
187 }
188
189 if (opt_v.size()){
190 target.insert(target.end(),"");
191 target.insert(target.end(),"Options:");
192 }
193
194 unsigned int max_width=0;
195 for (unsigned int c=0; c<opt_v.size();c++)
196 if(left[c].length()>max_width) max_width=left[c].length();
197 for (unsigned int c=0; c<opt_v.size();c++){
198 string nl(max_width,' ');
199 nl.replace(0,left[c].length(),left[c]);
200 nl+=" "+right[c];
201 while (nl.length()>80){ // Too long???
202 int limit=nl.find_last_of(' ',80);
203 target.insert(target.end(),nl.substr(0,limit));
204 nl=string(max_width+2,' ')+nl.substr(limit+1);
205 }
206 target.insert(target.end(),nl);
207 }
208
209 if (arg_v.size()){
210 target.insert(target.end(),"");
211 target.insert(target.end(),"Arguments:");
212 }
213
214 max_width=0;
215 for (unsigned int c=opt_v.size(); c<opt_v.size()+arg_v.size();c++)
216 if(left[c].length()>max_width) max_width=left[c].length();
217 for (unsigned int c=opt_v.size(); c<opt_v.size()+arg_v.size();c++){
218 string nl(max_width,' ');
219 nl.replace(0,left[c].length(),left[c]);
220 nl+=" "+right[c];
221
222 while (nl.length()>80){ // Too long???
223 int limit=nl.find_last_of(' ',80);
224 printf("limit:%i\n",limit);
225 target.insert(target.end(),nl.substr(0,limit));
226 nl=string(max_width+2,' ')+nl.substr(limit+1);
227 }
228
229 target.insert(target.end(),nl);
230 }
231 target.insert(target.end(),"");
232}
233
234/*!
235 *\brief Generate help.
236 *\return A vector containing many helpful strings for the user.
237 */
ca5fce3a 238vector<string> configuration_manager::get_help(){
ad324d29 239 vector<string> result;
240 get_help(result);
241 return result;
242}
243
244
245/**************************************************/
246
ca5fce3a 247configuration_manager::opt_t::opt_t(string n_shortname, string n_longname,string n_description, int * n_status,
ad324d29 248 string * n_target, string n_placeholder){
249 shortname=n_shortname;
250 longname=n_longname;
251 description=n_description;
252 status=n_status;
253 target=n_target;
254 placeholder=n_placeholder;
255 if (status) *status=0;
256}
257
ca5fce3a 258configuration_manager::arg_t::arg_t( string n_placeholder, string n_description,
ad324d29 259 int * n_status, string * n_target){
260 description=n_description;
261 status=n_status;
262 target=n_target;
263 placeholder=n_placeholder;
264 if (status) *status=0;
265}