Home | History | Annotate | Download | only in libvpx
      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 #ifdef _MSC_VER
     18 #define snprintf _snprintf
     19 #endif
     20 
     21 #if defined(__GNUC__) && __GNUC__
     22 extern void die(const char *fmt, ...) __attribute__((noreturn));
     23 #else
     24 extern void die(const char *fmt, ...);
     25 #endif
     26 
     27 
     28 struct arg arg_init(char **argv) {
     29   struct arg a;
     30 
     31   a.argv      = argv;
     32   a.argv_step = 1;
     33   a.name      = NULL;
     34   a.val       = NULL;
     35   a.def       = NULL;
     36   return a;
     37 }
     38 
     39 int arg_match(struct arg *arg_, const struct arg_def *def, char **argv) {
     40   struct arg arg;
     41 
     42   if (!argv[0] || argv[0][0] != '-')
     43     return 0;
     44 
     45   arg = arg_init(argv);
     46 
     47   if (def->short_name
     48       && strlen(arg.argv[0]) == strlen(def->short_name) + 1
     49       && !strcmp(arg.argv[0] + 1, def->short_name)) {
     50 
     51     arg.name = arg.argv[0] + 1;
     52     arg.val = def->has_val ? arg.argv[1] : NULL;
     53     arg.argv_step = def->has_val ? 2 : 1;
     54   } else if (def->long_name) {
     55     const size_t name_len = strlen(def->long_name);
     56 
     57     if (strlen(arg.argv[0]) >= name_len + 2
     58         && arg.argv[0][1] == '-'
     59         && !strncmp(arg.argv[0] + 2, def->long_name, name_len)
     60         && (arg.argv[0][name_len + 2] == '='
     61             || arg.argv[0][name_len + 2] == '\0')) {
     62 
     63       arg.name = arg.argv[0] + 2;
     64       arg.val = arg.name[name_len] == '=' ? arg.name + name_len + 1 : NULL;
     65       arg.argv_step = 1;
     66     }
     67   }
     68 
     69   if (arg.name && !arg.val && def->has_val)
     70     die("Error: option %s requires argument.\n", arg.name);
     71 
     72   if (arg.name && arg.val && !def->has_val)
     73     die("Error: option %s requires no argument.\n", arg.name);
     74 
     75   if (arg.name
     76       && (arg.val || !def->has_val)) {
     77     arg.def = def;
     78     *arg_ = arg;
     79     return 1;
     80   }
     81 
     82   return 0;
     83 }
     84 
     85 
     86 const char *arg_next(struct arg *arg) {
     87   if (arg->argv[0])
     88     arg->argv += arg->argv_step;
     89 
     90   return *arg->argv;
     91 }
     92 
     93 
     94 char **argv_dup(int argc, const char **argv) {
     95   char **new_argv = malloc((argc + 1) * sizeof(*argv));
     96 
     97   memcpy(new_argv, argv, argc * sizeof(*argv));
     98   new_argv[argc] = NULL;
     99   return new_argv;
    100 }
    101 
    102 
    103 void arg_show_usage(FILE *fp, const struct arg_def *const *defs) {
    104   char option_text[40] = {0};
    105 
    106   for (; *defs; defs++) {
    107     const struct arg_def *def = *defs;
    108     char *short_val = def->has_val ? " <arg>" : "";
    109     char *long_val = def->has_val ? "=<arg>" : "";
    110 
    111     if (def->short_name && def->long_name) {
    112       char *comma = def->has_val ? "," : ",      ";
    113 
    114       snprintf(option_text, 37, "-%s%s%s --%s%6s",
    115                def->short_name, short_val, comma,
    116                def->long_name, long_val);
    117     } else if (def->short_name)
    118       snprintf(option_text, 37, "-%s%s",
    119                def->short_name, short_val);
    120     else if (def->long_name)
    121       snprintf(option_text, 37, "          --%s%s",
    122                def->long_name, long_val);
    123 
    124     fprintf(fp, "  %-37s\t%s\n", option_text, def->desc);
    125 
    126     if (def->enums) {
    127       const struct arg_enum_list *listptr;
    128 
    129       fprintf(fp, "  %-37s\t  ", "");
    130 
    131       for (listptr = def->enums; listptr->name; listptr++)
    132         fprintf(fp, "%s%s", listptr->name,
    133                 listptr[1].name ? ", " : "\n");
    134     }
    135   }
    136 }
    137 
    138 
    139 unsigned int arg_parse_uint(const struct arg *arg) {
    140   long int   rawval;
    141   char      *endptr;
    142 
    143   rawval = strtol(arg->val, &endptr, 10);
    144 
    145   if (arg->val[0] != '\0' && endptr[0] == '\0') {
    146     if (rawval >= 0 && rawval <= UINT_MAX)
    147       return rawval;
    148 
    149     die("Option %s: Value %ld out of range for unsigned int\n",
    150         arg->name, rawval);
    151   }
    152 
    153   die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
    154   return 0;
    155 }
    156 
    157 
    158 int arg_parse_int(const struct arg *arg) {
    159   long int   rawval;
    160   char      *endptr;
    161 
    162   rawval = strtol(arg->val, &endptr, 10);
    163 
    164   if (arg->val[0] != '\0' && endptr[0] == '\0') {
    165     if (rawval >= INT_MIN && rawval <= INT_MAX)
    166       return rawval;
    167 
    168     die("Option %s: Value %ld out of range for signed int\n",
    169         arg->name, rawval);
    170   }
    171 
    172   die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
    173   return 0;
    174 }
    175 
    176 
    177 struct vpx_rational {
    178   int num; /**< fraction numerator */
    179   int den; /**< fraction denominator */
    180 };
    181 struct vpx_rational arg_parse_rational(const struct arg *arg) {
    182   long int             rawval;
    183   char                *endptr;
    184   struct vpx_rational  rat;
    185 
    186   /* parse numerator */
    187   rawval = strtol(arg->val, &endptr, 10);
    188 
    189   if (arg->val[0] != '\0' && endptr[0] == '/') {
    190     if (rawval >= INT_MIN && rawval <= INT_MAX)
    191       rat.num = rawval;
    192     else die("Option %s: Value %ld out of range for signed int\n",
    193                arg->name, rawval);
    194   } else die("Option %s: Expected / at '%c'\n", arg->name, *endptr);
    195 
    196   /* parse denominator */
    197   rawval = strtol(endptr + 1, &endptr, 10);
    198 
    199   if (arg->val[0] != '\0' && endptr[0] == '\0') {
    200     if (rawval >= INT_MIN && rawval <= INT_MAX)
    201       rat.den = rawval;
    202     else die("Option %s: Value %ld out of range for signed int\n",
    203                arg->name, rawval);
    204   } else die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
    205 
    206   return rat;
    207 }
    208 
    209 
    210 int arg_parse_enum(const struct arg *arg) {
    211   const struct arg_enum_list *listptr;
    212   long int                    rawval;
    213   char                       *endptr;
    214 
    215   /* First see if the value can be parsed as a raw value */
    216   rawval = strtol(arg->val, &endptr, 10);
    217   if (arg->val[0] != '\0' && endptr[0] == '\0') {
    218     /* Got a raw value, make sure it's valid */
    219     for (listptr = arg->def->enums; listptr->name; listptr++)
    220       if (listptr->val == rawval)
    221         return rawval;
    222   }
    223 
    224   /* Next see if it can be parsed as a string */
    225   for (listptr = arg->def->enums; listptr->name; listptr++)
    226     if (!strcmp(arg->val, listptr->name))
    227       return listptr->val;
    228 
    229   die("Option %s: Invalid value '%s'\n", arg->name, arg->val);
    230   return 0;
    231 }
    232 
    233 
    234 int arg_parse_enum_or_int(const struct arg *arg) {
    235   if (arg->def->enums)
    236     return arg_parse_enum(arg);
    237   return arg_parse_int(arg);
    238 }
    239