1 #ifndef _library_command__hpp__included__
2 #define _library_command__hpp__included__
16 threads::lock
& get_cmd_lock();
27 set() throw(std::bad_alloc
);
33 * Add a command to set.
35 void do_register(const std::string
& name
, factory_base
& cmd
) throw(std::bad_alloc
)
37 threads::alock
h(get_cmd_lock());
38 do_register_unlocked(name
, cmd
);
41 * Remove a command from set.
43 void do_unregister(const std::string
& name
, factory_base
& cmd
) throw(std::bad_alloc
)
45 threads::alock
h(get_cmd_lock());
46 // do_unregister_unlocked(name, cmd);
49 * Add a notification callback and call ccb on all.
51 * Parameter ccb: The create callback function.
52 * Parameter dcb: The destroy callback function.
53 * Parameter tcb: The terminate callback function.
54 * Returns: Callback handle.
56 uint64_t add_callback(std::function
<void(set
& s
, const std::string
& name
, factory_base
& cmd
)> ccb
,
57 std::function
<void(set
& s
, const std::string
& name
)> dcb
, std::function
<void(set
& s
)> tcb
)
60 threads::alock
h(get_cmd_lock());
61 return add_callback_unlocked(ccb
, dcb
, tcb
);
64 * Drop a notification callback and call dcb on all.
66 * Parameter handle: The handle of callback to drop.
68 void drop_callback(uint64_t handle
) throw()
70 threads::alock
h(get_cmd_lock());
71 drop_callback_unlocked(handle
);
74 * Obtain list of all commands so far.
76 std::map
<std::string
, factory_base
*> get_commands()
78 threads::alock
h(get_cmd_lock());
79 return get_commands_unlocked();
82 * Unlocked versions of other functions.
84 void do_register_unlocked(const std::string
& name
, factory_base
& cmd
) throw(std::bad_alloc
);
85 void do_unregister_unlocked(const std::string
& name
, factory_base
& cmd
) throw(std::bad_alloc
);
86 uint64_t add_callback_unlocked(std::function
<void(set
& s
, const std::string
& name
, factory_base
& cmd
)> ccb
,
87 std::function
<void(set
& s
, const std::string
& name
)> dcb
, std::function
<void(set
& s
)> tcb
)
88 throw(std::bad_alloc
);
89 void drop_callback_unlocked(uint64_t handle
) throw();
90 std::map
<std::string
, factory_base
*> get_commands_unlocked();
96 * A group of commands (with aliases).
102 * Create a new command group. This also places some builtin commands in that new group.
104 group() throw(std::bad_alloc
);
110 * Look up and invoke a command. The command will undergo alias expansion and recursion checking.
112 * parameter cmd: Command to exeucte.
114 void invoke(const std::string
& cmd
) throw();
116 * Get set of aliases.
118 std::set
<std::string
> get_aliases() throw(std::bad_alloc
);
122 std::string
get_alias_for(const std::string
& aname
) throw(std::bad_alloc
);
126 void set_alias_for(const std::string
& aname
, const std::string
& avalue
) throw(std::bad_alloc
);
128 * Is alias name valid.
130 bool valid_alias_name(const std::string
& aname
) throw(std::bad_alloc
);
132 * Register a command.
134 void do_register(const std::string
& name
, base
& cmd
) throw(std::bad_alloc
)
136 threads::alock
h(get_cmd_lock());
137 do_register_unlocked(name
, cmd
);
140 * Unregister a command.
142 void do_unregister(const std::string
& name
, base
& cmd
) throw(std::bad_alloc
)
144 threads::alock
h(get_cmd_lock());
145 do_unregister_unlocked(name
, cmd
);
148 * Add all commands (including future ones) in given set.
150 void add_set(set
& s
) throw(std::bad_alloc
)
152 threads::alock
h(get_cmd_lock());
156 * Drop a set of commands.
158 void drop_set(set
& s
) throw()
160 threads::alock
h(get_cmd_lock());
161 drop_set_unlocked(s
);
164 * Set the output stream.
166 void set_output(std::ostream
& s
);
168 * Set the OOM panic routine.
170 void set_oom_panic(void (*fn
)());
174 void do_register_unlocked(const std::string
& name
, base
& cmd
) throw(std::bad_alloc
);
175 void do_unregister_unlocked(const std::string
& name
, base
& cmd
) throw(std::bad_alloc
);
176 void add_set_unlocked(set
& s
) throw(std::bad_alloc
);
177 void drop_set_unlocked(set
& s
) throw();
179 std::set
<std::string
> command_stack
;
180 std::map
<std::string
, std::list
<std::string
>> aliases
;
181 std::ostream
* output
;
182 void (*oom_panic_routine
)();
193 * Register a new command.
195 * parameter group: The group command will be part of.
196 * parameter cmd: The command to register.
197 * parameter dynamic: Should the object be freed when its parent group dies?
198 * throws std::bad_alloc: Not enough memory.
200 base(group
& group
, const std::string
& cmd
, bool dynamic
) throw(std::bad_alloc
);
203 * Deregister a command.
205 virtual ~base() throw();
210 * parameter arguments: Arguments to command.
211 * throws std::bad_alloc: Not enough memory.
212 * throws std::runtime_error: Command execution failed.
214 virtual void invoke(const std::string
& arguments
) throw(std::bad_alloc
, std::runtime_error
) = 0;
216 * Get short help for command.
218 virtual std::string
get_short_help() throw(std::bad_alloc
);
221 * Get long help for command.
223 virtual std::string
get_long_help() throw(std::bad_alloc
);
225 * Get name of command.
227 const std::string
& get_name() { return commandname
; }
229 * Notify that the parent group died.
231 * Note: Assumed to be called with global lock held.
233 void group_died() throw();
236 base
& operator=(const base
&);
237 std::string commandname
;
248 factory_base() throw() {}
250 * Register a new command.
252 * parameter _set: The set command will be part of.
253 * parameter cmd: The command to register.
254 * throws std::bad_alloc: Not enough memory.
256 void _factory_base(set
& _set
, const std::string
& cmd
) throw(std::bad_alloc
);
260 virtual ~factory_base() throw();
262 * Make a new command.
264 virtual base
* make(group
& grp
) = 0;
266 * Notify that the parent set died.
268 * Note: Assumed to be called with global lock held.
270 void set_died() throw();
272 factory_base(const factory_base
&);
273 factory_base
& operator=(const factory_base
&);
274 std::string commandname
;
284 * The filename itself.
288 * Return the filename.
290 * returns: The filename.
292 operator std::string() { return v
; }
296 * Run command function helper.
298 * parameter fn: Function pointer to invoke.
299 * parameter a: The arguments to pass.
301 template<typename
... args
>
302 void invoke_fn(void (*fn
)(args
... arguments
), const std::string
& a
);
305 * Warp function pointer as command.
307 template<typename
... args
>
308 class _fnptr
: public base
312 * Create a new command.
314 * parameter group: The group command will be part of.
315 * parameter name: Name of the command
316 * parameter description Description for the command
317 * parameter help: Help for the command.
318 * parameter fn: Function to call on command.
319 * parameter dynamic: Should the object be freed when its parent group dies?
321 _fnptr(group
& group
, const std::string
& name
, const std::string
& _description
,
322 const std::string
& _help
, void (*_fn
)(args
... arguments
), bool dynamic
= false) throw(std::bad_alloc
)
323 : base(group
, name
, dynamic
)
325 description
= _description
;
338 * parameter a: Arguments to function.
340 void invoke(const std::string
& a
) throw(std::bad_alloc
, std::runtime_error
)
345 * Get short description.
347 * returns: Description.
348 * throw std::bad_alloc: Not enough memory.
350 std::string
get_short_help() throw(std::bad_alloc
)
358 * throw std::bad_alloc: Not enough memory.
360 std::string
get_long_help() throw(std::bad_alloc
)
365 void (*fn
)(args
... arguments
);
366 std::string description
;
371 * Function pointer command factory.
373 template<typename
... args
>
374 class fnptr
: public factory_base
378 * Create a new command.
380 * parameter _set: The set command will be part of.
381 * parameter name: Name of the command
382 * parameter description Description for the command
383 * parameter help: Help for the command.
384 * parameter fn: Function to call on command.
386 fnptr(set
& _set
, const std::string
& _name
, const std::string
& _description
,
387 const std::string
& _help
, void (*_fn
)(args
... arguments
)) throw(std::bad_alloc
)
389 description
= _description
;
393 _factory_base(_set
, name
);
404 base
* make(group
& grp
) throw(std::bad_alloc
)
406 return new _fnptr
<args
...>(grp
, name
, description
, help
, fn
, true);
409 void (*fn
)(args
... arguments
);
410 std::string description
;
416 * Generic byname factory.
419 class byname_factory
: public factory_base
423 * Create a new factory.
425 byname_factory(set
& s
, const std::string
& _name
)
428 _factory_base(s
, name
);
433 ~byname_factory() throw()
439 base
* make(group
& grp
) throw(std::bad_alloc
)
441 return new T(grp
, name
);