Home | History | Annotate | Download | only in tool
      1 /* Copyright (c) 2014, Google Inc.
      2  *
      3  * Permission to use, copy, modify, and/or distribute this software for any
      4  * purpose with or without fee is hereby granted, provided that the above
      5  * copyright notice and this permission notice appear in all copies.
      6  *
      7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
     10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
     12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
     13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
     14 
     15 #include <string>
     16 #include <vector>
     17 
     18 #include <limits.h>
     19 #include <stdio.h>
     20 #include <stdlib.h>
     21 #include <string.h>
     22 
     23 #include "internal.h"
     24 
     25 
     26 bool ParseKeyValueArguments(std::map<std::string, std::string> *out_args,
     27                             const std::vector<std::string> &args,
     28                             const struct argument *templates) {
     29   out_args->clear();
     30 
     31   for (size_t i = 0; i < args.size(); i++) {
     32     const std::string &arg = args[i];
     33     const struct argument *templ = nullptr;
     34     for (size_t j = 0; templates[j].name[0] != 0; j++) {
     35       if (strcmp(arg.c_str(), templates[j].name) == 0) {
     36         templ = &templates[j];
     37         break;
     38       }
     39     }
     40 
     41     if (templ == nullptr) {
     42       fprintf(stderr, "Unknown argument: %s\n", arg.c_str());
     43       return false;
     44     }
     45 
     46     if (out_args->find(arg) != out_args->end()) {
     47       fprintf(stderr, "Duplicate argument: %s\n", arg.c_str());
     48       return false;
     49     }
     50 
     51     if (templ->type == kBooleanArgument) {
     52       (*out_args)[arg] = "";
     53     } else {
     54       if (i + 1 >= args.size()) {
     55         fprintf(stderr, "Missing argument for option: %s\n", arg.c_str());
     56         return false;
     57       }
     58       (*out_args)[arg] = args[++i];
     59     }
     60   }
     61 
     62   for (size_t j = 0; templates[j].name[0] != 0; j++) {
     63     const struct argument *templ = &templates[j];
     64     if (templ->type == kRequiredArgument &&
     65         out_args->find(templ->name) == out_args->end()) {
     66       fprintf(stderr, "Missing value for required argument: %s\n", templ->name);
     67       return false;
     68     }
     69   }
     70 
     71   return true;
     72 }
     73 
     74 void PrintUsage(const struct argument *templates) {
     75   for (size_t i = 0; templates[i].name[0] != 0; i++) {
     76     const struct argument *templ = &templates[i];
     77     fprintf(stderr, "%s\t%s\n", templ->name, templ->description);
     78   }
     79 }
     80 
     81 bool GetUnsigned(unsigned *out, const std::string &arg_name,
     82                  unsigned default_value,
     83                  const std::map<std::string, std::string> &args) {
     84   const auto &it = args.find(arg_name);
     85   if (it == args.end()) {
     86     *out = default_value;
     87     return true;
     88   }
     89 
     90   const std::string &value = it->second;
     91   if (value.empty()) {
     92     return false;
     93   }
     94 
     95   char *endptr;
     96   unsigned long int num = strtoul(value.c_str(), &endptr, 10);
     97   if (*endptr ||
     98       num > UINT_MAX) {
     99     return false;
    100   }
    101 
    102   *out = num;
    103   return true;
    104 }
    105