2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
17 #include "vpx_ports/msvc.h"
19 #if defined(__GNUC__) && __GNUC__
20 extern void die(const char *fmt
, ...) __attribute__((noreturn
));
22 extern void die(const char *fmt
, ...);
26 struct arg
arg_init(char **argv
) {
37 int arg_match(struct arg
*arg_
, const struct arg_def
*def
, char **argv
) {
40 if (!argv
[0] || argv
[0][0] != '-')
46 && strlen(arg
.argv
[0]) == strlen(def
->short_name
) + 1
47 && !strcmp(arg
.argv
[0] + 1, def
->short_name
)) {
49 arg
.name
= arg
.argv
[0] + 1;
50 arg
.val
= def
->has_val
? arg
.argv
[1] : NULL
;
51 arg
.argv_step
= def
->has_val
? 2 : 1;
52 } else if (def
->long_name
) {
53 const size_t name_len
= strlen(def
->long_name
);
55 if (strlen(arg
.argv
[0]) >= name_len
+ 2
56 && arg
.argv
[0][1] == '-'
57 && !strncmp(arg
.argv
[0] + 2, def
->long_name
, name_len
)
58 && (arg
.argv
[0][name_len
+ 2] == '='
59 || arg
.argv
[0][name_len
+ 2] == '\0')) {
61 arg
.name
= arg
.argv
[0] + 2;
62 arg
.val
= arg
.name
[name_len
] == '=' ? arg
.name
+ name_len
+ 1 : NULL
;
67 if (arg
.name
&& !arg
.val
&& def
->has_val
)
68 die("Error: option %s requires argument.\n", arg
.name
);
70 if (arg
.name
&& arg
.val
&& !def
->has_val
)
71 die("Error: option %s requires no argument.\n", arg
.name
);
74 && (arg
.val
|| !def
->has_val
)) {
84 const char *arg_next(struct arg
*arg
) {
86 arg
->argv
+= arg
->argv_step
;
92 char **argv_dup(int argc
, const char **argv
) {
93 char **new_argv
= malloc((argc
+ 1) * sizeof(*argv
));
95 memcpy(new_argv
, argv
, argc
* sizeof(*argv
));
96 new_argv
[argc
] = NULL
;
101 void arg_show_usage(FILE *fp
, const struct arg_def
*const *defs
) {
102 char option_text
[40] = {0};
104 for (; *defs
; defs
++) {
105 const struct arg_def
*def
= *defs
;
106 char *short_val
= def
->has_val
? " <arg>" : "";
107 char *long_val
= def
->has_val
? "=<arg>" : "";
109 if (def
->short_name
&& def
->long_name
) {
110 char *comma
= def
->has_val
? "," : ", ";
112 snprintf(option_text
, 37, "-%s%s%s --%s%6s",
113 def
->short_name
, short_val
, comma
,
114 def
->long_name
, long_val
);
115 } else if (def
->short_name
)
116 snprintf(option_text
, 37, "-%s%s",
117 def
->short_name
, short_val
);
118 else if (def
->long_name
)
119 snprintf(option_text
, 37, " --%s%s",
120 def
->long_name
, long_val
);
122 fprintf(fp
, " %-37s\t%s\n", option_text
, def
->desc
);
125 const struct arg_enum_list
*listptr
;
127 fprintf(fp
, " %-37s\t ", "");
129 for (listptr
= def
->enums
; listptr
->name
; listptr
++)
130 fprintf(fp
, "%s%s", listptr
->name
,
131 listptr
[1].name
? ", " : "\n");
137 unsigned int arg_parse_uint(const struct arg
*arg
) {
141 rawval
= strtol(arg
->val
, &endptr
, 10);
143 if (arg
->val
[0] != '\0' && endptr
[0] == '\0') {
144 if (rawval
>= 0 && rawval
<= UINT_MAX
)
147 die("Option %s: Value %ld out of range for unsigned int\n",
151 die("Option %s: Invalid character '%c'\n", arg
->name
, *endptr
);
156 int arg_parse_int(const struct arg
*arg
) {
160 rawval
= strtol(arg
->val
, &endptr
, 10);
162 if (arg
->val
[0] != '\0' && endptr
[0] == '\0') {
163 if (rawval
>= INT_MIN
&& rawval
<= INT_MAX
)
166 die("Option %s: Value %ld out of range for signed int\n",
170 die("Option %s: Invalid character '%c'\n", arg
->name
, *endptr
);
175 struct vpx_rational
{
176 int num
; /**< fraction numerator */
177 int den
; /**< fraction denominator */
179 struct vpx_rational
arg_parse_rational(const struct arg
*arg
) {
182 struct vpx_rational rat
;
184 /* parse numerator */
185 rawval
= strtol(arg
->val
, &endptr
, 10);
187 if (arg
->val
[0] != '\0' && endptr
[0] == '/') {
188 if (rawval
>= INT_MIN
&& rawval
<= INT_MAX
)
190 else die("Option %s: Value %ld out of range for signed int\n",
192 } else die("Option %s: Expected / at '%c'\n", arg
->name
, *endptr
);
194 /* parse denominator */
195 rawval
= strtol(endptr
+ 1, &endptr
, 10);
197 if (arg
->val
[0] != '\0' && endptr
[0] == '\0') {
198 if (rawval
>= INT_MIN
&& rawval
<= INT_MAX
)
200 else die("Option %s: Value %ld out of range for signed int\n",
202 } else die("Option %s: Invalid character '%c'\n", arg
->name
, *endptr
);
208 int arg_parse_enum(const struct arg
*arg
) {
209 const struct arg_enum_list
*listptr
;
213 /* First see if the value can be parsed as a raw value */
214 rawval
= strtol(arg
->val
, &endptr
, 10);
215 if (arg
->val
[0] != '\0' && endptr
[0] == '\0') {
216 /* Got a raw value, make sure it's valid */
217 for (listptr
= arg
->def
->enums
; listptr
->name
; listptr
++)
218 if (listptr
->val
== rawval
)
222 /* Next see if it can be parsed as a string */
223 for (listptr
= arg
->def
->enums
; listptr
->name
; listptr
++)
224 if (!strcmp(arg
->val
, listptr
->name
))
227 die("Option %s: Invalid value '%s'\n", arg
->name
, arg
->val
);
232 int arg_parse_enum_or_int(const struct arg
*arg
) {
234 return arg_parse_enum(arg
);
235 return arg_parse_int(arg
);