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"
18 gettext (char const* s)
27 Getopt_long::argument_to_i()
30 if (!optional_argument_ch_C_
31 || sscanf (optional_argument_ch_C_, "%ld", &l) != 1)
32 report (E_ILLEGALARG);
37 const Long_option_init *
38 Getopt_long::parselong()
40 char const *optnm = arg_value_ch_a_a_[array_index_i_] + 2 ;
43 char const *endopt = strchr (optnm, '=');
44 int searchlen = (endopt) ? endopt - optnm : strlen (optnm);
47 for (int i=0; i< table_len_i_; i++)
49 char const *ln = option_a_[i].longname_sz_;
51 if (ln && !strncmp (ln, optnm, searchlen))
53 found_option_l_ = option_a_+i;
60 report (E_UNKNOWNOPTION);
64 argument_index_i_ = 0;
67 if (found_option_l_->take_arg_sz_)
70 optional_argument_ch_C_ = endopt +1; // a '='
73 optional_argument_ch_C_ = arg_value_ch_a_a_[array_index_i_];
76 if (!optional_argument_ch_C_)
82 optional_argument_ch_C_ = 0;
84 report (E_NOARGEXPECT);
87 return found_option_l_;
91 Long_option_init::str () const
95 str += "-" + shortname_ch_;
96 if (shortname_ch_ && longname_sz_)
99 str += String ("`--") + longname_sz_ + "'";
104 Long_option_init::str_for_help () const
108 s = "-" + to_str (shortname_ch_);
112 s = s + ((shortname_ch_ && longname_sz_) ? "," : " ");
115 s = s + "--" + longname_sz_;
124 s = s + gettext (take_arg_sz_);
129 // report an error, GNU style.
131 Getopt_long::report (Errorcod c)
134 if (!error_ostream_l_)
137 String str = arg_value_ch_a_a_[0];
142 str += _f ("Option `%s' requires an argument",
143 found_option_l_->str ());
146 str += _f ("Option `%s' doesn't allow an argument",
147 found_option_l_->str ());
149 case E_UNKNOWNOPTION:
150 str += _f ("unrecognized option: `%s'",
151 String (argument_index_i_
152 ? String ("-" + String_convert::form_str ("%c",
153 arg_value_ch_a_a_[array_index_i_][argument_index_i_]))
154 : String (arg_value_ch_a_a_[array_index_i_])));
157 str += _f ("invalid argument `%s' to option `%s'",
158 optional_argument_ch_C_, found_option_l_->str ());
162 *error_ostream_l_ << str << endl;
166 const Long_option_init *
167 Getopt_long::parseshort()
169 char c=arg_value_ch_a_a_[array_index_i_][argument_index_i_];
173 for (int i=0; i < table_len_i_; i++)
174 if (option_a_[i].shortname_ch_ == c)
176 found_option_l_ = option_a_+i;
180 if (!found_option_l_)
182 report (E_UNKNOWNOPTION);
187 if (!found_option_l_->take_arg_sz_)
189 optional_argument_ch_C_ = 0;
190 return found_option_l_;
192 optional_argument_ch_C_ = arg_value_ch_a_a_[array_index_i_] + argument_index_i_;
195 argument_index_i_ = 0;
197 if (!optional_argument_ch_C_[0])
199 optional_argument_ch_C_ = arg_value_ch_a_a_[array_index_i_];
202 if (!optional_argument_ch_C_)
204 report (E_ARGEXPECT);
207 return found_option_l_;
210 const Long_option_init *
211 Getopt_long::operator()()
220 if (argument_index_i_)
223 const char * argument_C = arg_value_ch_a_a_[array_index_i_];
225 if (argument_C[0] != '-')
228 if (argument_C[1] == '-') {// what to do with "command -- bla"
238 argument_index_i_ = 1;
250 Getopt_long::Getopt_long (int c, char **v, Long_option_init *lo)
253 error_ostream_l_ = &cerr;
254 arg_value_ch_a_a_ = v;
255 argument_count_i_ = c;
257 argument_index_i_ = 0;
259 // reached end of option table?
261 for (int i = 0; option_a_[i].longname_sz_ ||option_a_[i].shortname_ch_; i++)
267 Getopt_long::ok() const
269 return array_index_i_ < argument_count_i_;
276 while (array_index_i_ < argument_count_i_
277 && !arg_value_ch_a_a_[array_index_i_][argument_index_i_])
280 argument_index_i_ = 0;
285 Getopt_long::current_arg()
287 if (array_index_i_ >= argument_count_i_)
289 char const * a = arg_value_ch_a_a_[array_index_i_];
290 return a + argument_index_i_;
294 Getopt_long::get_next_arg()
296 char const * a = current_arg();
300 argument_index_i_= 0;
306 const int EXTRA_SPACES = 5;
309 Long_option_init::table_str (Long_option_init *l)
311 String argstr = "ARG";
315 for (int i=0; l[i].shortname_ch_ || l[i].longname_sz_; i++)
317 wid = wid >? l[i].str_for_help ().length_i ();
320 for (int i=0; l[i].shortname_ch_ || l[i].longname_sz_; i++)
322 String s = " " + l[i].str_for_help ();
323 s += String_convert::char_str (' ', wid - s.length_i () + EXTRA_SPACES);
325 tabstr += s + gettext (l[i].help_sz_) + "\n";
333 Long_option_init::compare (Long_option_init const &a, Long_option_init const &b)
335 if (a.shortname_ch_ && b.shortname_ch_ && a.shortname_ch_- b.shortname_ch_)
336 return a.shortname_ch_ - b.shortname_ch_;
338 if (b.shortname_ch_ && a.longname_sz_)
340 char s[2] = {b.shortname_ch_, 0};
341 return strcmp (a.longname_sz_, s);
343 if (a.shortname_ch_ && b.longname_sz_)
345 char s[2] = {a.shortname_ch_, 0};
346 return strcmp (s, b.longname_sz_);
349 return strcmp (a.longname_sz_, b.longname_sz_);