2 process command line, GNU style.
4 this is Copyleft (c) 1996--2007 Han-Wen Nienhuys, <hanwen@xs4all.nl>
7 #include "getopt-long.hh"
14 #include "international.hh"
18 gettext (char const *s
)
27 Getopt_long::get_argument_index ()
30 if (!optional_argument_str0_
31 || sscanf (optional_argument_str0_
, "%ld", &l
) != 1)
32 report (E_ILLEGALARG
);
37 const Long_option_init
*
38 Getopt_long::parselong ()
40 char const *optnm
= arg_value_char_a_a_
[array_index_
] + 2;
43 char const *endopt
= strchr (optnm
, '=');
44 int searchlen
= (endopt
) ? endopt
- optnm
: strlen (optnm
);
47 for (int i
= 0; i
< table_len_
; i
++)
49 char const *ln
= option_a_
[i
].longname_str0_
;
51 if (ln
&& !strncmp (ln
, optnm
, searchlen
))
53 found_option_
= option_a_
+ i
;
60 report (E_UNKNOWNOPTION
);
66 if (found_option_
->take_arg_str0_
)
69 optional_argument_str0_
= endopt
+1; // a '='
72 optional_argument_str0_
= arg_value_char_a_a_
[array_index_
];
75 if (!optional_argument_str0_
)
80 optional_argument_str0_
= 0;
82 report (E_NOARGEXPECT
);
89 Long_option_init::to_string () const
93 str
+= "-" + shortname_char_
;
94 if (shortname_char_
&& longname_str0_
)
97 str
+= string ("`--") + longname_str0_
+ "'";
102 Long_option_init::str_for_help () const
106 s
= "-" + ::to_string (shortname_char_
);
110 s
= s
+ ((shortname_char_
&& longname_str0_
) ? ", " : " ");
113 s
= s
+ "--" + longname_str0_
;
122 s
= s
+ gettext (take_arg_str0_
);
127 // report an error, GNU style.
129 Getopt_long::report (Errorcod c
)
135 string str
= arg_value_char_a_a_
[0];
140 str
+= _f ("option `%s' requires an argument",
141 found_option_
->to_string ());
144 str
+= _f ("option `%s' does not allow an argument",
145 found_option_
->to_string ());
147 case E_UNKNOWNOPTION
:
148 str
+= _f ("unrecognized option: `%s'",
149 string (argument_index_
150 ? string ("-" + string (1, arg_value_char_a_a_
[array_index_
][argument_index_
]))
151 : string (arg_value_char_a_a_
[array_index_
])));
154 str
+= _f ("invalid argument `%s' to option `%s'",
155 optional_argument_str0_
, found_option_
->to_string ());
160 fprintf (error_out_
, "%s\n", str
.c_str ());
164 const Long_option_init
*
165 Getopt_long::parseshort ()
167 char c
= arg_value_char_a_a_
[array_index_
][argument_index_
];
171 for (int i
= 0; i
< table_len_
; i
++)
172 if (option_a_
[i
].shortname_char_
== c
)
174 found_option_
= option_a_
+ i
;
180 report (E_UNKNOWNOPTION
);
185 if (!found_option_
->take_arg_str0_
)
187 optional_argument_str0_
= 0;
188 return found_option_
;
190 optional_argument_str0_
= arg_value_char_a_a_
[array_index_
] + argument_index_
;
195 if (!optional_argument_str0_
[0])
197 optional_argument_str0_
= arg_value_char_a_a_
[array_index_
];
200 if (!optional_argument_str0_
)
201 report (E_ARGEXPECT
);
203 return found_option_
;
206 const Long_option_init
*
207 Getopt_long::operator () ()
217 return parseshort ();
219 char const *argument
= arg_value_char_a_a_
[array_index_
];
221 if (argument
[0] != '-')
224 if (argument
[1] == '-') {// what to do with "command -- bla"
235 return parseshort ();
242 Getopt_long::Getopt_long (int c
, char **v
, Long_option_init
*lo
)
246 arg_value_char_a_a_
= v
;
251 // reached end of option table?
253 for (int i
= 0; option_a_
[i
].longname_str0_
|| option_a_
[i
].shortname_char_
; i
++)
258 Getopt_long::ok () const
260 return array_index_
< argument_count_
;
267 while (array_index_
< argument_count_
268 && !arg_value_char_a_a_
[array_index_
][argument_index_
])
276 Getopt_long::current_arg ()
278 if (array_index_
>= argument_count_
)
280 char const *a
= arg_value_char_a_a_
[array_index_
];
281 return a
+ argument_index_
;
285 Getopt_long::get_next_arg ()
287 char const *a
= current_arg ();
296 const int EXTRA_SPACES
= 5;
299 Long_option_init::table_string (Long_option_init
*l
)
304 for (int i
= 0; l
[i
].shortname_char_
|| l
[i
].longname_str0_
; i
++)
305 wid
= max (int(wid
), int(l
[i
].str_for_help ().length ()));
307 for (int i
= 0; l
[i
].shortname_char_
|| l
[i
].longname_str0_
; i
++)
309 string s
= " " + l
[i
].str_for_help ();
310 s
+= string (wid
- s
.length () + EXTRA_SPACES
, ' ');
312 string
help_text (gettext (l
[i
].help_str0_
));
313 replace_all (help_text
, "\n",
314 "\n" + string (wid
+ EXTRA_SPACES
+ 2, ' '));
315 tabstr
+= s
+ help_text
+ "\n";
322 Long_option_init::compare (Long_option_init
const &a
, Long_option_init
const &b
)
324 if (a
.shortname_char_
&& b
.shortname_char_
&& a
.shortname_char_
- b
.shortname_char_
)
325 return a
.shortname_char_
- b
.shortname_char_
;
327 if (b
.shortname_char_
&& a
.longname_str0_
)
329 char s
[2] = {b
.shortname_char_
, 0};
330 return strcmp (a
.longname_str0_
, s
);
332 if (a
.shortname_char_
&& b
.longname_str0_
)
334 char s
[2] = {a
.shortname_char_
, 0};
335 return strcmp (s
, b
.longname_str0_
);
338 return strcmp (a
.longname_str0_
, b
.longname_str0_
);