Loading...
Searching...
No Matches
Command.h
1/*
2
3MIT License
4
5Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26/*
27Part of Rack development has been done in the BALTRAD projects part-financed
28by the European Union (European Regional Development Fund and European
29Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30*/
31
32#ifndef DRAINLET_H_
33#define DRAINLET_H_
34
35//#include <map>
36//#include <set>
37//#include "drain/util/Debug.h"
38//#include "drain/util/ReferenceMap.h"
39
40#include <drain/Log.h>
41#include "drain/util/BeanLike.h"
42#include "drain/util/ReferenceMap.h"
43
44//#include "drain/util/Cloner.h"
45#include "Context.h"
46
47namespace drain {
48
50
53class Command : public Contextual {
54
55public:
56
57
58 inline
59 Command(): section(0){}; //
60
61 // TODO: CHECK: base Contextual is explicitly default-constructed (contextPtr=nullptr) here,
62 // same as before, rather than copying cmd's contextPtr. Commands are cloned per thread/context
63 // (see AGENTS.md), so a fresh (unset) context that gets reassigned afterward may well be the
64 // intended behavior here, but confirm.
66 inline
68 // setParameters(cmd.getParameters()); they do not exist yet!
69 }
70
71 virtual inline
72 ~Command(){};
73
74
76
79 virtual
80 const std::string & getName() const = 0;
81
82 virtual
83 const std::string & getDescription() const = 0;
84
85 virtual
86 const ReferenceMap & getParameters() const = 0;
87
88 static
90
91
92 virtual
93 void setParameters(const std::string & args) final;
94
95 // TODO: make this a loop calling set(key,val) - but then no
97 template <class T>
98 void setParameters(const T & args){
99 // TODO: set parameter X=Y ?
100 ReferenceMap & parameters = getParameters();
101 std::stringstream sstr;
102 char separator = 0;
103 for (const auto & entry: args){
104 parameters[entry.first] = entry.second;
105 // setParameter(entry.first, entry.second);
106 if (separator)
107 sstr << separator;
108 else
109 separator = ',';
110 sstr << entry.first << '=' << entry.second;
111 }
112 lastParameters = sstr.str();
113
114 }
115
117
121 template <class T>
122 void setParameter(const std::string & key, const T & value){
123 getParameters()[key] = value;
124 std::stringstream sstr;
125 sstr << key << '=' << value;
126 lastParameters = sstr.str();
127 }
128
129
130
131 // Could also need/replace void setParameters(const std::map<std::string,T> & p)
132
134 inline
135 bool hasParameters() const {
136
137 Logger mout(__FILE__, __FUNCTION__);
138
139 const ReferenceMap & params = this->getParameters();
140 //mout.warn(params );
141
142 const ReferenceMap::const_iterator it = params.begin();
143 if (it == params.end()) // empty
144 return false;
145 else
146 return it->second.getType() != typeid(void); // ???
147 };
148
150 /*
151 virtual inline
152 const std::string & getType() const {
153 static const std::string empty;
154 return empty;
155 };
156 */
157
158
160
163 virtual inline
164 void run(const std::string & params = "") final {
165 setParameters(params);
166 update();
167 exec();
168 }
169
171
174 virtual
175 void update(){
176 }
177
179 virtual inline
180 void exec() const {};
181
182
183 // Optional bit(s) marking the command type (compare with manual page sections)
187 typedef int cmd_section_type;
189
191 inline
192 Command & addSection(int i){ // drain::FlaggerBase<>::ivalue_t
193 section |= i;
194 return *this;
195 }
196
198 inline
199 const std::string & getLastParameters() const {
200 return lastParameters;
201 };
202
203
204 //virtual
205 // void help(std::ostream & ostr = std::cout, bool DETAILED=false) const final;
206
208 virtual
209 void getRelatedCommands(std::ostream & ostr = std::cout) const;
210
211
213
219 /*
220 template <class C, class ...CC>
221 Command & linkRelatedCommands(const C & cmd, const CC & ... cmds){
222 relatedCommands.insert(cmd);
223 linkRelatedCommands(cmds...);
224 return *this;
225 };
226 */
227
228 inline
229 void linkRelated(const std::string & cmdKey) const {
230 relatedCommands.insert(cmdKey);
231 };
232
234
239 virtual
240 void parametersToStream(std::ostream & ostr, const std::string & indent= " ") const;
241
243 virtual inline
244 void parameterKeysToStream(std::ostream & ostr) const {
245 parameterKeysToStream(ostr, getParameters().getKeyList(), getParameters().separator);
246 };
247
249 void parameterKeysToStream(std::ostream & ostr, const std::list<std::string> & list, char sep=',') const;
250
251
252protected:
253
254 mutable
255 std::set<std::string> relatedCommands;
256
257 // Terminal
258 /*
259 inline
260 Command & linkRelatedCommands(){
261 return *this;
262 };
263 */
264
265 // Why protected?
266 virtual
267 ReferenceMap & getParameters() = 0;
268
269 // Clumsy but useful
270 std::string lastParameters;
271
272};
273
274inline
275std::ostream & operator<<(std::ostream & ostr, const Command &cmd){
276 ostr << cmd.getName();
277 if (cmd.hasParameters()){
278 ostr << ' ' << cmd.getParameters(); // << ' ';
279 }
280 return ostr;
281}
282
283// See new implementations in CommandBank, CommandUtils.
284//typedef std::list<std::pair<Command &, std::string> > Script; // TODO: move
285
286
288/*
289template <class B>
290class BeanerCommand : public Command {
291
292public:
293
294 typedef B bean_t;
295
296 // Main
297 virtual
298 const bean_t & getBean() const = 0;
299
300 // Main
301 virtual
302 bean_t & getBean() = 0;
303
304
305
306
307 inline
308 const std::string & getName() const final {
309 return getBean().getName();
310 };
311
312 inline
313 const std::string & getDescription() const final {
314 return getBean().getDescription();
315 };
316
317 virtual inline
318 const drain::ReferenceMap & getParameters() const final {
319 return getBean().getParameters();
320 };
321
322protected:
323
324 virtual inline
325 drain::ReferenceMap & getParameters() final {
326 return getBean().getParameters();
327 };
328
329};
330*/
331
333
339template <class B, class B2=B>
340class BeanCommand : public Command {
341// class BeanCommand : public BeanerCommand<B> { // public Command {
342
343public:
344
345 BeanCommand(){
346 };
347
349 BeanCommand(const std::string & name, const std::string & description) : bean(name, description){
350 };
351
353 BeanCommand(const BeanCommand & cmd) : Command(cmd), bean(cmd.bean) {
354 // WARNING: this may have undesired beaviour:
355 // If B2 is (Bean &), also new instance of beanCmd.bean -> cmd.bean
356 };
357
359 BeanCommand(B & b) : bean(b) {
360 };
361
362 typedef B bean_t;
363
364// Consider private:
365 B2 bean;
366
367
369 virtual inline
370 const bean_t & getBean() const { // final
371 return bean;
372 };
373
375 virtual inline
376 bean_t & getBean() { // final
377 return bean;
378 };
379
380
381
383 inline
384 const std::string & getName() const final {
385 return getBean().getName();
386 };
387
389 inline
390 const std::string & getDescription() const final {
391 return getBean().getDescription();
392 };
393
395 virtual inline
396 const drain::ReferenceMap & getParameters() const { // final
397 return getBean().getParameters();
398 };
399
400protected:
401
402 virtual inline
404 return getBean().getParameters();
405 };
406
407
408 /*
409 virtual
410 void setAllParameters(const std::string & args) override {
411
412 Context & ctx = this->template getContext<>();
413 drain::Logger mout(ctx.log, __FUNCTION__, this->bean.getName() );
414
415 bean.setParameters(args,'=');
416 //mout.note() = "updating";
417 //this->update();
418 }
419 */
420
422 //virtual
423 /*
424 void setParameters(const VariableMap & params){
425 bean.setParameters(params);
426 // this->update();
427 }
428 */
429
430};
431
432
433
434template <class B>
435class BeanRefCommand : public drain::BeanCommand<B, B&> {
436
437public:
438
440 }
441
443 }
444
445 BeanRefCommand(const BeanRefCommand<B> & beanRefCmd) : drain::BeanCommand<B,B&>(beanRefCmd.bean){
446 }
447
448
449};
450
451
452
453
455
461class BasicCommand : public BeanCommand<BeanLike> { // Todo consider BeanLike
462
463public:
464
466 BasicCommand(const std::string & name, const std::string & description);
467
469 inline
470 //BasicCommand(const BasicCommand & cmd): Command(cmd), name(cmd.name), description(cmd.description) {
472 // remember to call importParameters()
473 }
474
475};
476
477
478//typedef BeanCommand<BeanLike> BasicCommand;
479
480
481
483
486template <class T = std::string>
488
489public:
490
491 T value;
492
494 SimpleCommand(const std::string & name, const std::string & description,
495 const std::string & key="value", const T & initValue = T(), const std::string & unit = "") : BasicCommand(name, description) {
496
497 getParameters().separator = '\0';
498 getParameters().link(key, value = initValue, unit);
499
500 if (key.empty()){
501 Context & ctx = getContext<Context>();
502 drain::Logger mout(ctx.log,__FILE__, __FUNCTION__);
503 mout.warn("Empty value key in command ", name, " (", description, ")");
504 }
505
506
507 };
508
510 template <class S>
511 SimpleCommand(const std::string & name, const std::string & description,
512 const std::string & key, std::initializer_list<S> l , const std::string & unit = "") : BasicCommand(name, description) {
513 // parameters.separator = '\0';
514 value = l;
515 getParameters().link(key, value);
516
517 if (key.empty()){
518 Context & ctx = getContext<Context>();
519 drain::Logger mout(ctx.log,__FILE__, __FUNCTION__);
520 mout.warn("Empty value key in command ", name, " (", description, ")");
521 }
522 }
523
524
527 getParameters().separator = '\0';
528 getParameters().copyStruct(cmd.getParameters(), cmd, *this);
529 /*
530 parameters.separator = '\0';
531 parameters.copyStruct(cmd.getParameters(), cmd, *this);
532 */
533 };
534
535 /*
536 void setParameters(const std::string & args){
537 const std::string & key = parameters.begin()->first;
538 Variable v(typeid(T));
539 if (key.empty()){
540 v = args;
541 }
542 else {
543 const std::string assignment = key+"=";
544 const size_t n = assignment.length();
545 if (args.compare(0,n,key)==0){
546 v = args.substr(n);
547 }
548 else
549 v = args;
550 }
551 value = v;
552 }
553 */
554
555
556
557};
558
560
563/*
564class DynamicCommand : public drain::Command {
565
566public:
567
568 virtual
569 void exec() const {
570 Context & ctx = getContext<Context>();
571 drain::Logger mout(ctx.log,__FILE__, __FUNCTION__);
572 mout.note("I am " , getName() , ", invoked as " , key );
573 }
574
575 virtual
576 void setKey(const std::string & cmdKey) const {
577 key = cmdKey;
578 }
579
580protected:
581
582 mutable
583 std::string key;
584
585};
586*/
587
588
589
590
591} // drain::
592
593#endif /* DRAINLET_H_ */
Simple implementation of Command: adds name , description and parameters .
Definition Command.h:461
BasicCommand(const BasicCommand &cmd)
Copy constructor.
Definition Command.h:471
Retrieves bean dynamically for each call.
Definition Command.h:340
virtual const bean_t & getBean() const
Returns the wrapped bean.
Definition Command.h:370
virtual bean_t & getBean()
Returns the wrapped bean.
Definition Command.h:376
const std::string & getName() const final
Returns the command name.
Definition Command.h:384
virtual const drain::ReferenceMap & getParameters() const
Returns the command parameters.
Definition Command.h:396
const std::string & getDescription() const final
Returns the command description.
Definition Command.h:390
BeanCommand(const BeanCommand &cmd)
Copy constructor.
Definition Command.h:353
BeanCommand(const std::string &name, const std::string &description)
Constructor.
Definition Command.h:349
B bean_t
The bean type.
Definition Command.h:362
BeanCommand(B &b)
Constructor wrapping an existing bean.
Definition Command.h:359
B2 bean
The wrapped bean instance.
Definition Command.h:365
Something which has a name, a description and possibly some parameters of varying type.
Definition BeanLike.h:58
Definition Command.h:435
Base class for commands: typically actions taking parameters but also plain variable assignments and ...
Definition Command.h:53
int cmd_section_type
Definition Command.h:187
std::set< std::string > relatedCommands
Set of related command keys shown in help.
Definition Command.h:255
void linkRelated(const std::string &cmdKey) const
Add related command(s), to appear in help after "See-also:" phrase.
Definition Command.h:229
std::string lastParameters
String record of the last argument(s) passed.
Definition Command.h:270
virtual const std::string & getName() const =0
Returns the class name of this command, like "CmdVerbose".
bool hasParameters() const
Returns true if this command has parameters.
Definition Command.h:135
virtual void run(const std::string &params="") final
Description of result, comparable to a return type of a function. ?
Definition Command.h:164
cmd_section_type section
Section bitmask; zero means hidden from help.
Definition Command.h:188
static const SprinterLayout cmdArgLayout
Layout flag for command argument handling.
Definition Command.h:89
virtual void getRelatedCommands(std::ostream &ostr=std::cout) const
Writes related command names to stream.
Definition Command.cpp:166
virtual void parameterKeysToStream(std::ostream &ostr) const
Writes parameter keys to stream.
Definition Command.h:244
virtual void parametersToStream(std::ostream &ostr, const std::string &indent=" ") const
By default, the "true", technical parameters.
Definition Command.cpp:132
virtual void exec() const
Run the command with current parameter values.
Definition Command.h:180
void setParameter(const std::string &key, const T &value)
Set a value to a single parameter.
Definition Command.h:122
void setParameters(const T &args)
Sets parameters from argument.
Definition Command.h:98
virtual void setParameters(const std::string &args) final
Definition Command.cpp:40
virtual void update()
Optional method for preparing command to execution.
Definition Command.h:175
Command(const Command &cmd)
Copy constructor.
Definition Command.h:67
Command & addSection(int i)
Marks this command as belonging to section i.
Definition Command.h:192
const std::string & getLastParameters() const
Returns the parameters from the last execution.
Definition Command.h:199
Definition Context.h:55
Definition Context.h:261
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:326
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition Log.h:440
Definition ReferenceMap.h:215
void copyStruct(const ReferenceMap &m, const T &src, T &dst, extLinkPolicy policy=RESERVE)
Experimental. Copies references and values of a structure to another.
Definition ReferenceMap.h:412
A single-parameter command.
Definition Command.h:487
SimpleCommand(const SimpleCommand &cmd)
Copy constructor.
Definition Command.h:526
SimpleCommand(const std::string &name, const std::string &description, const std::string &key="value", const T &initValue=T(), const std::string &unit="")
Constructor.
Definition Command.h:494
SimpleCommand(const std::string &name, const std::string &description, const std::string &key, std::initializer_list< S > l, const std::string &unit="")
Constuctor designer for SimpleCommand<Unituple<> > .
Definition Command.h:511
char separator
Default character used for splitting input and output. See setValues.
Definition SmartMap.h:81
Definition Data.h:1473
Definition Sprinter.h:136