Refine VP10 REFRESH_FRAME_CONTEXT_MODE
[aom.git] / args.c
blob14b031040a4b70057e5fa9485c3d4e045c9842d0
1 /*
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.
9 */
12 #include <stdlib.h>
13 #include <string.h>
14 #include <limits.h>
15 #include "args.h"
17 #include "vpx_ports/msvc.h"
19 #if defined(__GNUC__) && __GNUC__
20 extern void die(const char *fmt, ...) __attribute__((noreturn));
21 #else
22 extern void die(const char *fmt, ...);
23 #endif
26 struct arg arg_init(char **argv) {
27 struct arg a;
29 a.argv = argv;
30 a.argv_step = 1;
31 a.name = NULL;
32 a.val = NULL;
33 a.def = NULL;
34 return a;
37 int arg_match(struct arg *arg_, const struct arg_def *def, char **argv) {
38 struct arg arg;
40 if (!argv[0] || argv[0][0] != '-')
41 return 0;
43 arg = arg_init(argv);
45 if (def->short_name
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;
63 arg.argv_step = 1;
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);
73 if (arg.name
74 && (arg.val || !def->has_val)) {
75 arg.def = def;
76 *arg_ = arg;
77 return 1;
80 return 0;
84 const char *arg_next(struct arg *arg) {
85 if (arg->argv[0])
86 arg->argv += arg->argv_step;
88 return *arg->argv;
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;
97 return new_argv;
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);
124 if (def->enums) {
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) {
138 long int rawval;
139 char *endptr;
141 rawval = strtol(arg->val, &endptr, 10);
143 if (arg->val[0] != '\0' && endptr[0] == '\0') {
144 if (rawval >= 0 && rawval <= UINT_MAX)
145 return rawval;
147 die("Option %s: Value %ld out of range for unsigned int\n",
148 arg->name, rawval);
151 die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
152 return 0;
156 int arg_parse_int(const struct arg *arg) {
157 long int rawval;
158 char *endptr;
160 rawval = strtol(arg->val, &endptr, 10);
162 if (arg->val[0] != '\0' && endptr[0] == '\0') {
163 if (rawval >= INT_MIN && rawval <= INT_MAX)
164 return rawval;
166 die("Option %s: Value %ld out of range for signed int\n",
167 arg->name, rawval);
170 die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
171 return 0;
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) {
180 long int rawval;
181 char *endptr;
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)
189 rat.num = rawval;
190 else die("Option %s: Value %ld out of range for signed int\n",
191 arg->name, rawval);
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)
199 rat.den = rawval;
200 else die("Option %s: Value %ld out of range for signed int\n",
201 arg->name, rawval);
202 } else die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
204 return rat;
208 int arg_parse_enum(const struct arg *arg) {
209 const struct arg_enum_list *listptr;
210 long int rawval;
211 char *endptr;
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)
219 return 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))
225 return listptr->val;
227 die("Option %s: Invalid value '%s'\n", arg->name, arg->val);
228 return 0;
232 int arg_parse_enum_or_int(const struct arg *arg) {
233 if (arg->def->enums)
234 return arg_parse_enum(arg);
235 return arg_parse_int(arg);