2 process command line, GNU style.
4 this is (Copyleft) 1996, Han-Wen Nienhuys, <hanwen@cs.uu.nl>
14 #include "getopt-long.hh"
15 #include "international.hh"
16 #include "string-convert.hh"
21 gettext (char const* s
)
30 Getopt_long::argument_to_i()
33 if (!optional_argument_ch_C_
34 || sscanf (optional_argument_ch_C_
, "%ld", &l
) != 1)
35 report (E_ILLEGALARG
);
40 const Long_option_init
*
41 Getopt_long::parselong()
43 char const *optnm
= arg_value_ch_a_a_
[array_index_i_
] + 2 ;
46 char const *endopt
= strchr (optnm
, '=');
47 int searchlen
= (endopt
) ? endopt
- optnm
: strlen (optnm
);
50 for (int i
=0; i
< table_len_i_
; i
++)
52 char const *ln
= option_a_
[i
].longname_sz_
;
54 if (ln
&& !strncmp (ln
, optnm
, searchlen
))
56 found_option_l_
= option_a_
+i
;
63 report (E_UNKNOWNOPTION
);
67 argument_index_i_
= 0;
70 if (found_option_l_
->take_arg_sz_
)
73 optional_argument_ch_C_
= endopt
+1; // a '='
76 optional_argument_ch_C_
= arg_value_ch_a_a_
[array_index_i_
];
79 if (!optional_argument_ch_C_
)
85 optional_argument_ch_C_
= 0;
87 report (E_NOARGEXPECT
);
90 return found_option_l_
;
94 Long_option_init::str () const
98 str
+= "-" + shortname_ch_
;
99 if (shortname_ch_
&& longname_sz_
)
102 str
+= String ("`--") + longname_sz_
+ "'";
107 Long_option_init::str_for_help () const
111 s
= "-" + to_str (shortname_ch_
);
115 s
= s
+ ((shortname_ch_
&& longname_sz_
) ? "," : " ");
118 s
= s
+ "--" + longname_sz_
;
127 s
= s
+ gettext (take_arg_sz_
);
132 // report an error, GNU style.
134 Getopt_long::report (Errorcod c
)
137 if (!error_ostream_l_
)
140 String str
= arg_value_ch_a_a_
[0];
145 str
+= _f ("option `%s' requires an argument",
146 found_option_l_
->str ());
149 str
+= _f ("option `%s' doesn't allow an argument",
150 found_option_l_
->str ());
152 case E_UNKNOWNOPTION
:
153 str
+= _f ("unrecognized option: `%s'",
154 String (argument_index_i_
155 ? String ("-" + String_convert::form_str ("%c",
156 arg_value_ch_a_a_
[array_index_i_
][argument_index_i_
]))
157 : String (arg_value_ch_a_a_
[array_index_i_
])));
160 str
+= _f ("invalid argument `%s' to option `%s'",
161 optional_argument_ch_C_
, found_option_l_
->str ());
166 *error_ostream_l_
<< str
<< endl
;
170 const Long_option_init
*
171 Getopt_long::parseshort()
173 char c
=arg_value_ch_a_a_
[array_index_i_
][argument_index_i_
];
177 for (int i
=0; i
< table_len_i_
; i
++)
178 if (option_a_
[i
].shortname_ch_
== c
)
180 found_option_l_
= option_a_
+i
;
184 if (!found_option_l_
)
186 report (E_UNKNOWNOPTION
);
191 if (!found_option_l_
->take_arg_sz_
)
193 optional_argument_ch_C_
= 0;
194 return found_option_l_
;
196 optional_argument_ch_C_
= arg_value_ch_a_a_
[array_index_i_
] + argument_index_i_
;
199 argument_index_i_
= 0;
201 if (!optional_argument_ch_C_
[0])
203 optional_argument_ch_C_
= arg_value_ch_a_a_
[array_index_i_
];
206 if (!optional_argument_ch_C_
)
208 report (E_ARGEXPECT
);
211 return found_option_l_
;
214 const Long_option_init
*
215 Getopt_long::operator()()
224 if (argument_index_i_
)
227 const char * argument_C
= arg_value_ch_a_a_
[array_index_i_
];
229 if (argument_C
[0] != '-')
232 if (argument_C
[1] == '-') {// what to do with "command -- bla"
242 argument_index_i_
= 1;
254 Getopt_long::Getopt_long (int c
, char **v
, Long_option_init
*lo
)
257 error_ostream_l_
= &cerr
;
258 arg_value_ch_a_a_
= v
;
259 argument_count_i_
= c
;
261 argument_index_i_
= 0;
263 // reached end of option table?
265 for (int i
= 0; option_a_
[i
].longname_sz_
||option_a_
[i
].shortname_ch_
; i
++)
271 Getopt_long::ok() const
273 return array_index_i_
< argument_count_i_
;
280 while (array_index_i_
< argument_count_i_
281 && !arg_value_ch_a_a_
[array_index_i_
][argument_index_i_
])
284 argument_index_i_
= 0;
289 Getopt_long::current_arg()
291 if (array_index_i_
>= argument_count_i_
)
293 char const * a
= arg_value_ch_a_a_
[array_index_i_
];
294 return a
+ argument_index_i_
;
298 Getopt_long::get_next_arg()
300 char const * a
= current_arg();
304 argument_index_i_
= 0;
310 const int EXTRA_SPACES
= 5;
313 Long_option_init::table_str (Long_option_init
*l
)
315 String argstr
= "ARG";
319 for (int i
=0; l
[i
].shortname_ch_
|| l
[i
].longname_sz_
; i
++)
321 wid
= wid
>? l
[i
].str_for_help ().length_i ();
324 for (int i
=0; l
[i
].shortname_ch_
|| l
[i
].longname_sz_
; i
++)
326 String s
= " " + l
[i
].str_for_help ();
327 s
+= String_convert::char_str (' ', wid
- s
.length_i () + EXTRA_SPACES
);
329 tabstr
+= s
+ gettext (l
[i
].help_sz_
) + "\n";
337 Long_option_init::compare (Long_option_init
const &a
, Long_option_init
const &b
)
339 if (a
.shortname_ch_
&& b
.shortname_ch_
&& a
.shortname_ch_
- b
.shortname_ch_
)
340 return a
.shortname_ch_
- b
.shortname_ch_
;
342 if (b
.shortname_ch_
&& a
.longname_sz_
)
344 char s
[2] = {b
.shortname_ch_
, 0};
345 return strcmp (a
.longname_sz_
, s
);
347 if (a
.shortname_ch_
&& b
.longname_sz_
)
349 char s
[2] = {a
.shortname_ch_
, 0};
350 return strcmp (s
, b
.longname_sz_
);
353 return strcmp (a
.longname_sz_
, b
.longname_sz_
);