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