2 process command line, GNU style.
4 this is (Copyleft) 1996, Han-Wen Nienhuys, <hanwen@cs.uu.nl>
12 #include "getopt-long.hh"
13 #include "international.hh"
14 #include "string-convert.hh"
19 gettext (char const* s)
28 Getopt_long::argument_to_i()
31 if (!optional_argument_ch_C_
32 || sscanf (optional_argument_ch_C_, "%ld", &l) != 1)
33 report (E_ILLEGALARG);
38 const Long_option_init *
39 Getopt_long::parselong()
41 char const *optnm = arg_value_ch_a_a_[array_index_i_] + 2 ;
44 char const *endopt = strchr (optnm, '=');
45 int searchlen = (endopt) ? endopt - optnm : strlen (optnm);
48 for (int i=0; i< table_len_i_; i++)
50 char const *ln = option_a_[i].longname_sz_;
52 if (ln && !strncmp (ln, optnm, searchlen))
54 found_option_l_ = option_a_+i;
61 report (E_UNKNOWNOPTION);
65 argument_index_i_ = 0;
68 if (found_option_l_->take_arg_sz_)
71 optional_argument_ch_C_ = endopt +1; // a '='
74 optional_argument_ch_C_ = arg_value_ch_a_a_[array_index_i_];
77 if (!optional_argument_ch_C_)
83 optional_argument_ch_C_ = 0;
85 report (E_NOARGEXPECT);
88 return found_option_l_;
92 Long_option_init::str () const
96 str += "-" + shortname_ch_;
97 if (shortname_ch_ && longname_sz_)
100 str += String ("`--") + longname_sz_ + "'";
105 Long_option_init::str_for_help () const
109 s = "-" + to_str (shortname_ch_);
113 s = s + ((shortname_ch_ && longname_sz_) ? "," : " ");
116 s = s + "--" + longname_sz_;
125 s = s + gettext (take_arg_sz_);
130 // report an error, GNU style.
132 Getopt_long::report (Errorcod c)
135 if (!error_ostream_l_)
138 String str = arg_value_ch_a_a_[0];
143 str += _f ("Option `%s' requires an argument",
144 found_option_l_->str ());
147 str += _f ("Option `%s' doesn't allow an argument",
148 found_option_l_->str ());
150 case E_UNKNOWNOPTION:
151 str += _f ("unrecognized option: `%s'",
152 String (argument_index_i_
153 ? String ("-" + String_convert::form_str ("%c",
154 arg_value_ch_a_a_[array_index_i_][argument_index_i_]))
155 : String (arg_value_ch_a_a_[array_index_i_])));
158 str += _f ("invalid argument `%s' to option `%s'",
159 optional_argument_ch_C_, found_option_l_->str ());
164 *error_ostream_l_ << str << endl;
168 const Long_option_init *
169 Getopt_long::parseshort()
171 char c=arg_value_ch_a_a_[array_index_i_][argument_index_i_];
175 for (int i=0; i < table_len_i_; i++)
176 if (option_a_[i].shortname_ch_ == c)
178 found_option_l_ = option_a_+i;
182 if (!found_option_l_)
184 report (E_UNKNOWNOPTION);
189 if (!found_option_l_->take_arg_sz_)
191 optional_argument_ch_C_ = 0;
192 return found_option_l_;
194 optional_argument_ch_C_ = arg_value_ch_a_a_[array_index_i_] + argument_index_i_;
197 argument_index_i_ = 0;
199 if (!optional_argument_ch_C_[0])
201 optional_argument_ch_C_ = arg_value_ch_a_a_[array_index_i_];
204 if (!optional_argument_ch_C_)
206 report (E_ARGEXPECT);
209 return found_option_l_;
212 const Long_option_init *
213 Getopt_long::operator()()
222 if (argument_index_i_)
225 const char * argument_C = arg_value_ch_a_a_[array_index_i_];
227 if (argument_C[0] != '-')
230 if (argument_C[1] == '-') {// what to do with "command -- bla"
240 argument_index_i_ = 1;
252 Getopt_long::Getopt_long (int c, char **v, Long_option_init *lo)
255 error_ostream_l_ = &cerr;
256 arg_value_ch_a_a_ = v;
257 argument_count_i_ = c;
259 argument_index_i_ = 0;
261 // reached end of option table?
263 for (int i = 0; option_a_[i].longname_sz_ ||option_a_[i].shortname_ch_; i++)
269 Getopt_long::ok() const
271 return array_index_i_ < argument_count_i_;
278 while (array_index_i_ < argument_count_i_
279 && !arg_value_ch_a_a_[array_index_i_][argument_index_i_])
282 argument_index_i_ = 0;
287 Getopt_long::current_arg()
289 if (array_index_i_ >= argument_count_i_)
291 char const * a = arg_value_ch_a_a_[array_index_i_];
292 return a + argument_index_i_;
296 Getopt_long::get_next_arg()
298 char const * a = current_arg();
302 argument_index_i_= 0;
308 const int EXTRA_SPACES = 5;
311 Long_option_init::table_str (Long_option_init *l)
313 String argstr = "ARG";
317 for (int i=0; l[i].shortname_ch_ || l[i].longname_sz_; i++)
319 wid = wid >? l[i].str_for_help ().length_i ();
322 for (int i=0; l[i].shortname_ch_ || l[i].longname_sz_; i++)
324 String s = " " + l[i].str_for_help ();
325 s += String_convert::char_str (' ', wid - s.length_i () + EXTRA_SPACES);
327 tabstr += s + gettext (l[i].help_sz_) + "\n";
335 Long_option_init::compare (Long_option_init const &a, Long_option_init const &b)
337 if (a.shortname_ch_ && b.shortname_ch_ && a.shortname_ch_- b.shortname_ch_)
338 return a.shortname_ch_ - b.shortname_ch_;
340 if (b.shortname_ch_ && a.longname_sz_)
342 char s[2] = {b.shortname_ch_, 0};
343 return strcmp (a.longname_sz_, s);
345 if (a.shortname_ch_ && b.longname_sz_)
347 char s[2] = {a.shortname_ch_, 0};
348 return strcmp (s, b.longname_sz_);
351 return strcmp (a.longname_sz_, b.longname_sz_);