Line data Source code
1 : /* src/toolbox/Option.hpp - Command line option parsing library
2 :
3 : Copyright (C) 1996-2014
4 : CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 :
6 : This file is part of CACAO.
7 :
8 : This program is free software; you can redistribute it and/or
9 : modify it under the terms of the GNU General Public License as
10 : published by the Free Software Foundation; either version 2, or (at
11 : your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program; if not, write to the Free Software
20 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 : 02110-1301, USA.
22 :
23 : */
24 :
25 : #ifndef TOOLBOX_OPTION_HPP_
26 : #define TOOLBOX_OPTION_HPP_
27 :
28 : #include "config.h"
29 : #include <cstring>
30 : #include <cassert>
31 : #include <set>
32 : #include <cstdio>
33 :
34 : /**
35 : * @file
36 : *
37 : * This file contains the command line option parsing library.
38 : *
39 : * @ingroup cmd-option
40 : */
41 :
42 : /**
43 : * @defgroup cmd-option Command line option
44 : * Command line option parsing library.
45 : *
46 : * The aim of this module is to provide a decentralized, type-safe library for
47 : * command line options.
48 : *
49 : * Goals:
50 : * - Type-safe: no casting required
51 : * - Decentralized: Feature specific options can be defined in the feature
52 : * implementation files. No global, shared data structures need changes.
53 : * - Support for common types: Ints, strings, enums.
54 : * - Namespace support: Options can be organized in namespaces.
55 : */
56 : namespace cacao {
57 :
58 : class OStream;
59 : class OptionEntry;
60 :
61 0 : class OptionPrefix {
62 : public:
63 : typedef std::set<OptionEntry*> ChildSetTy;
64 : typedef ChildSetTy::iterator iterator;
65 :
66 : OptionPrefix(const char* name);
67 :
68 0 : const char* get_name() const {
69 0 : return name;
70 : }
71 0 : std::size_t size() const {
72 0 : return s;
73 : }
74 0 : iterator begin() { return children.begin(); }
75 0 : iterator end() { return children.end(); }
76 : void insert(OptionEntry* oe);
77 : #if 0
78 : {
79 : children.insert(oe);
80 : }
81 : #endif
82 : private:
83 : const char* name;
84 : std::size_t s;
85 : ChildSetTy children;
86 : };
87 :
88 : class OptionParser {
89 : public:
90 : static void print_usage(OptionPrefix& root, FILE* fp = stdout);
91 : static bool parse_option(OptionPrefix& root, const char* name, size_t name_len,
92 : const char* value, size_t value_len);
93 : };
94 :
95 : class OptionEntry {
96 : public:
97 : OptionEntry(const char* name, const char* desc, OptionPrefix &parent)
98 : : name(name), name_size(std::strlen(name)), desc(desc) {
99 : parent.insert(this);
100 : }
101 0 : const char* get_name() const {
102 0 : return name;
103 : }
104 0 : std::size_t size() const {
105 0 : return name_size;
106 : }
107 0 : const char* get_desc() const {
108 0 : return desc;
109 : }
110 : virtual std::size_t print(OStream& OS) = 0;
111 : virtual bool parse(const char* value, std::size_t value_len) = 0;
112 :
113 : virtual ~OptionEntry() {} // make compiler happy
114 : private:
115 : const char* name;
116 : std::size_t name_size;
117 : const char* desc;
118 : };
119 :
120 :
121 : template<class T>
122 : class OptionBase : public OptionEntry {
123 : public:
124 : OptionBase(const char* name, const char* desc, T value, OptionPrefix &parent)
125 : : OptionEntry(name, desc, parent), value(value) {}
126 : T get() { return value; }
127 : operator T() { return get(); }
128 :
129 : virtual std::size_t print(OStream& OS);
130 : protected:
131 0 : void set_value(T v) {
132 0 : value = v;
133 0 : }
134 : private:
135 : T value;
136 : };
137 :
138 : std::size_t option_print(OptionBase<bool>& option, OStream& OS);
139 :
140 : std::size_t option_print(OptionEntry& option, OStream& OS);
141 :
142 : template<class T>
143 : inline std::size_t OptionBase<T>::print(OStream& OS) {
144 : return option_print(*this,OS);
145 : }
146 :
147 : template<class T>
148 : class Option : public OptionBase<T> {
149 : public:
150 : Option(const char* name, const char* desc, T value, OptionPrefix &parent)
151 : : OptionBase<T>(name,desc,value,parent) {}
152 : virtual bool parse(const char* value, std::size_t value_len);
153 : };
154 :
155 :
156 : namespace option {
157 : OptionPrefix& root();
158 : OptionPrefix& xx_root();
159 : } // end namespace option
160 :
161 : } // end namespace cacao
162 :
163 : #endif // TOOLBOX_OPTION_HPP_
164 :
165 : /*
166 : * These are local overrides for various environment variables in Emacs.
167 : * Please do not remove this and leave it at the end of the file, where
168 : * Emacs will automagically detect them.
169 : * ---------------------------------------------------------------------
170 : * Local variables:
171 : * mode: c++
172 : * indent-tabs-mode: t
173 : * c-basic-offset: 4
174 : * tab-width: 4
175 : * End:
176 : * vim:noexpandtab:sw=4:ts=4:
177 : */
|