NeoPZ
arglib.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2012 by Edson Borin *
3  * edson@ic.unicamp.br *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
20 #include "arglib.h"
21 
22 //#include <unordered_map>
23 //#define MAP unordered_map
24 
25 #include <map>
26 #define MAP map
27 
28 using namespace std;
29 
30 //#define DEBUG_AL(...) cout << __VA_ARGS__
31 #define DEBUG_AL(...)
32 
33 namespace clarg {
34 
39  public:
40 
42  {
43  DEBUG_AL("Registering argument " << arg->get_name() << " ("
44  << arg->get_desc() << ")" << endl);
45  args[arg->get_name()] = arg;
46  }
47 
48  void arguments_descriptions(ostream& os, string prefix, string suffix)
49  {
50  MAP<string, arg_base*>::iterator it;
51  for (it = args.begin(); it != args.end(); it++) {
52  arg_base* arg = it->second;
53  os << prefix << arg->get_name() << " : " << arg->get_desc() << suffix;
54  }
55  }
56 
57  void list_arguments(ostream& os, bool defined_only)
58  {
59  MAP<string, arg_base*>::iterator it;
60  for (it = args.begin(); it != args.end(); it++) {
61  if (defined_only && !(it->second->was_set()))
62  continue;
63  os << "# " << it->second->get_desc() << " (default value:";
64  it->second->write_parameters(os, true);
65  os << ")" << endl;
66  os << it->second->get_name() << " ";
67  it->second->write_parameters(os);
68  os << endl;
69  }
70  }
71 
80  int parse_arguments_from_file(std::istream& is)
81  {
82  /* Suggestion: parse lines, one by one. For each line:
83  * - discard characters after '#'
84  * - \# is converted into '#'
85  * - build argc and argv for the line.
86  * - call parse_arguments(argc, argv)
87  */
88  cerr << "ERROR: " << __PRETTY_FUNCTION__ << " was not implemented yet" << endl;
89  return 1; /* Return error for now. */
90  }
91 
92  int parse_arguments(int argc, char *argv[])
93  {
94  if (argc <= 0)
95  return -1;
96  prog_name = string(argv[0]);
97  argv++;
98  argc--;
99 
100  while (argc > 0) {
101 
102  string argn = string(argv[0]);
103  /* Search argument */
104  DEBUG_AL("parse_arguments: look for \"" << argn << "\"" << endl);
105  std::MAP<string,arg_base*>::const_iterator got = args.find(argn);
106  if (got == args.end()) {
107  cerr << "Error: could not find argument: " << argn << endl;
108  return -1;
109  }
110  DEBUG_AL("found it" << endl);
111  arg_base* argp = got->second;
112  argv++;
113  argc--;
114 
115  /* Sanity checking. */
116  if (argp->was_set()) {
117  /* argument is being set more than once. */
118  cerr << "WARNING: argument " << argp->get_name() << " is being set more than once." << endl;
119  }
120  else {
121  argp->mark_set(true);
122  }
123 
124  /* Parse parameters */
125  int consumed = argp->parse_parameters(argc, argv);
126  DEBUG_AL("parse_arguments: consumed " << consumed
127  << " parameters when parsing argument "
128  << argn << endl);
129 
130  if (consumed < 0) {
131  /* parse_arguments returned error. */
132  cerr << "Error when parsing parameters for argument: " << got->first << endl;
133  return 1;
134  }
135 
136  /* Update argc, argv */
137  argv += consumed;
138  argc -= consumed;
139  }
140 
141  return 0;
142  }
143 
144  /* Arguments. */
145  MAP<string, arg_base*> args;
146  /* Program name. */
147  string prog_name;
148  };
149 
151  public:
152  container_manager() {create_container();}
153  ~container_manager() {if (container != NULL) delete container; }
154 
156  if (container == NULL)
157  create_container();
158  return container;
159  }
160 
161  private:
162 
164 
166  if (container == NULL)
167  container = new args_container();
168  }
169  };
170 
171  args_container* container_manager::container = NULL;
172 
174 
175 
176  arg_base::arg_base(const char* name, const char* desc) :
177  arg_name (name), arg_desc (desc)
178  {
179  cm.get_container()->register_argument(this);
180  }
181 
182  /* Print the arguments. */
183  void values(ostream& os, bool defined_only)
184  {
185  cm.get_container()->list_arguments(os, defined_only);
186  }
187 
188  /* Print the arguments descriptions. */
189  void arguments_descriptions(ostream& os, string prefix, string suffix)
190  {
191  cm.get_container()->arguments_descriptions(os,prefix,suffix);
192  }
193 
194  /* Parse the arguments. */
195  int parse_arguments(int argc, char *argv[])
196  {
197  return cm.get_container()->parse_arguments(argc, argv);
198  }
199 
204  int dump_arguments_to_file(ostream& of)
205  {
206  try {cm.get_container()->list_arguments(of, false);}
207  catch (...){ return 1;}
208  return 0;
209  }
210 
215  int parse_arguments_from_file(std::istream& is)
216  {
217  return cm.get_container()->parse_arguments_from_file(is);
218  }
219 
220 }
221 
const string & get_name() const
Definition: arglib.h:133
void values(ostream &os, bool defined_only)
Definition: arglib.cpp:183
MAP< string, arg_base * > args
Definition: arglib.cpp:145
clarg::argInt cm("-cm", "clean memory before execution", 512)
virtual int parse_parameters(int argc, char *argv [])=0
int parse_arguments(int argc, char *argv[])
Definition: arglib.cpp:92
int parse_arguments(int argc, char *argv[])
Definition: arglib.cpp:195
int parse_arguments_from_file(std::istream &is)
Definition: arglib.cpp:215
void mark_set(bool m)
Definition: arglib.h:140
void arguments_descriptions(ostream &os, string prefix, string suffix)
Definition: arglib.cpp:189
void list_arguments(ostream &os, bool defined_only)
Definition: arglib.cpp:57
int dump_arguments_to_file(ostream &of)
Definition: arglib.cpp:204
void register_argument(arg_base *arg)
Definition: arglib.cpp:41
args_container * get_container()
Definition: arglib.cpp:155
void arguments_descriptions(ostream &os, string prefix, string suffix)
Definition: arglib.cpp:48
bool was_set() const
Definition: arglib.h:138
int parse_arguments_from_file(std::istream &is)
Definition: arglib.cpp:80
const string & get_desc() const
Definition: arglib.h:135
#define DEBUG_AL(...)
Definition: arglib.cpp:31
Definition: arglib.cpp:33
static args_container * container
Definition: arglib.cpp:163