2 process command line, GNU style.
4 this is Copyleft (c) 1996--2003 Han-Wen Nienhuys, <hanwen@cs.uu.nl>
15 #include "getopt-long.hh"
16 #include "international.hh"
17 #include "string-convert.hh"
22 gettext (char const* s
)
31 Getopt_long::get_argument_index ()
34 if (!optional_argument_str0_
35 || sscanf (optional_argument_str0_
, "%ld", &l
) != 1)
36 report (E_ILLEGALARG
);
41 const Long_option_init
*
42 Getopt_long::parselong ()
44 char const *optnm
= arg_value_char_a_a_
[array_index_
] + 2 ;
47 char const *endopt
= strchr (optnm
, '=');
48 int searchlen
= (endopt
) ? endopt
- optnm
: strlen (optnm
);
51 for (int i
=0; i
< table_len_
; i
++)
53 char const *ln
= option_a_
[i
].longname_str0_
;
55 if (ln
&& !strncmp (ln
, optnm
, searchlen
))
57 found_option_
= option_a_
+i
;
64 report (E_UNKNOWNOPTION
);
71 if (found_option_
->take_arg_str0_
)
74 optional_argument_str0_
= endopt
+1; // a '='
77 optional_argument_str0_
= arg_value_char_a_a_
[array_index_
];
80 if (!optional_argument_str0_
)
86 optional_argument_str0_
= 0;
88 report (E_NOARGEXPECT
);
95 Long_option_init::to_string () const
99 str
+= "-" + shortname_char_
;
100 if (shortname_char_
&& longname_str0_
)
103 str
+= String ("`--") + longname_str0_
+ "'";
108 Long_option_init::str_for_help () const
112 s
= "-" + ::to_string (shortname_char_
);
116 s
= s
+ ((shortname_char_
&& longname_str0_
) ? ", " : " ");
119 s
= s
+ "--" + longname_str0_
;
128 s
= s
+ gettext (take_arg_str0_
);
133 // report an error, GNU style.
135 Getopt_long::report (Errorcod c
)
141 String str
= arg_value_char_a_a_
[0];
146 str
+= _f ("option `%s' requires an argument",
147 found_option_
->to_string ());
150 str
+= _f ("option `%s' doesn't allow an argument",
151 found_option_
->to_string ());
153 case E_UNKNOWNOPTION
:
154 str
+= _f ("unrecognized option: `%s'",
155 String (argument_index_
156 ? String ("-" + String_convert::form_string ("%c",
157 arg_value_char_a_a_
[array_index_
][argument_index_
]))
158 : String (arg_value_char_a_a_
[array_index_
])));
161 str
+= _f ("invalid argument `%s' to option `%s'",
162 optional_argument_str0_
, found_option_
->to_string ());
167 fprintf(error_out_
, "%s\n", str
.to_str0 ());
171 const Long_option_init
*
172 Getopt_long::parseshort ()
174 char c
=arg_value_char_a_a_
[array_index_
][argument_index_
];
178 for (int i
=0; i
< table_len_
; i
++)
179 if (option_a_
[i
].shortname_char_
== c
)
181 found_option_
= option_a_
+i
;
187 report (E_UNKNOWNOPTION
);
192 if (!found_option_
->take_arg_str0_
)
194 optional_argument_str0_
= 0;
195 return found_option_
;
197 optional_argument_str0_
= arg_value_char_a_a_
[array_index_
] + argument_index_
;
202 if (!optional_argument_str0_
[0])
204 optional_argument_str0_
= arg_value_char_a_a_
[array_index_
];
207 if (!optional_argument_str0_
)
209 report (E_ARGEXPECT
);
212 return found_option_
;
215 const Long_option_init
*
216 Getopt_long::operator () ()
226 return parseshort ();
228 const char * argument
= arg_value_char_a_a_
[array_index_
];
230 if (argument
[0] != '-')
233 if (argument
[1] == '-') {// what to do with "command -- bla"
244 return parseshort ();
255 Getopt_long::Getopt_long (int c
, char **v
, Long_option_init
*lo
)
259 arg_value_char_a_a_
= v
;
264 // reached end of option table?
266 for (int i
= 0; option_a_
[i
].longname_str0_
||option_a_
[i
].shortname_char_
; i
++)
272 Getopt_long::ok () const
274 return array_index_
< argument_count_
;
281 while (array_index_
< argument_count_
282 && !arg_value_char_a_a_
[array_index_
][argument_index_
])
290 Getopt_long::current_arg ()
292 if (array_index_
>= argument_count_
)
294 char const * a
= arg_value_char_a_a_
[array_index_
];
295 return a
+ argument_index_
;
299 Getopt_long::get_next_arg ()
301 char const * a
= current_arg ();
311 const int EXTRA_SPACES
= 5;
314 Long_option_init::table_string (Long_option_init
*l
)
316 String argstr
= "ARG";
320 for (int i
=0; l
[i
].shortname_char_
|| l
[i
].longname_str0_
; i
++)
322 wid
= wid
>? l
[i
].str_for_help ().length ();
325 for (int i
=0; l
[i
].shortname_char_
|| l
[i
].longname_str0_
; i
++)
327 String s
= " " + l
[i
].str_for_help ();
328 s
+= String_convert::char_string (' ', wid
- s
.length () + EXTRA_SPACES
);
330 tabstr
+= s
+ gettext (l
[i
].help_str0_
) + "\n";
338 Long_option_init::compare (Long_option_init
const &a
, Long_option_init
const &b
)
340 if (a
.shortname_char_
&& b
.shortname_char_
&& a
.shortname_char_
- b
.shortname_char_
)
341 return a
.shortname_char_
- b
.shortname_char_
;
343 if (b
.shortname_char_
&& a
.longname_str0_
)
345 char s
[2] = {b
.shortname_char_
, 0};
346 return strcmp (a
.longname_str0_
, s
);
348 if (a
.shortname_char_
&& b
.longname_str0_
)
350 char s
[2] = {a
.shortname_char_
, 0};
351 return strcmp (s
, b
.longname_str0_
);
354 return strcmp (a
.longname_str0_
, b
.longname_str0_
);