Jpp 19.3.0-rc.3
the software that should make you happy
Loading...
Searching...
No Matches
JShellParser.cc
Go to the documentation of this file.
1
2#include <iostream>
3#include <iomanip>
4#include <string>
5#include <cstring>
6#include <list>
7
8#include "JLang/JNullType.hh"
9#include "JLang/JEquation.hh"
11#include "JLang/JException.hh"
13#include "JLang/JLangToolkit.hh"
15#include "Jeep/JParser.hh"
16
17
18/**
19 * \author mdejong
20 */
21
22namespace {
23
24 using namespace JPP;
25
26 const char OPTIONS_SEPARATOR = ','; //!< options separator
27
28
29 /**
30 * Auxiliary class for environment variable.
31 */
32 template<class T>
33 struct JParameter {
34 /**
35 * Constructor.
36 *
37 * \param variable environment variable
38 */
39 JParameter(const std::string& variable) :
40 name (variable),
41 value()
42 {}
43
44
45 /**
46 * Equals operator.
47 *
48 * \param first first parameter
49 * \param second second parameter
50 * \return true if first parameter equals second parameter; else false
51 */
52 friend bool operator==(const JParameter& first, const JParameter& second)
53 {
54 return (first.name == second.name &&
55 first.value == second.value);
56 }
57
58
59 /**
60 * Stream input.
61 *
62 * Note that only the value of the parameter is read.
63 *
64 * \param in input stream
65 * \return input stream
66 */
67 inline std::istream& read(std::istream& in)
68 {
69 return in >> this->value;
70 }
71
72
73 /**
74 * Stream output.
75 *
76 * Note that only the value of the parameter is written.
77 *
78 * \param out output stream
79 * \return output stream
80 */
81 inline std::ostream& write(std::ostream& out) const
82 {
83 return out << this->value;
84 }
85
86 std::string name; //!< environment variable name
87 T value; //!< environment variable value
88 };
89
90
91 /**
92 * Template specialisation of JParameter<std::string>::read.
93 *
94 * Note that the complete text until the end-of-line is read, including possible white spaces.
95 *
96 * \param in input stream
97 * \return input stream
98 */
99 template<>
100 inline std::istream& JParameter<std::string>::read(std::istream& in)
101 {
102 return std::getline(in, this->value);
103 }
104
105
106 /**
107 * Template specialisation of JParameter<bool>::read.
108 *
109 * Note that no data are read; only the value is set to <tt>true</tt>
110 *
111 * \param in input stream
112 * \return input stream
113 */
114 template<>
115 inline std::istream& JParameter<bool>::read(std::istream& in)
116 {
117 this->value = true;
118
119 return in;
120 }
121
122
123 /**
124 * Template specialisation of JParameter<bool>::write.
125 *
126 * \param out output stream
127 * \return output stream
128 */
129 template<>
130 inline std::ostream& JParameter<bool>::write(std::ostream& out) const
131 {
132 return out << (this->value ? "1" : "0");
133 }
134
135
136 /**
137 * Stream input of parameter.
138 *
139 * \param in input stream
140 * \param parameter parameter
141 * \return input stream
142 */
143 template<class T>
144 inline std::istream& operator>>(std::istream& in, JParameter<T>& parameter)
145 {
146 return parameter.read(in);
147 }
148
149
150 /**
151 * Stream output of parameter.
152 *
153 * \param out output stream
154 * \param parameter parameter
155 * \return output stream
156 */
157 template<class T>
158 inline std::ostream& operator<<(std::ostream& out, const JParameter<T>& parameter)
159 {
160 return parameter.write(out);
161 }
162
163
164 /**
165 * Base class for environment variables.
166 */
167 template<class T = JNullType>
168 struct JShellParser;
169
170
171 /**
172 * Base class for environment variables.
173 *
174 * This class is used to redirect the standard output and error so that
175 * - output is parsed via JSYSTEM::gprint; and
176 * - termination is handled via JSYSTEM::gexit.
177 */
178 template<>
179 struct JShellParser<JNullType> :
180 public JParser<>
181 {
182 typedef JParser<>::key_type key_type;
183
184
185 /**
186 * Default constructor.
187 */
188 JShellParser() :
189 __terminate__(false),
190 __exit_code__(0)
191 {}
192
193
194 /**
195 * Virtual destructor.
196 */
197 virtual ~JShellParser()
198 {}
199
200
201 /**
202 * Terminate.
203 *
204 * \param status exit status
205 */
206 virtual void terminate(const int status)
207 {
208 __terminate__ = true;
209 __exit_code__ = status;
210 }
211
212
213 /**
214 * Parse the program's command line options.
215 *
216 * \param args argument list
217 * \return argument list
218 */
219 JArgs operator()(const JArgs& args)
220 {
221 using namespace std;
222 using namespace JPP;
223
224 ostringstream os;
225
226 {
227 JRedirectStream rs_out(cout, os);
228 JRedirectStream rs_err(cerr, os);
229
230 if (rs_out &&
231 rs_err) {
232 static_cast<JParser<>&>(*this)(args);
233 }
234 }
235
236 gprint(os.str());
237
238 if (__terminate__) {
239 gexit(__exit_code__);
240 }
241
242 return JArgs();
243 }
244
245 private:
246 bool __terminate__;
247 int __exit_code__;
248 };
249
250
251 /**
252 * Base class for environment variables.
253 *
254 * This class includes the data to be evaluated to shell variables in the end.
255 */
256 template<class T>
257 struct JShellParser :
258 public JShellParser<>
259 {
260 typedef JShellParser<>::key_type key_type;
261 typedef JParameter<T> parameter_type;
263
264
265 /**
266 * Evaluate environment to shell commands.
267 */
268 void evaluate() const
269 {
270 for (typename data_type::const_iterator i = this->data.begin(); i != this->data.end(); ++i) {
271
272 std::ostringstream os;
273
274 os << *i;
275
276 set_variable(i->name, os.str());
277 }
278 }
279
280
281 protected:
282 data_type data; //!< internal memory
283 };
284
285
286 /**
287 * Parser for environment variables.
288 */
289 template<class T>
290 struct JEnvironment;
291
292
293 /**
294 * Template specialisation of JEnvironment for regular environment variables.
295 */
296 template<>
297 struct JEnvironment<std::string> :
298 public JShellParser<std::string>
299 {
300 typedef JShellParser<std::string>::key_type key_type;
301 typedef JShellParser<std::string>::parameter_type parameter_type;
302
303
304 /**
305 * Default constructor.
306 */
307 JEnvironment()
308 {}
309
310
311 /**
312 * Stream input.
313 *
314 * \param in input stream
315 * \param environment environment
316 * \return input stream
317 */
318 friend inline std::istream& operator>>(std::istream& in, JEnvironment& environment)
319 {
320 using namespace std;
321 using namespace JPP;
322
323 static const JEquationFacet facet(JEquationParameters("=", ";\n", "./", "#"));
324
325 char c;
326 key_type key;
327 JEquation equation;
328
329 if (!has_facet<JEquationFacet>(in.getloc())) {
330 in.imbue(locale(in.getloc(), facet.clone()));
331 }
332
333 if (in >> c >> key >> equation) {
334
335 if (c == '-' && !equation.getKey().empty()) {
336
337 environment.data.push_back(parameter_type(equation.getKey()));
338
339 parameter_type& parameter = environment.data.back();
340
341 if (facet.isSeparator(equation.getSeparator())) {
342
343 // read possible values
344
345 istringstream is(equation.getValue());
346
347 vector<parameter_type> possible_values;
348
349 for (parameter_type buffer(parameter.name); getline(is, buffer.value, OPTIONS_SEPARATOR); ) {
350
351 buffer.value = trim(buffer.value);
352
353 possible_values.push_back(buffer);
354 }
355
356 environment[key] = JPARSER::getOption(parameter, equation.getKey(), possible_values.begin(), possible_values.end());
357
358 } else {
359
360 environment[key] = JPARSER::getOption(parameter, equation.getKey());
361 }
362
363 } else {
364
365 THROW(JParseError, "JEnvironment: error parsing " << c << " <" << equation.getKey() << ">");
366 }
367 }
368
369 return in;
370 }
371 };
372
373
374 /**
375 * Template specialisation of JEnvironment for boolean environment variables.
376 */
377 template<>
378 struct JEnvironment<bool> :
379 public JShellParser<bool>
380 {
381 typedef JShellParser<bool>::key_type key_type;
382 typedef JShellParser<bool>::parameter_type parameter_type;
383
384
385 /**
386 * Default constructor.
387 */
388 JEnvironment()
389 {}
390
391
392 /**
393 * Stream input.
394 *
395 * \param in input stream
396 * \param environment environment
397 * \return input stream
398 */
399 friend inline std::istream& operator>>(std::istream& in, JEnvironment& environment)
400 {
401 using namespace std;
402 using namespace JPP;
403
404 static const JEquationFacet facet(JEquationParameters("=", ";\n", "./", "#"));
405
406 char c;
407 key_type key;
408 JEquation equation;
409
410 if (!has_facet<JEquationFacet>(in.getloc())) {
411 in.imbue(locale(in.getloc(), facet.clone()));
412 }
413
414 if (in >> c >> key >> equation) {
415
416 if (c == '-' && !equation.getKey().empty()) {
417
418 environment.data.push_back(parameter_type(equation.getKey()));
419
420 parameter_type& parameter = environment.data.back();
421
422 if (facet.isSeparator(equation.getSeparator()) || equation.getValue() != "") {
423
424 THROW(JParseError, "JEnvironment: invalid operation " << c << " <" << equation.getKey() << ">");
425
426 } else {
427
428 environment[key] = JPARSER::getOption(parameter.value, equation.getKey());
429 }
430
431 } else {
432
433 THROW(JParseError, "JEnvironment: error parsing " << c << " <" << equation.getKey() << ">");
434 }
435 }
436
437 return in;
438 }
439 };
440}
441
442
443/**
444 * \file
445 *
446 * Auxiliary program to interface JPARSER::JParser to command line of shell scripts.
447 * Syntax:
448 * <pre>
449 * eval `JShellParser -o "-a <environment variable> [= <default value>[, <possible value>]]" -- $*`
450 * </pre>
451 */
452int main(int argc, char **argv)
453{
454 using namespace std;
455 using namespace JPP;
456
457 try {
458
459 JEnvironment<bool> boolean;
460 JEnvironment<string> regular;
461
462 JParser<> zap;
463
464 zap['b'] = make_field(boolean) = JPARSER::initialised();
465 zap['o'] = make_field(regular) = JPARSER::initialised();
466
467 const JArgs options = zap(argc, argv);
468
469 JShellParser<> buffer;
470
471 buffer.join(boolean);
472 buffer.join(regular);
473
474 buffer(options);
475
476 boolean.evaluate();
477 regular.evaluate();
478 }
479 catch(const exception& error) {
480 return gexit(2, error.what());
481 }
482}
Exceptions.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
std::istream & operator>>(std::istream &in, JAANET::JHead &header)
Read header from input.
Definition JHead.hh:1832
Utility class to parse command line options.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition JParser.hh:2142
int main(int argc, char **argv)
System auxiliaries.
Data structure to store command line arguments.
Definition JArgs.hh:26
Facet class to specify parsing of equations in currect locale (see class JLANG::JEquation).
Simple data structure to support I/O of equations (see class JLANG::JEquation).
General purpose equation class.
Definition JEquation.hh:47
const std::string & getKey() const
Get key.
Definition JEquation.hh:163
const std::string & getValue() const
Get value.
Definition JEquation.hh:185
const char getSeparator() const
Get separator.
Definition JEquation.hh:174
Parameter class.
Definition JParameter.hh:36
Exception for parsing value.
This class can be used to temporarily redirect one output (input) stream to another output (input) st...
Utility class to parse command line options.
Definition JParser.hh:1698
bool write(const Vec &v, std::ostream &os)
Write a Vec(tor) to a stream.
Definition io_ascii.hh:155
bool operator==(const Head &first, const Head &second)
Equal operator.
Definition JHead.hh:1801
std::istream & read(std::istream &in, JTestSummary &summary, const char delimiter=' ')
Read test summary.
std::istream & operator>>(std::istream &in, JAHRSCalibration &calibration)
Read AHRS calibration from input stream.
std::ostream & operator<<(std::ostream &out, const JAHRSCalibration &calibration)
Write AHRS calibration to output stream.
std::istream & getline(std::istream &in, JString &object)
Read string from input stream until end of line.
Definition JString.hh:478
std::string trim(const std::string &buffer)
Trim string.
JParserTemplateElement< JType_t > getOption(JType_t &object, const std::string &name, const std::string &help="")
Auxiliary method for creation of template parser element object.
Definition JParser.hh:2077
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
std::vector< event_type > data_type
Definition JPerth.cc:81
int gexit(int status, const std::string &message="")
Exit method.
void gprint(const std::string &message)
Print method.
void set_variable(const std::string &name, const std::string &value)
Set environment variable.
Data structure for measured coincidence rates of all pairs of PMTs in optical module.
Definition JFitK40.hh:103
Auxiliary class for no type definition.
Definition JNullType.hh:19
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition JParser.hh:68