lilypond-0.1.12
[lilypond.git] / flower / lgetopt.cc
blobf0a49ab3602c4bd5af1a52a3199b857ae2bcf581
1 /*
2 process command line, GNU style.
4 this is (Copyleft) 1996, Han-Wen Nienhuys, <hanwen@stack.nl>
5 */
6 #include <stdio.h>
7 #include <iostream.h>
8 #include <assert.h>
9 #include "lgetopt.hh"
11 long
12 Getopt_long::argument_to_i()
14 long l;
15 if (!optional_argument_ch_C_
16 || sscanf (optional_argument_ch_C_, "%ld", &l) != 1)
17 report (E_ILLEGALARG);
19 return l;
22 const Long_option_init *
23 Getopt_long::parselong()
25 char const *optnm = arg_value_ch_a_a_[array_index_i_] + 2 ;
26 assert (*optnm);
28 char const *endopt = strchr (optnm, '=');
29 int searchlen = (endopt) ? endopt - optnm : strlen (optnm);
31 found_option_l_=0;
32 for (int i=0; i< table_len_i_; i++)
34 char const *ln = option_a_[i].longname;
36 if (ln && !strncmp (ln, optnm, searchlen))
38 found_option_l_ = option_a_+i;
39 break;
43 if (!found_option_l_)
45 report (E_UNKNOWNOPTION);
46 return 0;
48 array_index_i_++;
49 argument_index_i_ = 0;
52 if (found_option_l_->take_arg)
54 if (endopt)
55 optional_argument_ch_C_ = endopt +1; // a '='
56 else
58 optional_argument_ch_C_ = arg_value_ch_a_a_[array_index_i_];
59 array_index_i_++;
61 if (!optional_argument_ch_C_)
62 report (E_ARGEXPECT);
65 else
67 optional_argument_ch_C_ = 0;
68 if (endopt)
69 report (E_NOARGEXPECT);
72 return found_option_l_;
76 void
77 Long_option_init::printon (ostream &errorout) const
79 if (shortname)
80 errorout <<"-" << shortname;
81 if (shortname && longname)
82 errorout << ", ";
83 if (longname)
84 errorout << "`--" << longname << "'";
87 // report an error, GNU style.
88 void
89 Getopt_long::report (Errorcod c)
91 error_ = c;
92 if (!error_ostream_l_)
93 return;
95 *error_ostream_l_ << arg_value_ch_a_a_[0] << ": ";
96 switch (c)
98 case E_ARGEXPECT:
99 *error_ostream_l_<< "option ";
100 found_option_l_->printon (*error_ostream_l_);
101 *error_ostream_l_ << "requires an argument"<<endl;
102 break;
103 case E_NOARGEXPECT:
104 *error_ostream_l_ << "option `--" <<
105 found_option_l_->longname << "' does not allow an argument"<<endl;
106 break;
108 case E_UNKNOWNOPTION:
109 *error_ostream_l_ << "unrecognized option ";
110 if (argument_index_i_)
111 *error_ostream_l_ << "-" << arg_value_ch_a_a_[array_index_i_][argument_index_i_] << endl;
112 else
113 *error_ostream_l_ << arg_value_ch_a_a_[array_index_i_] << endl;
115 break;
116 case E_ILLEGALARG:
117 *error_ostream_l_ << "illegal argument `" << optional_argument_ch_C_ << "\'to option ";
118 found_option_l_->printon (*error_ostream_l_);
119 *error_ostream_l_ << '\n';
120 default:
121 assert (false);
123 exit (2);
126 const Long_option_init *
127 Getopt_long::parseshort()
129 char c=arg_value_ch_a_a_[array_index_i_][argument_index_i_];
130 found_option_l_=0;
131 assert (c);
133 for (int i=0; i < table_len_i_; i++)
134 if (option_a_[i].shortname == c)
136 found_option_l_ = option_a_+i;
137 break;
140 if (!found_option_l_)
142 report (E_UNKNOWNOPTION);
143 return 0;
146 argument_index_i_++;
147 if (!found_option_l_->take_arg)
149 optional_argument_ch_C_ = 0;
150 return found_option_l_;
152 optional_argument_ch_C_ = arg_value_ch_a_a_[array_index_i_] + argument_index_i_;
154 array_index_i_ ++;
155 argument_index_i_ = 0;
157 if (!optional_argument_ch_C_[0])
159 optional_argument_ch_C_ = arg_value_ch_a_a_[array_index_i_];
160 array_index_i_ ++;
162 if (!optional_argument_ch_C_)
164 report (E_ARGEXPECT);
167 return found_option_l_;
170 const Long_option_init *
171 Getopt_long::operator()()
173 if (!ok())
174 return 0;
176 next();
178 if (argument_index_i_)
179 return parseshort();
181 const char * argument_C = arg_value_ch_a_a_[array_index_i_];
183 if (argument_C[0] != '-')
184 return 0;
186 if (argument_C[1] == '-') {// what to do with "command -- bla"
187 if ( argument_C[2])
188 return parselong();
189 else
190 return 0;
192 else
194 if (argument_C[ 1 ])
196 argument_index_i_ = 1;
197 return parseshort();
199 else
201 return 0;
206 Getopt_long::Getopt_long (int c, char **v, Long_option_init *lo)
208 option_a_ = lo;
209 error_ostream_l_ = &cerr;
210 arg_value_ch_a_a_ = v;
211 argument_count_i_ = c;
212 array_index_i_ = 1;
213 argument_index_i_ = 0;
215 // reached end of option table?
216 table_len_i_ =0;
217 for (int i = 0; option_a_[i].longname ||option_a_[i].shortname; i++)
218 table_len_i_ ++;
221 bool
222 Getopt_long::ok() const
224 return array_index_i_ < argument_count_i_;
227 void
228 Getopt_long::next()
230 error_ = E_NOERROR;
231 while (array_index_i_ < argument_count_i_
232 && !arg_value_ch_a_a_[array_index_i_][argument_index_i_])
234 array_index_i_++;
235 argument_index_i_ = 0;
239 char const *
240 Getopt_long::current_arg()
242 if (array_index_i_ >= argument_count_i_)
243 return 0;
244 char const * a = arg_value_ch_a_a_[array_index_i_];
245 return a + argument_index_i_;
248 char const *
249 Getopt_long::get_next_arg()
251 char const * a = current_arg();
252 if (a)
254 array_index_i_ ++;
255 argument_index_i_= 0;
257 return a;