2 * Wrapper for GNU getopt which deals with standard options
3 * Copyright (C) 1998-2001,2003,2004,2011,2012,2014 Olly Betts
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
39 /* It might be useful to be able to disable all long options on small
40 * platforms like older PDAs.
43 # define getopt_long(ARGC, ARGV, STR, OPTS, PTR) getopt(ARGC, ARGV, STR)
47 * bad command line give:
66 * want to cope with optional/required parameters on long options
67 * and also parameters on short options
70 static const char newline_tabs
[] = "\n\t\t\t\t";
73 static char * const *argv
;
74 static const char *shortopts
;
75 static const struct option
*longopts
;
77 static const struct help_msg
*help
;
78 static int min_args
, max_args
;
79 static int msg_args
, msg_extra
;
80 static const char * msg_extra_arg
;
85 while (help
&& help
->opt
) {
86 const char *longopt
= 0;
88 const struct option
*o
= 0;
90 if (HLP_ISLONG(opt
)) {
91 o
= longopts
+ HLP_DECODELONG(opt
);
96 if (isalnum((unsigned char)opt
))
97 printf(" -%c%c", opt
, longopt
? ',' : ' ');
102 int len
= strlen(longopt
);
103 printf(" --%s", longopt
);
104 if (o
&& o
->has_arg
) {
108 if (o
->has_arg
== optional_argument
) {
115 for (p
= longopt
; *p
; p
++) putchar(toupper(*p
));
117 if (o
->has_arg
== optional_argument
) putchar(']');
119 len
= (len
>> 3) + 2;
120 if (len
> 4) len
= 0;
121 fputs(newline_tabs
+ len
, stdout
);
123 fputs(newline_tabs
+ 1, stdout
);
127 SVX_ASSERT(strstr(msg(help
->msg_no
), "%s") != NULL
);
128 printf(msg(help
->msg_no
), help
->arg
);
131 SVX_ASSERT(strstr(msg(help
->msg_no
), "%s") == NULL
);
132 puts(msg(help
->msg_no
));
136 fputs(" --help\t\t\t", stdout
);
137 /* TRANSLATORS: description of --help option */
138 puts(msg(/*display this help and exit*/150));
139 fputs(" --version\t\t\t", stdout
);
140 /* TRANSLATORS: description of --version option */
141 puts(msg(/*output version information and exit*/151));
146 SVX_ASSERT(strstr(msg(msg_extra
), "%s") != NULL
);
147 printf(msg(msg_extra
), msg_extra_arg
);
150 SVX_ASSERT(strstr(msg(msg_extra
), "%s") == NULL
);
151 puts(msg(msg_extra
));
159 cmdline_version(void)
161 printf("%s - "PRETTYPACKAGE
" "VERSION
"\n", msg_appname());
167 /* TRANSLATORS: as in: Usage: cavern … */
168 printf("\n%s: %s", msg(/*Usage*/49), msg_appname());
169 /* TRANSLATORS: in command line usage messages e.g. Usage: cavern [OPTION]… */
170 if (help
&& help
->opt
) printf(" [%s]...", msg(/*OPTION*/153));
178 while (i
--) printf(" %s", msg(/*FILE*/124));
180 if (max_args
== -1) {
181 if (!min_args
) printf(" [%s]", msg(/*FILE*/124));
182 fputs("...", stdout
);
183 } else if (max_args
> min_args
) {
184 int i
= max_args
- min_args
;
185 while (i
--) printf(" [%s]", msg(/*FILE*/124));
191 syntax_and_help_pointer(void)
194 fprintf(stderr
, msg(/*Try “%s --help” for more information.\n*/157),
200 moan_and_die(int msgno
)
202 fprintf(stderr
, "%s: ", msg_appname());
203 fprintf(stderr
, msg(msgno
), optarg
);
210 cmdline_too_few_args(void)
212 fprintf(stderr
, "%s: %s\n", msg_appname(), msg(/*too few arguments*/122));
213 syntax_and_help_pointer();
217 cmdline_too_many_args(void)
219 fprintf(stderr
, "%s: %s\n", msg_appname(), msg(/*too many arguments*/123));
220 syntax_and_help_pointer();
224 cmdline_set_syntax_message(int msg_args_
, int msg_extra_
, const char * arg
)
226 msg_args
= msg_args_
;
227 msg_extra
= msg_extra_
;
232 cmdline_int_arg(void)
239 result
= strtol(optarg
, &endptr
, 10);
241 if (errno
== ERANGE
|| result
> INT_MAX
|| result
< INT_MIN
) {
242 moan_and_die(/*numeric argument “%s” out of range*/185);
243 } else if (*optarg
== '\0' || *endptr
!= '\0') {
244 moan_and_die(/*argument “%s” not an integer*/186);
251 cmdline_double_arg(void)
258 result
= strtod(optarg
, &endptr
);
260 if (errno
== ERANGE
) {
261 moan_and_die(/*numeric argument “%s” out of range*/185);
262 } else if (*optarg
== '\0' || *endptr
!= '\0') {
263 moan_and_die(/*argument “%s” not a number*/187);
270 cmdline_init(int argc_
, char *const *argv_
, const char *shortopts_
,
271 const struct option
*longopts_
, int *longind_
,
272 const struct help_msg
*help_
,
273 int min_args_
, int max_args_
)
277 shortopts
= shortopts_
;
278 longopts
= longopts_
;
281 min_args
= min_args_
;
282 max_args
= max_args_
;
288 int opt
= getopt_long(argc
, argv
, shortopts
, longopts
, longind
);
292 /* check valid # of args given - if not give syntax message */
293 if (argc
- optind
< min_args
) {
294 cmdline_too_few_args();
295 } else if (max_args
>= 0 && argc
- optind
> max_args
) {
296 cmdline_too_many_args();
299 case ':': /* parameter missing */
300 case '?': /* unknown opt, ambiguous match, or extraneous param */
301 /* getopt displays a message for us */
302 syntax_and_help_pointer();
304 case HLP_VERSION
: /* --version */
307 case HLP_HELP
: /* --help */