2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 1996--2010 Han-Wen Nienhuys, <hanwen@xs4all.nl>
6 LilyPond is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 LilyPond is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
20 #include "getopt-long.hh"
27 #include "international.hh"
31 gettext (char const *s
)
40 Getopt_long::get_argument_index ()
43 if (!optional_argument_str0_
44 || sscanf (optional_argument_str0_
, "%ld", &l
) != 1)
45 report (E_ILLEGALARG
);
50 const Long_option_init
*
51 Getopt_long::parselong ()
53 char const *optnm
= arg_value_char_a_a_
[array_index_
] + 2;
56 char const *endopt
= strchr (optnm
, '=');
57 int searchlen
= (endopt
) ? endopt
- optnm
: strlen (optnm
);
60 for (int i
= 0; i
< table_len_
; i
++)
62 char const *ln
= option_a_
[i
].longname_str0_
;
64 if (ln
&& !strncmp (ln
, optnm
, searchlen
))
66 found_option_
= option_a_
+ i
;
73 report (E_UNKNOWNOPTION
);
79 if (found_option_
->take_arg_str0_
)
82 optional_argument_str0_
= endopt
+1; // a '='
85 optional_argument_str0_
= arg_value_char_a_a_
[array_index_
];
88 if (!optional_argument_str0_
)
93 optional_argument_str0_
= 0;
95 report (E_NOARGEXPECT
);
102 Long_option_init::to_string () const
106 str
+= "-" + shortname_char_
;
107 if (shortname_char_
&& longname_str0_
)
110 str
+= string ("`--") + longname_str0_
+ "'";
115 Long_option_init::str_for_help () const
119 s
= "-" + ::to_string (shortname_char_
);
123 s
= s
+ ((shortname_char_
&& longname_str0_
) ? ", " : " ");
126 s
= s
+ "--" + longname_str0_
;
135 s
= s
+ gettext (take_arg_str0_
);
140 // report an error, GNU style.
142 Getopt_long::report (Errorcod c
)
148 string str
= arg_value_char_a_a_
[0];
153 str
+= _f ("option `%s' requires an argument",
154 found_option_
->to_string ());
157 str
+= _f ("option `%s' does not allow an argument",
158 found_option_
->to_string ());
160 case E_UNKNOWNOPTION
:
161 str
+= _f ("unrecognized option: `%s'",
162 string (argument_index_
163 ? string ("-" + string (1, arg_value_char_a_a_
[array_index_
][argument_index_
]))
164 : string (arg_value_char_a_a_
[array_index_
])));
167 str
+= _f ("invalid argument `%s' to option `%s'",
168 optional_argument_str0_
, found_option_
->to_string ());
173 fprintf (error_out_
, "%s\n", str
.c_str ());
177 const Long_option_init
*
178 Getopt_long::parseshort ()
180 char c
= arg_value_char_a_a_
[array_index_
][argument_index_
];
184 for (int i
= 0; i
< table_len_
; i
++)
185 if (option_a_
[i
].shortname_char_
== c
)
187 found_option_
= option_a_
+ i
;
193 report (E_UNKNOWNOPTION
);
198 if (!found_option_
->take_arg_str0_
)
200 optional_argument_str0_
= 0;
201 return found_option_
;
203 optional_argument_str0_
= arg_value_char_a_a_
[array_index_
] + argument_index_
;
208 if (!optional_argument_str0_
[0])
210 optional_argument_str0_
= arg_value_char_a_a_
[array_index_
];
213 if (!optional_argument_str0_
)
214 report (E_ARGEXPECT
);
216 return found_option_
;
219 const Long_option_init
*
220 Getopt_long::operator () ()
230 return parseshort ();
232 char const *argument
= arg_value_char_a_a_
[array_index_
];
234 if (argument
[0] != '-')
237 if (argument
[1] == '-') {// what to do with "command -- bla"
248 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
++)
271 Getopt_long::ok () const
273 return array_index_
< argument_count_
;
280 while (array_index_
< argument_count_
281 && !arg_value_char_a_a_
[array_index_
][argument_index_
])
289 Getopt_long::current_arg ()
291 if (array_index_
>= argument_count_
)
293 char const *a
= arg_value_char_a_a_
[array_index_
];
294 return a
+ argument_index_
;
298 Getopt_long::get_next_arg ()
300 char const *a
= current_arg ();
309 const int EXTRA_SPACES
= 5;
312 Long_option_init::table_string (Long_option_init
*l
)
317 for (int i
= 0; l
[i
].shortname_char_
|| l
[i
].longname_str0_
; i
++)
318 wid
= max (int(wid
), int(l
[i
].str_for_help ().length ()));
320 for (int i
= 0; l
[i
].shortname_char_
|| l
[i
].longname_str0_
; i
++)
322 string s
= " " + l
[i
].str_for_help ();
323 s
+= string (wid
- s
.length () + EXTRA_SPACES
, ' ');
325 string
help_text (gettext (l
[i
].help_str0_
));
326 replace_all (&help_text
, "\n",
327 "\n" + string (wid
+ EXTRA_SPACES
+ 2, ' '));
328 tabstr
+= s
+ help_text
+ "\n";
335 Long_option_init::compare (Long_option_init
const &a
, Long_option_init
const &b
)
337 if (a
.shortname_char_
&& b
.shortname_char_
&& a
.shortname_char_
- b
.shortname_char_
)
338 return a
.shortname_char_
- b
.shortname_char_
;
340 if (b
.shortname_char_
&& a
.longname_str0_
)
342 char s
[2] = {b
.shortname_char_
, 0};
343 return strcmp (a
.longname_str0_
, s
);
345 if (a
.shortname_char_
&& b
.longname_str0_
)
347 char s
[2] = {a
.shortname_char_
, 0};
348 return strcmp (s
, b
.longname_str0_
);
351 return strcmp (a
.longname_str0_
, b
.longname_str0_
);