Templates -- Meow  1.1.4
A C++ template which is unable and also not allowed to compile to obj-file first.
Usage.hpp
Go to the documentation of this file.
1 #include <string>
2 #include <cstdint>
3 #include <vector>
4 #include <map>
5 #include <algorithm>
6 #include <cstdlib>
7 
8 #include "utility.h"
9 
10 extern "C"{
11 #include <unistd.h>
12 }
13 
14 namespace meow{
15  inline Usage::Usage(){ name = "nobody"; }
16  inline Usage::Usage(std::string const& _name){ name = _name; }
17  inline bool Usage::import(Usage const& usage){
18  OptionsIterator it;
19  for(it = usage.options.begin(); it != usage.options.end(); it++){
20  unsigned char const& chr = it->first;
21  Option const& opt = it->second;
22  if(options.find(chr) == options.end()){
23  options[chr] = opt;
24  }else{
25  return false;
26  }
27  }
28  for(size_t i = 0; i < usage.usage_begin.size(); i++){
29  usage_begin.push_back(usage.usage_begin[i]);
30  }
31  for(size_t i = 0; i < usage.usage_end.size(); i++){
32  usage_end.push_back(usage.usage_end[i]);
33  }
34  return true;
35  }
36  inline bool Usage::update(Usage const& usage){
37  OptionsIterator it;
38  for(it = usage.options.begin(); it != usage.options.end(); it++){
39  unsigned char const& chr = it->first;
40  if(options.find(chr) == options.end()){
41  continue;
42  }
43  options[chr] = it->second;
44  }
45  return true;
46  }
47  inline bool Usage::addOption(unsigned char opt, std::string const& des){
48  if(options.find(opt) != options.end()){
49  return false;
50  }
51  options[opt] = Option(des);
52  return true;
53  }
54  inline bool Usage::addOption(unsigned char opt, std::string const& des,
55  std::string const& val_type,
56  std::string const& val_default,
57  bool must){
58  if(options.find(opt) != options.end()){
59  return false;
60  }
61  options[opt] = Option(des, val_type, val_default, must);
62  return true;
63  }
64  inline bool Usage::addOptionValueAccept(unsigned char opt,
65  std::string const& val,
66  std::string const& des){
67  if(options.find(opt) == options.end()){
68  return false;
69  }
70  return options[opt].addValueAccept(val, des);
71  }
72  inline bool Usage::hasOptionSetup(unsigned char opt) const {
73  return (options.find(opt) != options.end() &&
74  options.find(opt)->second.hasSetup());
75  }
76  inline size_t Usage::getOptionValuesCount(unsigned char opt) const {
77  if(options.find(opt) == options.end()){
78  return 0;
79  }
80  return options.find(opt)->second.getValuesCount();
81  }
82  inline std::string Usage::getOptionValue(unsigned char opt,
83  size_t index) const {
84  if(options.find(opt) == options.end()){
85  return std::string();
86  }
87  return options.find(opt)->second.getValue(index);
88  }
89  inline size_t Usage::getProcArgsCount()const{return proc_arguments.size();}
90  inline std::string Usage::getProcArg(size_t index) const {
91  if(index >= proc_arguments.size()){
92  return std::string();
93  }
94  return proc_arguments[index];
95  }
96  inline std::vector<std::string> Usage::getProcArgs() const {
97  return proc_arguments;
98  }
99  inline void Usage::addUsageBegin(std::string const& des){
100  usage_begin.push_back(stringReplace(des, "<name>", name));
101  }
102  inline void Usage::addUsageEnd(std::string const& des){
103  usage_end.push_back(stringReplace(des, "<name>", name));
104  }
105  inline std::string Usage::getUsage() const {
106  std::string out = stringPrintf("USAGE\n %s", name.c_str());
107  OptionsIterator it;
108  for(it = options.begin(); it != options.end(); it++){
109  out += " " + it->second.getUsage(it->first, false);
110  }
111  out += "\n\nDESCRIPTION\n";
112  for(size_t i = 0; i < usage_begin.size(); i++){
113  out += " " + usage_begin[i] + "\n\n";
114  }
115  for(it = options.begin(); it != options.end(); it++){
116  out += it->second.getUsage(it->first, true);
117  }
118  for(size_t i = 0; i < usage_end.size(); i++){
119  out += " " + usage_end[i] + "\n\n";
120  }
121  return out;
122  }
123  inline bool Usage::setArguments(int argc, char** argv, std::string *errmsg){
124  opterr = 0;
125  std::string s;
126  OptionsIterator it;
127  std::string zzz;
128  std::string& err = (errmsg == NULL ? zzz : *errmsg);
129  for(it = options.begin(); it != options.end(); it++){
130  s += (char)(it->first);
131  if(it->second.hasValue()){
132  s += ":";
133  }
134  }
135  for(int opt; (opt = getopt(argc, argv, s.c_str())) != -1; ){
136  if(options.find(opt) == options.end()){
137  if(options.find(optopt) == options.end()){
138  err += stringPrintf("Unknown option '-%c'\n", optopt);
139  }else{
140  err += stringPrintf("No specify argument to '-%c'\n",
141  optopt);
142  }
143  opt = optopt;
144  return false;
145  }
146  if(options[opt].setValue(optarg == NULL ? "" : optarg) == false){
147  err += stringPrintf(
148  "Option argument '%s' to '-%c' is not allowed\n"
149  , optarg, opt);
150  return false;
151  }
152  }
153  for(it = options.begin(); it != options.end(); it++){
154  if(it->second.chkSetup() == false){
155  err += stringPrintf("No specify argument to '-%c'\n",
156  it->first);
157  return false;
158  }
159  }
160  for(int i = optind; i < argc; i++){
161  proc_arguments.push_back(std::string(argv[i]));
162  }
163  return true;
164  }
165  //
166  inline Usage::Value::Value(){ }
167  inline Usage::Value::Value(std::string const& v){
168  value = v;
169  description = "";
170  }
171  inline Usage::Value::Value(std::string const& v, std::string const& d){
172  value = v;
173  description = stringReplace(d, "<value>", v);
174  }
175  inline std::string Usage::Value::getUsage() const {
176  if(description.length() > 0)
177  return stringPrintf("%8s%s : %s\n",
178  " ", value.c_str(), description.c_str());
179  else
180  return "";
181  }
182  inline std::string Usage::Value::getValue() const { return value; }
183  inline bool Usage::Value::operator==(Value const& b) const {
184  return (value == b.value);
185  }
186  //
187  inline Usage::Option::Option(){ }
188  inline Usage::Option::Option(std::string const& des){
189  has_setup = false;
190  has_value = false;
191  description = des;
192  must_setup = false;
193  }
194  inline Usage::Option::Option(std::string const& des,
195  std::string const& typ,
196  std::string const& def,
197  bool must){
198  has_setup = false;
199  has_value = true;
200  description = des;
201  value_type = typ;
202  value_default = def;
203  must_setup = must;
204  }
205  inline bool Usage::Option::setValue(std::string const& str){
206  if(has_value){
207  if(values_accept.size() > 0 &&
208  std::find(values_accept.begin(), values_accept.end(),
209  Value(str, "")) == values_accept.end()){
210  return false;
211  }
212  values.push_back(str);
213  }
214  has_setup = true;
215  return true;
216  }
217  inline size_t Usage::Option::getValuesCount()const{return values.size();}
218  inline std::string Usage::Option::getValue(size_t index) const{
219  if(!has_value){
220  return "";
221  }
222  if(!has_setup || index >= values.size()){
223  return value_default;
224  }
225  return values[index];
226  }
227  inline bool Usage::Option::addValueAccept(std::string const& val,
228  std::string const& des){
229  if(!has_value){
230  return false;
231  }
232  if(std::find(values_accept.begin(), values_accept.end(), Value(val))
233  == values_accept.end()){
234  values_accept.push_back(Value(val, des));
235  }
236  return true;
237  }
238  inline bool Usage::Option::hasSetup() const { return has_setup; }
239  inline bool Usage::Option::hasValue() const { return has_value; }
240  inline bool Usage::Option::chkSetup() const {
241  return !(must_setup && !has_setup);
242  }
243  inline std::string Usage::Option::getUsage(unsigned char opt,
244  bool detail) const {
245  std::string ret;
246  if(!detail){
247  if(!has_value){
248  ret = stringPrintf("-%c", opt);
249  }else{
250  ret = stringPrintf("-%c %s", opt, value_type.c_str());
251  }
252  if(!must_setup){
253  ret = stringPrintf("[%s]", ret.c_str());
254  }
255  }else{
256  std::string tmp;
257  if(has_value){
258  std::string tmp2;
259  if(value_default != ""){
260  tmp2=stringPrintf("defuault='%s'",value_default.c_str());
261  }
262  std::string tmp3 = must_setup ? "" : "optional";
263  if(tmp2.length() + tmp3.length() > 0){
264  if(tmp2.length() > 0 && tmp3.length() > 0){
265  tmp = "(" + tmp3 + ", " + tmp2 + ")";
266  }else{
267  tmp = "(" + tmp3 + tmp2 + ")";
268  }
269  }
270  tmp = value_type + " " + tmp;
271  }
272  ret = stringPrintf(" -%c %s\n", opt, tmp.c_str());
273  tmp = stringReplace(description, "<type>", value_type);
274  std::string vs;
275  for(size_t i = 0; i < values_accept.size(); i++){
276  if(i > 0){
277  vs += (i + 1 < values_accept.size() ? ", " : " or ");
278  }
279  vs += "'" + values_accept[i].getValue() + "'";
280  }
281  if(vs.length() == 0){
282  vs = "... (anything)";
283  }
284  tmp = stringReplace(tmp, "<values>", vs);
285  ret += " " + tmp + "\n";
286  for(size_t i = 0; i < values_accept.size(); i++){
287  ret += values_accept[i].getUsage();
288  }
289  ret += "\n";
290  }
291  return ret;
292  }
293 }
294 
bool import(Usage const &usage)
將另一個usage的設置匯入
Definition: Usage.h:216
bool hasOptionSetup(String opt) const
回傳是否有設定此選項
Definition: Usage.h:304
Usage()
constructor
Definition: Usage.h:184
std::string stringReplace(std::string str, std::string const &from, std::string const &to)
將輸入字串中的某個pattern取代成另一個pattern
Definition: utility.h:60
bool update(Usage const &usage)
將另一個usage的選項設置加進來
Definition: Usage.h:239
std::string stringPrintf(char const *fmt,...)
類似C的printf, 不過是將格式化的字串丟到 std::string 裡回傳
Definition: utility.h:42