lilypond-0.1.15
[lilypond.git] / flower / lgetopt.cc
blob8e9fd408ddb85a590e7a87aed72aa9a11c51ba3f
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();
177 if (!ok ())
178 return 0;
180 if (argument_index_i_)
181 return parseshort();
183 const char * argument_C = arg_value_ch_a_a_[array_index_i_];
185 if (argument_C[0] != '-')
186 return 0;
188 if (argument_C[1] == '-') {// what to do with "command -- bla"
189 if (argument_C[2])
190 return parselong();
191 else
192 return 0;
194 else
196 if (argument_C[ 1 ])
198 argument_index_i_ = 1;
199 return parseshort();
201 else
203 return 0;
208 Getopt_long::Getopt_long (int c, char **v, Long_option_init *lo)
210 option_a_ = lo;
211 error_ostream_l_ = &cerr;
212 arg_value_ch_a_a_ = v;
213 argument_count_i_ = c;
214 array_index_i_ = 1;
215 argument_index_i_ = 0;
217 // reached end of option table?
218 table_len_i_ =0;
219 for (int i = 0; option_a_[i].longname ||option_a_[i].shortname; i++)
220 table_len_i_ ++;
223 bool
224 Getopt_long::ok() const
226 return array_index_i_ < argument_count_i_;
229 void
230 Getopt_long::next()
232 error_ = E_NOERROR;
233 while (array_index_i_ < argument_count_i_
234 && !arg_value_ch_a_a_[array_index_i_][argument_index_i_])
236 array_index_i_++;
237 argument_index_i_ = 0;
241 char const *
242 Getopt_long::current_arg()
244 if (array_index_i_ >= argument_count_i_)
245 return 0;
246 char const * a = arg_value_ch_a_a_[array_index_i_];
247 return a + argument_index_i_;
250 char const *
251 Getopt_long::get_next_arg()
253 char const * a = current_arg();
254 if (a)
256 array_index_i_ ++;
257 argument_index_i_= 0;
259 return a;