190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/*
2f71323e297a928af368937089d3ed71239786f86Andreas Huber *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
4f71323e297a928af368937089d3ed71239786f86Andreas Huber *  Use of this source code is governed by a BSD-style license
5f71323e297a928af368937089d3ed71239786f86Andreas Huber *  that can be found in the LICENSE file in the root of the source
6f71323e297a928af368937089d3ed71239786f86Andreas Huber *  tree. An additional intellectual property rights grant can be found
7f71323e297a928af368937089d3ed71239786f86Andreas Huber *  in the file PATENTS.  All contributing project authors may
8f71323e297a928af368937089d3ed71239786f86Andreas Huber *  be found in the AUTHORS file in the root of the source tree.
990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber */
1090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <stdlib.h>
1390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <string.h>
1490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <limits.h>
1590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include "args.h"
1690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#ifdef _MSC_VER
1890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define snprintf _snprintf
1990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
2090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#if defined(__GNUC__) && __GNUC__
2290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberextern void die(const char *fmt, ...) __attribute__((noreturn));
2390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#else
2490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberextern void die(const char *fmt, ...);
2590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#endif
2690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
28ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstruct arg arg_init(char **argv) {
29ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct arg a;
30ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
31ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  a.argv      = argv;
32ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  a.argv_step = 1;
33ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  a.name      = NULL;
34ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  a.val       = NULL;
35ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  a.def       = NULL;
36ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return a;
3790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
3890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
39ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangint arg_match(struct arg *arg_, const struct arg_def *def, char **argv) {
40ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct arg arg;
4190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
42ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!argv[0] || argv[0][0] != '-')
43ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return 0;
4490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
45ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  arg = arg_init(argv);
4690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
47ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (def->short_name
48ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      && strlen(arg.argv[0]) == strlen(def->short_name) + 1
49ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      && !strcmp(arg.argv[0] + 1, def->short_name)) {
5090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
51ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    arg.name = arg.argv[0] + 1;
52ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    arg.val = def->has_val ? arg.argv[1] : NULL;
53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    arg.argv_step = def->has_val ? 2 : 1;
54ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else if (def->long_name) {
55ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const size_t name_len = strlen(def->long_name);
56ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
57ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (strlen(arg.argv[0]) >= name_len + 2
58ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        && arg.argv[0][1] == '-'
59ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        && !strncmp(arg.argv[0] + 2, def->long_name, name_len)
60ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        && (arg.argv[0][name_len + 2] == '='
61ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            || arg.argv[0][name_len + 2] == '\0')) {
62ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
63ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      arg.name = arg.argv[0] + 2;
64ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      arg.val = arg.name[name_len] == '=' ? arg.name + name_len + 1 : NULL;
65ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      arg.argv_step = 1;
6690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
67ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
6890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
69ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (arg.name && !arg.val && def->has_val)
70ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    die("Error: option %s requires argument.\n", arg.name);
7190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
72ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (arg.name && arg.val && !def->has_val)
73ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    die("Error: option %s requires no argument.\n", arg.name);
7490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
75ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (arg.name
76ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      && (arg.val || !def->has_val)) {
77ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    arg.def = def;
78ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *arg_ = arg;
79ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return 1;
80ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
8190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
82ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return 0;
8390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
8490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
8590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
86ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangconst char *arg_next(struct arg *arg) {
87ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (arg->argv[0])
88ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    arg->argv += arg->argv_step;
8990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
90ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return *arg->argv;
9190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
9290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
9390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
94ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangchar **argv_dup(int argc, const char **argv) {
95ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  char **new_argv = malloc((argc + 1) * sizeof(*argv));
9690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
97ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  memcpy(new_argv, argv, argc * sizeof(*argv));
98ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  new_argv[argc] = NULL;
99ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return new_argv;
10090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
10190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
10290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
103ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid arg_show_usage(FILE *fp, const struct arg_def *const *defs) {
104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  char option_text[40] = {0};
10590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (; *defs; defs++) {
107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const struct arg_def *def = *defs;
108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    char *short_val = def->has_val ? " <arg>" : "";
109ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    char *long_val = def->has_val ? "=<arg>" : "";
11090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (def->short_name && def->long_name) {
112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      char *comma = def->has_val ? "," : ",      ";
113538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
114ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      snprintf(option_text, 37, "-%s%s%s --%s%6s",
115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang               def->short_name, short_val, comma,
116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang               def->long_name, long_val);
117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else if (def->short_name)
118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      snprintf(option_text, 37, "-%s%s",
119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang               def->short_name, short_val);
120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    else if (def->long_name)
121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      snprintf(option_text, 37, "          --%s%s",
122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang               def->long_name, long_val);
12390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    fprintf(fp, "  %-37s\t%s\n", option_text, def->desc);
12579f15823c34ae1e423108295e416213200bb280fAndreas Huber
126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (def->enums) {
127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      const struct arg_enum_list *listptr;
12879f15823c34ae1e423108295e416213200bb280fAndreas Huber
129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      fprintf(fp, "  %-37s\t  ", "");
13079f15823c34ae1e423108295e416213200bb280fAndreas Huber
131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (listptr = def->enums; listptr->name; listptr++)
132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        fprintf(fp, "%s%s", listptr->name,
133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                listptr[1].name ? ", " : "\n");
13490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
13690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
13790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
13890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangunsigned int arg_parse_uint(const struct arg *arg) {
140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  long int   rawval;
141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  char      *endptr;
14290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  rawval = strtol(arg->val, &endptr, 10);
14490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (arg->val[0] != '\0' && endptr[0] == '\0') {
146ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (rawval >= 0 && rawval <= UINT_MAX)
147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      return rawval;
14890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
149ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    die("Option %s: Value %ld out of range for unsigned int\n",
150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        arg->name, rawval);
151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
15290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return 0;
15590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
15690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
15790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangint arg_parse_int(const struct arg *arg) {
159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  long int   rawval;
160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  char      *endptr;
16190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  rawval = strtol(arg->val, &endptr, 10);
16390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (arg->val[0] != '\0' && endptr[0] == '\0') {
165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (rawval >= INT_MIN && rawval <= INT_MAX)
166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      return rawval;
16790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    die("Option %s: Value %ld out of range for signed int\n",
169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        arg->name, rawval);
170ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
17190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
173ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return 0;
17490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
17590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
17690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstruct vpx_rational {
178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int num; /**< fraction numerator */
179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int den; /**< fraction denominator */
18090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber};
181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstruct vpx_rational arg_parse_rational(const struct arg *arg) {
182ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  long int             rawval;
183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  char                *endptr;
184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct vpx_rational  rat;
185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* parse numerator */
187ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  rawval = strtol(arg->val, &endptr, 10);
188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (arg->val[0] != '\0' && endptr[0] == '/') {
190ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (rawval >= INT_MIN && rawval <= INT_MAX)
191ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      rat.num = rawval;
192ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    else die("Option %s: Value %ld out of range for signed int\n",
193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang               arg->name, rawval);
194ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else die("Option %s: Expected / at '%c'\n", arg->name, *endptr);
195ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
196ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* parse denominator */
197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  rawval = strtol(endptr + 1, &endptr, 10);
198ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
199ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (arg->val[0] != '\0' && endptr[0] == '\0') {
200ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (rawval >= INT_MIN && rawval <= INT_MAX)
201ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      rat.den = rawval;
202ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    else die("Option %s: Value %ld out of range for signed int\n",
203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang               arg->name, rawval);
204ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
205ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
206ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return rat;
20790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
20879f15823c34ae1e423108295e416213200bb280fAndreas Huber
20979f15823c34ae1e423108295e416213200bb280fAndreas Huber
210ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangint arg_parse_enum(const struct arg *arg) {
211ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const struct arg_enum_list *listptr;
212ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  long int                    rawval;
213ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  char                       *endptr;
21479f15823c34ae1e423108295e416213200bb280fAndreas Huber
215ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* First see if the value can be parsed as a raw value */
216ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  rawval = strtol(arg->val, &endptr, 10);
217ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (arg->val[0] != '\0' && endptr[0] == '\0') {
218ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    /* Got a raw value, make sure it's valid */
219ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (listptr = arg->def->enums; listptr->name; listptr++)
220ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (listptr->val == rawval)
221ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        return rawval;
222ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
22379f15823c34ae1e423108295e416213200bb280fAndreas Huber
224ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Next see if it can be parsed as a string */
225ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (listptr = arg->def->enums; listptr->name; listptr++)
226ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (!strcmp(arg->val, listptr->name))
227ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      return listptr->val;
228ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
229ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  die("Option %s: Invalid value '%s'\n", arg->name, arg->val);
230ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return 0;
23179f15823c34ae1e423108295e416213200bb280fAndreas Huber}
23279f15823c34ae1e423108295e416213200bb280fAndreas Huber
23379f15823c34ae1e423108295e416213200bb280fAndreas Huber
234ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangint arg_parse_enum_or_int(const struct arg *arg) {
235ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (arg->def->enums)
236ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return arg_parse_enum(arg);
237ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return arg_parse_int(arg);
23879f15823c34ae1e423108295e416213200bb280fAndreas Huber}
239