Empirical
command_line.h
Go to the documentation of this file.
1 // This file is part of Empirical, https://github.com/devosoft/Empirical
2 // Copyright (C) Michigan State University, 2016-2017.
3 // Released under the MIT Software license; see doc/LICENSE
4 //
5 //
6 // This file contains tools for dealing with command-line arguments (argv and argc).
7 //
8 // Functions here include:
9 //
10 // emp::vector<std::string> args_to_strings(int argc, char* argv[]);
11 // - Convert the standard command-line args to a more managable vector of strings.
12 //
13 // int find_arg(const emp::vector<std::string> & args, const std::string & pattern);
14 // - Return index where a specified argument can be found (or -1 if it doesn't exist).
15 //
16 // bool has_arg(const emp::vector<std::string> & args, const std::string & pattern);
17 // - Return true if a particular argument was set on the command line
18 //
19 // bool use_arg(emp::vector<std::string> & args, const std::string & pattern);
20 // - Same as has_arg(), but remove the argument for the set of available args.
21 //
22 //
23 // Development notes:
24 // * Add has_flag() and use_flag() functions to more gracefully handle flags.
25 // For example, if -a and -b are legal flags, -ab should trigger both of them.
26 //
27 // * Process arguments from left-to right, rather than out of order?
28 //
29 // * Identify errors if arguments to a flag begin with a '-' and should be a
30 // flag themselves? Or, more generally, recognize if an argument is clearly
31 // the wrong type (e.g., a string where and int was expected)
32 
33 #ifndef EMP_COMMAND_LINE_H
34 #define EMP_COMMAND_LINE_H
35 
36 #include <string>
37 
38 #include "../base/vector.h"
39 
40 namespace emp {
41  namespace cl {
42 
43  // Convert input arguments to a vector of strings for easier processing.
44  emp::vector<std::string> args_to_strings(int argc, char* argv[]) {
46  for (size_t i = 0; i < (size_t) argc; i++) {
47  args.push_back(argv[i]);
48  }
49  return args;
50  }
51 
52  // Search through args to find a specific value.
53  int find_arg(const emp::vector<std::string> & args, const std::string & pattern) {
54  for (size_t i = 0; i < args.size(); i++) {
55  if (args[i] == pattern) return (int) i;
56  }
57  return -1;
58  }
59 
60  // Return true/false if a specific argument is present.
61  bool has_arg(const emp::vector<std::string> & args, const std::string & pattern) {
62  return (find_arg(args, pattern) != -1);
63  }
64 
65  // Return true/false if a specific argument is present and REMOVE IT.
66  bool use_flag(emp::vector<std::string> & args, const std::string & pattern) {
67  const int pos = find_arg(args, pattern);
68  if (pos >= 0) args.erase(args.begin()+pos);
69  return (pos != -1);
70  }
71 
72  // Return 1 for arg set to value, 0 for arg not found, and -1 for invalid use.
73  // ...assume arg is a single string.
74  int get_arg_value(emp::vector<std::string> & args, const std::string & pattern, std::string & var) {
75  const int pos = find_arg(args, pattern);
76  if (pos == -1) return 0; // Arg not found.
77  if (pos >= (int) args.size() - 1) return -1; // No room for a value!
78  var = args[(size_t)pos+1];
79  return 1;
80  }
81 
82  // ...assume arg is a PAIR of strings.
83  int get_arg_value(emp::vector<std::string> & args, const std::string & pattern,
84  std::string & var1, std::string & var2) {
85  const int pos = find_arg(args, pattern);
86  if (pos == -1) return 0; // Arg not found.
87  if (pos >= (int) args.size() - 2) return -1; // No room for both values!
88  var1 = args[(size_t)pos+1];
89  var2 = args[(size_t)pos+2];
90  return 1;
91  }
92 
93  // ...assume arg is a single int.
94  int get_arg_value(emp::vector<std::string> & args, const std::string & pattern, int & var) {
95  const int pos = find_arg(args, pattern);
96  if (pos == -1) return 0; // Arg not found.
97  if (pos >= (int) args.size() - 1) return -1; // No room for a value!
98  var = stoi(args[(size_t)pos+1]);
99  return 1;
100  }
101 
102  // ...assume arg is a single double.
103  int get_arg_value(emp::vector<std::string> & args, const std::string & pattern, double & var) {
104  const int pos = find_arg(args, pattern);
105  if (pos == -1) return 0; // Arg not found.
106  if (pos >= (int) args.size() - 1) return -1; // No room for a value!
107  var = stod(args[(size_t)pos+1]);
108  return 1;
109  }
110 
111 
112  // Same as get arg_value, but ALSO remove the args.
113  template <typename... Ts>
114  int use_arg_value(emp::vector<std::string> & args, const std::string & pattern, Ts &... vars) {
115  const int result = get_arg_value(args, pattern, vars...);
116  const int pos = find_arg(args, pattern);
117  if (result == 1) args.erase(args.begin()+pos, args.begin()+pos+sizeof...(Ts)+1);
118  return result;
119  }
120 
121 
122  }
123 }
124 
125 #endif
int find_arg(const emp::vector< std::string > &args, const std::string &pattern)
Definition: command_line.h:53
int use_arg_value(emp::vector< std::string > &args, const std::string &pattern, Ts &...vars)
Definition: command_line.h:114
void push_back(PB_Ts &&...args)
Definition: vector.h:189
bool use_flag(emp::vector< std::string > &args, const std::string &pattern)
Definition: command_line.h:66
size_t size() const
Definition: vector.h:151
emp::vector< std::string > args_to_strings(int argc, char *argv[])
Definition: command_line.h:44
iterator begin() noexcept
Definition: vector.h:153
If we are in emscripten, make sure to include the header.
Definition: array.h:37
int get_arg_value(emp::vector< std::string > &args, const std::string &pattern, std::string &var)
Definition: command_line.h:74
iterator erase(ARGS &&...args)
Definition: vector.h:207
bool has_arg(const emp::vector< std::string > &args, const std::string &pattern)
Definition: command_line.h:61