]> granicus.if.org Git - libvpx/blob - args.c
Merge "vp9: Change the scheme for modeling rd for 32x32 on newmv_last mode."
[libvpx] / args.c
1 /*
2  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3  *
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  */
10
11
12 #include <stdlib.h>
13 #include <string.h>
14 #include <limits.h>
15 #include "args.h"
16
17 #include "vpx_ports/msvc.h"
18
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
24
25
26 struct arg arg_init(char **argv) {
27   struct arg a;
28
29   a.argv      = argv;
30   a.argv_step = 1;
31   a.name      = NULL;
32   a.val       = NULL;
33   a.def       = NULL;
34   return a;
35 }
36
37 int arg_match(struct arg *arg_, const struct arg_def *def, char **argv) {
38   struct arg arg;
39
40   if (!argv[0] || argv[0][0] != '-')
41     return 0;
42
43   arg = arg_init(argv);
44
45   if (def->short_name
46       && strlen(arg.argv[0]) == strlen(def->short_name) + 1
47       && !strcmp(arg.argv[0] + 1, def->short_name)) {
48
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);
54
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')) {
60
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;
64     }
65   }
66
67   if (arg.name && !arg.val && def->has_val)
68     die("Error: option %s requires argument.\n", arg.name);
69
70   if (arg.name && arg.val && !def->has_val)
71     die("Error: option %s requires no argument.\n", arg.name);
72
73   if (arg.name
74       && (arg.val || !def->has_val)) {
75     arg.def = def;
76     *arg_ = arg;
77     return 1;
78   }
79
80   return 0;
81 }
82
83
84 const char *arg_next(struct arg *arg) {
85   if (arg->argv[0])
86     arg->argv += arg->argv_step;
87
88   return *arg->argv;
89 }
90
91
92 char **argv_dup(int argc, const char **argv) {
93   char **new_argv = malloc((argc + 1) * sizeof(*argv));
94
95   memcpy(new_argv, argv, argc * sizeof(*argv));
96   new_argv[argc] = NULL;
97   return new_argv;
98 }
99
100
101 void arg_show_usage(FILE *fp, const struct arg_def *const *defs) {
102   char option_text[40] = {0};
103
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>" : "";
108
109     if (def->short_name && def->long_name) {
110       char *comma = def->has_val ? "," : ",      ";
111
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);
121
122     fprintf(fp, "  %-37s\t%s\n", option_text, def->desc);
123
124     if (def->enums) {
125       const struct arg_enum_list *listptr;
126
127       fprintf(fp, "  %-37s\t  ", "");
128
129       for (listptr = def->enums; listptr->name; listptr++)
130         fprintf(fp, "%s%s", listptr->name,
131                 listptr[1].name ? ", " : "\n");
132     }
133   }
134 }
135
136
137 unsigned int arg_parse_uint(const struct arg *arg) {
138   long int   rawval;
139   char      *endptr;
140
141   rawval = strtol(arg->val, &endptr, 10);
142
143   if (arg->val[0] != '\0' && endptr[0] == '\0') {
144     if (rawval >= 0 && rawval <= UINT_MAX)
145       return rawval;
146
147     die("Option %s: Value %ld out of range for unsigned int\n",
148         arg->name, rawval);
149   }
150
151   die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
152   return 0;
153 }
154
155
156 int arg_parse_int(const struct arg *arg) {
157   long int   rawval;
158   char      *endptr;
159
160   rawval = strtol(arg->val, &endptr, 10);
161
162   if (arg->val[0] != '\0' && endptr[0] == '\0') {
163     if (rawval >= INT_MIN && rawval <= INT_MAX)
164       return rawval;
165
166     die("Option %s: Value %ld out of range for signed int\n",
167         arg->name, rawval);
168   }
169
170   die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
171   return 0;
172 }
173
174
175 struct vpx_rational {
176   int num; /**< fraction numerator */
177   int den; /**< fraction denominator */
178 };
179 struct vpx_rational arg_parse_rational(const struct arg *arg) {
180   long int             rawval;
181   char                *endptr;
182   struct vpx_rational  rat;
183
184   /* parse numerator */
185   rawval = strtol(arg->val, &endptr, 10);
186
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);
193
194   /* parse denominator */
195   rawval = strtol(endptr + 1, &endptr, 10);
196
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);
203
204   return rat;
205 }
206
207
208 int arg_parse_enum(const struct arg *arg) {
209   const struct arg_enum_list *listptr;
210   long int                    rawval;
211   char                       *endptr;
212
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;
220   }
221
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;
226
227   die("Option %s: Invalid value '%s'\n", arg->name, arg->val);
228   return 0;
229 }
230
231
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);
236 }