cmd_line.hpp
Go to the documentation of this file.
1 #ifndef STAN_IO_CMD_LINE_HPP
2 #define STAN_IO_CMD_LINE_HPP
3 
4 #include <map>
5 #include <ostream>
6 #include <set>
7 #include <string>
8 #include <sstream>
9 #include <vector>
10 
11 namespace stan {
12 
13  namespace io {
14 
15  /**
16  * Print help option with padding.
17  *
18  * Print 2 spaces, the specified help option, then pad
19  * to the specified width with spaces. If there is not
20  * room for at least 2 padding spaces, start a new line
21  * and pad out to width.
22  *
23  * @param option Option to print (default to empty string).
24  * @param width Width of option (defaults to 20).
25  * @param o Output stream ptr, default to null
26  */
27  inline void pad_help_option(std::ostream* o,
28  const std::string& option = "",
29  unsigned int width = 20) {
30  if (!o) return;
31  *o << " " << option;
32  int padding = width - option.size();
33  if (padding < 2) {
34  *o << std::endl;
35  padding = width + 2; // 2 is
36  }
37  for (int i = 0; i < padding; ++i)
38  *o << ' ';
39  }
40 
41  /**
42  * Prints single print option to output ptr if non-null.
43  *
44  * @param o
45  * @param key_val
46  * @param msg
47  * @param note
48  */
49  inline void print_help_helper(std::ostream* o,
50  const std::string& key_val,
51  const std::string& msg,
52  const std::string& note = "") {
53  if (!o) return;
54  pad_help_option(o, key_val);
55  *o << msg
56  << std::endl;
57  if (note.size() > 0) {
58  pad_help_option(o, "");
59  *o << " (" << note << ")"
60  << std::endl;
61  }
62  *o << std::endl;
63  }
64 
65  /**
66  * Prints single print option to output ptr if non-null.
67  *
68  * @param o
69  * @param key
70  * @param value_type
71  * @param msg
72  * @param note
73  */
74  inline void print_help_option(std::ostream* o,
75  const std::string& key,
76  const std::string& value_type,
77  const std::string& msg,
78  const std::string& note = "") {
79  std::stringstream ss;
80  ss << "--" << key;
81  if (value_type.size() > 0)
82  ss << "=<" << value_type << ">";
83  print_help_helper(o, ss.str(), msg, note);
84  }
85 
86  /**
87  * Parses and stores command-line arguments.
88  *
89  * <p>Command-line arguments are organized into four types.
90  *
91  * <p><b>Command</b>: The first argument (at index 0) is just the
92  * command itself. There method <code>command()</code> retrieves
93  * the command.
94  *
95  * <p><b>Key/Value</b>: The second type of argument is a key-value pair,
96  * which must be in the form <code>--key=val</code>. Two hyphens
97  * are used to separate arguments from negated numbers. The method
98  * <code>has_key(const std::string&)</code> indicates if there is a key
99  * and <code>val(const std::string&,T&)</code> writes its value into
100  * a reference (whose type is templated; any type understand by the
101  * output operator <code>&gt;&gt;</code> is acceptable.
102  *
103  * <p><b>Flag</b>: Flags are specified as <code>--flag</code>. The
104  * method <code>has_flag(const std::string&)</code> tests if a flag
105  * is present.
106  *
107  * <p><b>Bare Argument</b>: Bare arguments are any arguments that
108  * are not prefixed with two hyphens (<code>--</code>). The
109  * method <code>bare_size()</code> returns the number of bare
110  * arguments and they are retrieved with the generic method
111  * <code>bare(const std::string&,T&)</code>.
112  */
113  class cmd_line {
114  private:
116  std::map<std::string, std::string> key_val_;
117  std::set<std::string> flag_;
118  std::vector<std::string> bare_;
119  void parse_arg(const std::string& s) {
120  if (s.size() < 2
121  || s[0] != '-'
122  || s[1] != '-') {
123  bare_.push_back(s);
124  return;
125  }
126  for (size_t i = 2; i < s.size(); ++i) {
127  if (s[i] == '=') {
128  key_val_[s.substr(2, i - 2)] = s.substr(i + 1, s.size() - i - 1);
129  return;
130  }
131  }
132  flag_.insert(s.substr(2, s.size()));
133  }
134 
135  public:
136  /**
137  * Construct a command-line argument object from the specified
138  * command-line arguments.
139  *
140  * @param argc Number of arguments.
141  * @param argv Argument strings.
142  */
143  cmd_line(int argc, const char* argv[])
144  : cmd_(argv[0]) {
145  for (int i = 1; i < argc; ++i)
146  parse_arg(argv[i]);
147  }
148 
149  /**
150  * Returns the name of the command itself. The
151  * command is always supplied as the first argument
152  * (at index 0).
153  *
154  * @return Name of command.
155  */
157  return cmd_;
158  }
159 
160  /**
161  * Return <code>true</code> if the specified key is defined.
162  *
163  * @param key Key to test.
164  * @return <code>true</code> if it has a value.
165  */
166  bool has_key(const std::string& key) const {
167  return key_val_.find(key) != key_val_.end();
168  }
169 
170  /**
171  * Returns the value for the key provided.
172  *
173  * If the specified key is defined, write the value of the key
174  * into the specified reference and return <code>true</code>,
175  * otherwise do not modify the reference and return
176  * <code>false</code>.
177  *
178  * <p>The conversions defined by <code>std::ostream</code>
179  * are used to convert the base string value to the specified
180  * type. Thus this method will work as long as <code>operator>>()</code>
181  * is defined for the specified type.
182  *
183  * @param[in] key Key whose value is returned.
184  * @param[out] x Reference to value.
185  * @return False if the key is not found, and true if
186  * it is found.
187  * @tparam Type of value.
188  */
189  template <typename T>
190  inline bool val(const std::string& key, T& x) const {
191  if (!has_key(key))
192  return false;
193  std::stringstream s(key_val_.find(key)->second);
194  s >> x;
195  return true;
196  }
197 
198  /**
199  * Return <code>true</code> if the specified flag is defined.
200  *
201  * @param flag Flag to test.
202  * @return <code>true</code> if flag is defined.
203  */
204  bool has_flag(const std::string& flag) const {
205  return flag_.find(flag) != flag_.end();
206  }
207 
208  /**
209  * Return the number of bare arguments.
210  *
211  * @return Number of bare arguments.
212  */
213  inline size_t bare_size() const {
214  return bare_.size();
215  }
216 
217  /**
218  * Returns the bare argument.
219  *
220  * If the specified index is valid for bare arguments,
221  * write the bare argument at the specified index into
222  * the specified reference, and otherwise return false
223  * without modifying the reference.
224  *
225  * @param[in] n Bare argument position.
226  * @param[out] x Reference to result.
227  * @return <code>true</code> if there were enough bare arguments.
228  * @tparam T Type of value returned.
229  */
230  template <typename T>
231  inline bool bare(size_t n, T& x) const {
232  if (n >= bare_.size())
233  return false;
234  std::stringstream s(bare_[n]);
235  s >> x;
236  return true;
237  }
238 
239 
240  /**
241  * Print a human readable parsed form of the command-line
242  * arguments to the specified output stream.
243  *
244  * @param[out] out Output stream.
245  */
246  void print(std::ostream& out) const {
247  out << "COMMAND=" << cmd_ << '\n';
248  size_t flag_count = 0;
249  for (std::set<std::string>::const_iterator it = flag_.begin();
250  it != flag_.end();
251  ++it) {
252  out << "FLAG " << flag_count << "=" << (*it) << '\n';
253  ++flag_count;
254  }
255  size_t key_val_count = 0;
256  for (std::map<std::string, std::string>::const_iterator it
257  = key_val_.begin();
258  it != key_val_.end();
259  ++it) {
260  out << "KEY " << key_val_count << "=" << (*it).first;
261  out << " VAL " << key_val_count << "=" << (*it).second << '\n';
262  ++key_val_count;
263  }
264  size_t bare_count = 0;
265  for (size_t i = 0; i < bare_.size(); ++i) {
266  out << "BARE ARG " << bare_count << "=" << bare_[i] << '\n';
267  ++bare_count;
268  }
269  }
270  };
271 
272  // explicit instantation for std::string to allow for spaces
273  // in bare_[n]
274  template <>
275  inline bool cmd_line::bare<std::string>(size_t n, std::string& x) const {
276  if (n >= bare_.size())
277  return false;
278  x = bare_[n];
279  return true;
280  }
281 
282  // explicit instantation for std::string to allow for spaces
283  // in key_val_
284  template <>
285  inline bool cmd_line::val<std::string>(const std::string& key,
286  std::string& x) const {
287  if (!has_key(key))
288  return false;
289  x = key_val_.find(key)->second;
290  return true;
291  }
292  }
293 }
294 
295 #endif
set< int >::iterator it
void pad_help_option(std::ostream *o, const std::string &option="", unsigned int width=20)
Definition: cmd_line.hpp:27
std::set< std::string > flag_
Definition: cmd_line.hpp:117
Float_t ss
Definition: plot.C:24
bool val(const std::string &key, T &x) const
Definition: cmd_line.hpp:190
bool has_key(const std::string &key) const
Definition: cmd_line.hpp:166
cmd_line(int argc, const char *argv[])
Definition: cmd_line.hpp:143
void parse_arg(const std::string &s)
Definition: cmd_line.hpp:119
std::vector< std::string > bare_
Definition: cmd_line.hpp:118
const XML_Char * s
Definition: expat.h:262
std::string cmd_
Definition: cmd_line.hpp:115
bool has_flag(const std::string &flag) const
Definition: cmd_line.hpp:204
void print_help_helper(std::ostream *o, const std::string &key_val, const std::string &msg, const std::string &note="")
Definition: cmd_line.hpp:49
size_t bare_size() const
Definition: cmd_line.hpp:213
std::map< std::string, std::string > key_val_
Definition: cmd_line.hpp:116
::xsd::cxx::tree::string< char, simple_type > string
Definition: Database.h:154
void print(std::ostream &out) const
Definition: cmd_line.hpp:246
bool bare(size_t n, T &x) const
Definition: cmd_line.hpp:231
void print_help_option(std::ostream *o, const std::string &key, const std::string &value_type, const std::string &msg, const std::string &note="")
Definition: cmd_line.hpp:74
double T
Definition: Xdiff_gwt.C:5
std::string command()
Definition: cmd_line.hpp:156