]> git.stg.codes - stg.git/blob - projects/sgconf/actions.h
Merge remote-tracking branch 'origin/master' into ticket
[stg.git] / projects / sgconf / actions.h
1 /*
2  *    This program is free software; you can redistribute it and/or modify
3  *    it under the terms of the GNU General Public License as published by
4  *    the Free Software Foundation; either version 2 of the License, or
5  *    (at your option) any later version.
6  *
7  *    This program is distributed in the hope that it will be useful,
8  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *    GNU General Public License for more details.
11  *
12  *    You should have received a copy of the GNU General Public License
13  *    along with this program; if not, write to the Free Software
14  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  */
16
17 /*
18  *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
19  */
20
21 #ifndef __STG_SGCONF_ACTIONS_H__
22 #define __STG_SGCONF_ACTIONS_H__
23
24 #include "action.h"
25 #include "options.h"
26 #include "parser_state.h"
27
28 #include "stg/common.h"
29 #include "stg/resetable.h"
30
31 #include <string>
32
33 #include <cassert>
34
35 namespace SGCONF
36 {
37
38 typedef void (* FUNC0)();
39
40 template <typename F>
41 class FUNC0_ACTION : public ACTION
42 {
43     public:
44         FUNC0_ACTION(const F & func) : m_func(func) {}
45
46         virtual ACTION * Clone() const { return new FUNC0_ACTION<F>(*this); }
47
48         virtual std::string ParamDescription() const { return ""; }
49         virtual std::string DefaultDescription() const { return ""; }
50         virtual OPTION_BLOCK & Suboptions() { return m_suboptions; }
51         virtual PARSER_STATE Parse(int argc, char ** argv, void * /*data*/)
52         {
53         m_func();
54         return PARSER_STATE(true, argc, argv);
55         }
56
57     private:
58         F m_func;
59         OPTION_BLOCK m_suboptions;
60 };
61
62 template <typename F>
63 inline
64 FUNC0_ACTION<F> * MakeFunc0Action(F func)
65 {
66 return new FUNC0_ACTION<F>(func);
67 }
68
69 template <typename T>
70 class PARAM_ACTION : public ACTION
71 {
72     public:
73         PARAM_ACTION(RESETABLE<T> & param,
74                      const T & defaultValue,
75                      const std::string & paramDescription)
76             : m_param(param),
77               m_defaltValue(defaultValue),
78               m_description(paramDescription),
79               m_hasDefault(true)
80         {}
81         PARAM_ACTION(RESETABLE<T> & param)
82             : m_param(param),
83               m_hasDefault(false)
84         {}
85         PARAM_ACTION(RESETABLE<T> & param,
86                      const std::string & paramDescription)
87             : m_param(param),
88               m_description(paramDescription),
89               m_hasDefault(false)
90         {}
91
92         virtual ACTION * Clone() const { return new PARAM_ACTION<T>(*this); }
93
94         virtual std::string ParamDescription() const { return m_description; }
95         virtual std::string DefaultDescription() const;
96         virtual OPTION_BLOCK & Suboptions() { return m_suboptions; }
97         virtual PARSER_STATE Parse(int argc, char ** argv, void * /*data*/);
98         virtual void ParseValue(const std::string & value);
99
100     private:
101         RESETABLE<T> & m_param;
102         T m_defaltValue;
103         std::string m_description;
104         bool m_hasDefault;
105         OPTION_BLOCK m_suboptions;
106 };
107
108 template <typename T>
109 inline
110 std::string PARAM_ACTION<T>::DefaultDescription() const
111 {
112 return m_hasDefault ? " (default: '" + x2str(m_defaltValue) + "')"
113                     : "";
114 }
115
116 template <>
117 inline
118 std::string PARAM_ACTION<std::string>::DefaultDescription() const
119 {
120 return m_hasDefault ? " (default: '" + m_defaltValue + "')"
121                     : "";
122 }
123
124 template <typename T>
125 inline
126 PARSER_STATE PARAM_ACTION<T>::Parse(int argc, char ** argv, void * /*data*/)
127 {
128 if (argc == 0 ||
129     argv == NULL ||
130     *argv == NULL)
131     throw ERROR("Missing argument.");
132 T value;
133 if (str2x(*argv, value))
134     throw ERROR(std::string("Bad argument: '") + *argv + "'");
135 m_param = value;
136 return PARSER_STATE(false, --argc, ++argv);
137 }
138
139 template <>
140 inline
141 PARSER_STATE PARAM_ACTION<bool>::Parse(int argc, char ** argv, void * /*data*/)
142 {
143 m_param = true;
144 return PARSER_STATE(false, argc, argv);
145 }
146
147 template <typename T>
148 inline
149 void PARAM_ACTION<T>::ParseValue(const std::string & stringValue)
150 {
151 if (stringValue.empty())
152     throw ERROR("Missing value.");
153 T value;
154 if (str2x(stringValue, value))
155     throw ERROR(std::string("Bad value: '") + stringValue + "'");
156 m_param = value;
157 }
158
159 template <>
160 inline
161 void PARAM_ACTION<std::string>::ParseValue(const std::string & stringValue)
162 {
163 m_param = stringValue;
164 }
165
166 template <>
167 inline
168 PARSER_STATE PARAM_ACTION<std::string>::Parse(int argc, char ** argv, void * /*data*/)
169 {
170 if (argc == 0 ||
171     argv == NULL ||
172     *argv == NULL)
173     throw ERROR("Missing argument.");
174 m_param = *argv;
175 return PARSER_STATE(false, --argc, ++argv);
176 }
177
178 template <typename T>
179 inline
180 PARAM_ACTION<T> * MakeParamAction(RESETABLE<T> & param,
181                                   const T & defaultValue,
182                                   const std::string & paramDescription)
183 {
184 return new PARAM_ACTION<T>(param, defaultValue, paramDescription);
185 }
186
187 template <typename T>
188 inline
189 PARAM_ACTION<T> * MakeParamAction(RESETABLE<T> & param)
190 {
191 return new PARAM_ACTION<T>(param);
192 }
193
194 template <typename T>
195 inline
196 PARAM_ACTION<T> * MakeParamAction(RESETABLE<T> & param,
197                                   const std::string & paramDescription)
198 {
199 return new PARAM_ACTION<T>(param, paramDescription);
200 }
201
202 class KV_ACTION : public ACTION
203 {
204     public:
205         KV_ACTION(const std::string & name,
206                   const std::string & paramDescription)
207             : m_name(name),
208               m_description(paramDescription)
209         {}
210
211         virtual ACTION * Clone() const { return new KV_ACTION(*this); }
212
213         virtual std::string ParamDescription() const { return m_description; }
214         virtual std::string DefaultDescription() const { return ""; }
215         virtual OPTION_BLOCK & Suboptions() { return m_suboptions; }
216         virtual PARSER_STATE Parse(int argc, char ** argv, void * data);
217
218     private:
219         std::string m_name;
220         std::string m_description;
221         OPTION_BLOCK m_suboptions;
222 };
223
224 inline
225 PARSER_STATE KV_ACTION::Parse(int argc, char ** argv, void * data)
226 {
227 if (argc == 0 ||
228     argv == NULL ||
229     *argv == NULL)
230     throw ERROR("Missing argument.");
231 assert(data != NULL && "Expecting container pointer.");
232 std::map<std::string, std::string> & kvs = *static_cast<std::map<std::string, std::string>*>(data);
233 kvs[m_name] = *argv;
234 return PARSER_STATE(false, --argc, ++argv);
235 }
236
237 inline
238 KV_ACTION * MakeKVAction(const std::string & name,
239                          const std::string & paramDescription)
240 {
241 return new KV_ACTION(name, paramDescription);
242 }
243
244 } // namespace SGCONF
245
246 #endif