2 process command line, GNU style.
4 this is (Copyleft) 1996, Han-Wen Nienhuys, <hanwen@cs.uu.nl>
11 #include "getopt-long.hh"
12 #include "international.hh"
13 #include "string-convert.hh"
17 gettext (char const* s)
26 Getopt_long::argument_to_i()
29 if (!optional_argument_ch_C_
30 || sscanf (optional_argument_ch_C_, "%ld", &l) != 1)
31 report (E_ILLEGALARG);
36 const Long_option_init *
37 Getopt_long::parselong()
39 char const *optnm = arg_value_ch_a_a_[array_index_i_] + 2 ;
42 char const *endopt = strchr (optnm, '=');
43 int searchlen = (endopt) ? endopt - optnm : strlen (optnm);
46 for (int i=0; i< table_len_i_; i++)
48 char const *ln = option_a_[i].longname_sz_;
50 if (ln && !strncmp (ln, optnm, searchlen))
52 found_option_l_ = option_a_+i;
59 report (E_UNKNOWNOPTION);
63 argument_index_i_ = 0;
66 if (found_option_l_->take_arg_sz_)
69 optional_argument_ch_C_ = endopt +1; // a '='
72 optional_argument_ch_C_ = arg_value_ch_a_a_[array_index_i_];
75 if (!optional_argument_ch_C_)
81 optional_argument_ch_C_ = 0;
83 report (E_NOARGEXPECT);
86 return found_option_l_;
90 Long_option_init::str () const
94 str += "-" + shortname_ch_;
95 if (shortname_ch_ && longname_sz_)
98 str += String ("`--") + longname_sz_ + "'";
103 Long_option_init::str_for_help () const
107 s = "-" + to_str (shortname_ch_);
111 s = s + ((shortname_ch_ && longname_sz_) ? "," : " ");
114 s = s + "--" + longname_sz_;
123 s = s + gettext (take_arg_sz_);
128 // report an error, GNU style.
130 Getopt_long::report (Errorcod c)
133 if (!error_ostream_l_)
136 String str = arg_value_ch_a_a_[0];
141 str += _f ("option `%s\' requires an argument",
142 found_option_l_->str ());
145 str += _f ("option `%s\' doesn't allow an argument",
146 found_option_l_->str ());
148 case E_UNKNOWNOPTION:
149 str += _f ("unrecognized option: `%s\'",
150 String (argument_index_i_
151 ? String ("-" + _f("%c",arg_value_ch_a_a_[array_index_i_][argument_index_i_]))
152 : String (arg_value_ch_a_a_[array_index_i_])));
155 str += _f ("invalid argument `%s\' to option `%s'",
156 optional_argument_ch_C_, found_option_l_->str ());
160 *error_ostream_l_ << str << endl;
164 const Long_option_init *
165 Getopt_long::parseshort()
167 char c=arg_value_ch_a_a_[array_index_i_][argument_index_i_];
171 for (int i=0; i < table_len_i_; i++)
172 if (option_a_[i].shortname_ch_ == c)
174 found_option_l_ = option_a_+i;
178 if (!found_option_l_)
180 report (E_UNKNOWNOPTION);
185 if (!found_option_l_->take_arg_sz_)
187 optional_argument_ch_C_ = 0;
188 return found_option_l_;
190 optional_argument_ch_C_ = arg_value_ch_a_a_[array_index_i_] + argument_index_i_;
193 argument_index_i_ = 0;
195 if (!optional_argument_ch_C_[0])
197 optional_argument_ch_C_ = arg_value_ch_a_a_[array_index_i_];
200 if (!optional_argument_ch_C_)
202 report (E_ARGEXPECT);
205 return found_option_l_;
208 const Long_option_init *
209 Getopt_long::operator()()
218 if (argument_index_i_)
221 const char * argument_C = arg_value_ch_a_a_[array_index_i_];
223 if (argument_C[0] != '-')
226 if (argument_C[1] == '-') {// what to do with "command -- bla"
236 argument_index_i_ = 1;
248 Getopt_long::Getopt_long (int c, char **v, Long_option_init *lo)
251 error_ostream_l_ = &cerr;
252 arg_value_ch_a_a_ = v;
253 argument_count_i_ = c;
255 argument_index_i_ = 0;
257 // reached end of option table?
259 for (int i = 0; option_a_[i].longname_sz_ ||option_a_[i].shortname_ch_; i++)
265 Getopt_long::ok() const
267 return array_index_i_ < argument_count_i_;
274 while (array_index_i_ < argument_count_i_
275 && !arg_value_ch_a_a_[array_index_i_][argument_index_i_])
278 argument_index_i_ = 0;
283 Getopt_long::current_arg()
285 if (array_index_i_ >= argument_count_i_)
287 char const * a = arg_value_ch_a_a_[array_index_i_];
288 return a + argument_index_i_;
292 Getopt_long::get_next_arg()
294 char const * a = current_arg();
298 argument_index_i_= 0;
304 const int EXTRA_SPACES = 5;
307 Long_option_init::table_str (Long_option_init *l)
309 String argstr = "ARG";
313 for (int i=0; l[i].shortname_ch_ || l[i].longname_sz_; i++)
315 wid = wid >? l[i].str_for_help ().length_i ();
318 for (int i=0; l[i].shortname_ch_ || l[i].longname_sz_; i++)
320 String s = " " + l[i].str_for_help ();
321 s += String_convert::char_str (' ', wid - s.length_i () + EXTRA_SPACES);
323 tabstr += s + gettext (l[i].help_sz_) + "\n";
331 Long_option_init::compare (Long_option_init const &a, Long_option_init const &b)
333 if (a.shortname_ch_ && b.shortname_ch_ && a.shortname_ch_- b.shortname_ch_)
334 return a.shortname_ch_ - b.shortname_ch_;
336 if (b.shortname_ch_ && a.longname_sz_)
338 char s[2] = {b.shortname_ch_, 0};
339 return strcmp (a.longname_sz_, s);
341 if (a.shortname_ch_ && b.longname_sz_)
343 char s[2] = {a.shortname_ch_, 0};
344 return strcmp (s, b.longname_sz_);
347 return strcmp (a.longname_sz_, b.longname_sz_);