Fawkes API Fawkes Development Version
init_options.cpp
1
2/***************************************************************************
3 * init_options.cpp - Fawkes run-time initialization options
4 *
5 * Created: Tue Jun 07 14:19:56 2011
6 * Copyright 2006-2011 Tim Niemueller [www.niemueller.de]
7 *
8 ****************************************************************************/
9
10/* This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version. A runtime exception applies to
14 * this software (see LICENSE.GPL_WRE file mentioned below for details).
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Library General Public License for more details.
20 *
21 * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22 */
23
24#include <baseapp/init_options.h>
25#include <baseapp/run.h>
26#include <utils/system/argparser.h>
27
28#include <cstdlib>
29#include <cstring>
30
31namespace fawkes {
32namespace runtime {
33
34/** @class InitOptions <baseapp/init_options.h>
35 * Initialization options class.
36 * This class provides a container for initialization options that can be
37 * passed to the Fawkes runtime. It uses the named parameter idiom which
38 * allows to set only the parameters which divert from the default value.
39 * @author Tim Niemueller
40 */
41
42/** Constructor.
43 * Initializes the default options.
44 * @param basename program base name
45 */
46InitOptions::InitOptions(const char *basename)
47{
48 basename_ = strdup(basename);
49 default_plugin_ = strdup("default");
50 has_net_tcp_port_ = false;
51 net_tcp_port_ = 0;
52 has_loggers_ = false;
53 loggers_ = NULL;
54 log_level_ = Logger::LL_DEBUG;
55 has_net_service_name_ = false;
56 net_service_name_ = NULL;
57 has_username_ = false;
58 username_ = NULL;
59 has_groupname_ = false;
60 groupname_ = NULL;
61 config_file_ = NULL;
62 daemonize_ = false;
63 daemon_pid_file_ = NULL;
64 daemonize_kill_ = false;
65 daemonize_status_ = false;
66 show_help_ = false;
67 bb_cleanup_ = false;
68 default_signal_handlers_ = true;
69 init_plugin_cache_ = true;
70 has_load_plugin_list_ = false;
71 load_plugin_list_ = NULL;
72 plugin_module_flags_ = Module::MODULE_FLAGS_DEFAULT;
73}
74
75/** Copy constructor.
76 * @param options options object to copy
77 */
79{
80 basename_ = strdup(options.basename_);
81 default_plugin_ = strdup(options.default_plugin_);
82 net_tcp_port_ = 0;
83 has_net_tcp_port_ = options.has_net_tcp_port_;
84 if (has_net_tcp_port_) {
85 net_tcp_port_ = options.net_tcp_port_;
86 }
87 loggers_ = NULL;
88 has_loggers_ = options.has_loggers_;
89 if (has_loggers_) {
90 loggers_ = strdup(options.loggers_);
91 }
92
93 log_level_ = options.log_level_;
94
95 net_service_name_ = NULL;
96 has_net_service_name_ = options.has_net_service_name_;
97 if (has_net_service_name_) {
98 net_service_name_ = strdup(options.net_service_name_);
99 }
100
101 username_ = NULL;
102 has_username_ = options.has_username_;
103 if (has_username_) {
104 username_ = strdup(options.username_);
105 }
106 groupname_ = NULL;
107 has_groupname_ = options.has_groupname_;
108 if (has_groupname_) {
109 groupname_ = strdup(options.groupname_);
110 }
111
112 config_file_ = NULL;
113 if (options.config_file_) {
114 config_file_ = strdup(options.config_file_);
115 }
116 daemonize_ = options.daemonize_;
117 daemon_pid_file_ = NULL;
118 if (daemonize_ && options.daemon_pid_file_) {
119 daemon_pid_file_ = strdup(options.daemon_pid_file_);
120 }
121 daemonize_kill_ = options.daemonize_kill_;
122 daemonize_status_ = options.daemonize_status_;
123 show_help_ = options.show_help_;
124 bb_cleanup_ = options.bb_cleanup_;
125 default_signal_handlers_ = options.default_signal_handlers_;
126 init_plugin_cache_ = options.init_plugin_cache_;
127 load_plugin_list_ = NULL;
128 has_load_plugin_list_ = options.has_load_plugin_list_;
129 if (has_load_plugin_list_) {
130 load_plugin_list_ = strdup(options.load_plugin_list_);
131 }
132
133 plugin_module_flags_ = options.plugin_module_flags_;
134}
135
136/** Constructor from arguments.
137 * Initializes the options from arguments passed from the command line.
138 * @param argc number of elements in @p argv
139 * @param argv argument array
140 */
141InitOptions::InitOptions(int argc, char **argv)
142{
143 option long_options[] = {{"net-service-name", 1, 0, 0}, {0, 0, 0, 0}};
144
145 fawkes::runtime::argument_parser =
146 new ArgumentParser(argc, argv, "hCc:dq::l:L:p:P:u:g:D::ks", long_options);
147
148 ArgumentParser *argp = fawkes::runtime::argument_parser;
149
150 basename_ = strdup(argp->program_name());
151 default_plugin_ = strdup("default");
152
153 has_net_tcp_port_ = argp->has_arg("P");
154 if (has_net_tcp_port_) {
155 net_tcp_port_ = argp->parse_int("P");
156 }
157 has_loggers_ = argp->has_arg("L");
158 if (has_loggers_) {
159 loggers_ = strdup(argp->arg("L"));
160 }
161
162 const char *tmp;
163 log_level_ = Logger::LL_INFO;
164 if (argp->has_arg("d")) {
165 log_level_ = Logger::LL_DEBUG;
166 } else if (argp->has_arg("q")) {
167 log_level_ = Logger::LL_WARN;
168 if ((tmp = argp->arg("q")) != NULL) {
169 for (unsigned int i = 0; i < strlen(tmp); ++i) {
170 if (tmp[i] == 'q') {
171 switch (log_level_) {
172 case Logger::LL_INFO: log_level_ = Logger::LL_WARN; break;
173 case Logger::LL_WARN: log_level_ = Logger::LL_ERROR; break;
174 case Logger::LL_ERROR: log_level_ = Logger::LL_NONE; break;
175 default: break;
176 }
177 }
178 }
179 }
180 } else if ((tmp = argp->arg("l")) != NULL) {
181 if (strcmp(tmp, "debug") == 0) {
182 log_level_ = Logger::LL_DEBUG;
183 } else if (strcmp(tmp, "info") == 0) {
184 log_level_ = Logger::LL_INFO;
185 } else if (strcmp(tmp, "warn") == 0) {
186 log_level_ = Logger::LL_WARN;
187 } else if (strcmp(tmp, "error") == 0) {
188 log_level_ = Logger::LL_ERROR;
189 } else if (strcmp(tmp, "none") == 0) {
190 log_level_ = Logger::LL_NONE;
191 }
192 }
193
194 has_net_service_name_ = argp->has_arg("net-service-name");
195 if (has_net_service_name_) {
196 net_service_name_ = strdup(argp->arg("net-service-name"));
197 } else {
198 net_service_name_ = NULL;
199 }
200
201 has_username_ = argp->has_arg("u");
202 if (has_username_) {
203 username_ = strdup(argp->arg("u"));
204 } else {
205 username_ = NULL;
206 }
207
208 has_groupname_ = argp->has_arg("u");
209 if (has_groupname_) {
210 groupname_ = strdup(argp->arg("u"));
211 } else {
212 groupname_ = NULL;
213 }
214
215 config_file_ = NULL;
216 if (argp->arg("c")) {
217 config_file_ = strdup(argp->arg("c"));
218 }
219
220 daemonize_ = argp->has_arg("D");
221 daemonize_kill_ = daemonize_ && argp->has_arg("k");
222 daemonize_status_ = daemonize_ && argp->has_arg("s");
223 daemon_pid_file_ = NULL;
224 if (daemonize_ && argp->arg("D")) {
225 daemon_pid_file_ = strdup(argp->arg("D"));
226 } else {
227 daemon_pid_file_ = NULL;
228 }
229 show_help_ = argp->has_arg("h");
230 bb_cleanup_ = argp->has_arg("C");
231
232 has_load_plugin_list_ = argp->has_arg("p") || argp->num_items() > 0;
233 if (has_load_plugin_list_) {
234 uint len = 0;
235 for (uint i = 0; i < argp->items().size(); i++) {
236 len += strlen(argp->items()[i]);
237 }
238 if (argp->has_arg("p")) {
239 len += strlen(argp->arg("p") + 1);
240 }
241 char res[len + argp->items().size()];
242 if (argp->has_arg("p") && argp->num_items() > 0) {
243 sprintf(res, "%s,%s,", argp->arg("p"), argp->items()[0]);
244 } else if (argp->has_arg("p")) {
245 sprintf(res, "%s", argp->arg("p"));
246 } else {
247 sprintf(res, "%s", argp->items()[0]);
248 }
249 for (uint i = 1; i < argp->items().size(); i++) {
250 char *tmp = strdup(res);
251 sprintf(res, "%s,%s", tmp, argp->items()[i]);
252 free(tmp);
253 }
254 load_plugin_list_ = strdup(res);
255 } else {
256 load_plugin_list_ = NULL;
257 }
258
259 init_plugin_cache_ = true;
260 plugin_module_flags_ = Module::MODULE_FLAGS_DEFAULT;
261 default_signal_handlers_ = true;
262}
263
264/** Destructor. */
266{
267 free(basename_);
268 free(default_plugin_);
269 if (has_loggers_)
270 free(loggers_);
271 if (has_net_service_name_)
272 free(net_service_name_);
273 if (has_username_)
274 free(username_);
275 if (has_groupname_)
276 free(groupname_);
277 if (has_load_plugin_list_)
278 free(load_plugin_list_);
279 if (config_file_)
280 free(config_file_);
281 if (daemon_pid_file_)
282 free(daemon_pid_file_);
283}
284
285/** Assignment operator.
286 * @param options options object to copy
287 * @return reference to this instance
288 */
291{
292 free(basename_);
293 basename_ = strdup(options.basename_);
294 free(default_plugin_);
295 default_plugin_ = strdup(options.default_plugin_);
296 net_tcp_port_ = 0;
297 has_net_tcp_port_ = options.has_net_tcp_port_;
298 if (has_net_tcp_port_) {
299 net_tcp_port_ = options.net_tcp_port_;
300 }
301 if (has_loggers_) {
302 has_loggers_ = false;
303 free(loggers_);
304 loggers_ = NULL;
305 }
306 has_loggers_ = options.has_loggers_;
307 if (has_loggers_) {
308 loggers_ = strdup(options.loggers_);
309 }
310
311 log_level_ = options.log_level_;
312
313 if (has_net_service_name_) {
314 has_net_service_name_ = false;
315 free(net_service_name_);
316 net_service_name_ = NULL;
317 }
318 has_net_service_name_ = options.has_net_service_name_;
319 if (has_net_service_name_) {
320 net_service_name_ = strdup(options.net_service_name_);
321 }
322
323 if (has_username_) {
324 has_username_ = false;
325 free(username_);
326 username_ = NULL;
327 }
328 has_username_ = options.has_username_;
329 if (has_username_) {
330 username_ = strdup(options.username_);
331 }
332
333 if (has_groupname_) {
334 has_groupname_ = false;
335 free(groupname_);
336 groupname_ = NULL;
337 }
338 groupname_ = NULL;
339 has_groupname_ = options.has_groupname_;
340 if (has_groupname_) {
341 groupname_ = strdup(options.groupname_);
342 }
343
344 if (config_file_) {
345 free(config_file_);
346 config_file_ = NULL;
347 }
348 if (options.config_file_) {
349 config_file_ = strdup(options.config_file_);
350 }
351
352 daemonize_ = options.daemonize_;
353 if (daemon_pid_file_) {
354 free(daemon_pid_file_);
355 daemon_pid_file_ = NULL;
356 }
357 if (daemonize_ && options.daemon_pid_file_) {
358 daemon_pid_file_ = strdup(options.daemon_pid_file_);
359 }
360 daemonize_kill_ = options.daemonize_kill_;
361 daemonize_status_ = options.daemonize_status_;
362 show_help_ = options.show_help_;
363 bb_cleanup_ = options.bb_cleanup_;
364
365 if (load_plugin_list_) {
366 free(load_plugin_list_);
367 load_plugin_list_ = NULL;
368 }
369 has_load_plugin_list_ = options.has_load_plugin_list_;
370 if (has_load_plugin_list_) {
371 load_plugin_list_ = strdup(options.load_plugin_list_);
372 }
373
374 init_plugin_cache_ = options.init_plugin_cache_;
375 plugin_module_flags_ = options.plugin_module_flags_;
376 default_signal_handlers_ = options.default_signal_handlers_;
377
378 return *this;
379}
380
381/** Set additional default plugin name.
382 * @param default_plugin additional default plugin name
383 * @return reference to this instance
384 */
386InitOptions::default_plugin(const char *default_plugin)
387{
388 free(default_plugin_);
389 default_plugin_ = strdup(default_plugin);
390 return *this;
391}
392
393/** Set Fawkes network TCP port.
394 * @param port TCP port
395 * @return reference to this instance
396 */
398InitOptions::net_tcp_port(unsigned short int port)
399{
400 has_net_tcp_port_ = true;
401 net_tcp_port_ = port;
402 return *this;
403}
404
405/** Set Fawkes network service name.
406 * @param service_name service name
407 * @return reference to this instance
408 */
410InitOptions::net_service_name(const char *service_name)
411{
412 if (has_net_service_name_) {
413 has_net_service_name_ = false;
414 free(net_service_name_);
415 }
416 if (service_name) {
417 has_net_service_name_ = true;
418 net_service_name_ = strdup(service_name);
419 }
420 return *this;
421}
422
423/** Set daemonization options.
424 * @param daemonize daemonization requested
425 * @param kill kill a running daemon
426 * @param status print status about running daemon
427 * @param pid_file path to file to write PID to
428 * @return reference to this instance
429 */
431InitOptions::daemonize(bool daemonize, bool kill, bool status, const char *pid_file)
432{
433 daemonize_ = daemonize;
434 daemonize_kill_ = daemonize && kill;
435 daemonize_status_ = daemonize && status;
436 if (daemonize && pid_file) {
437 daemon_pid_file_ = strdup(pid_file);
438 }
439 return *this;
440}
441
442/** Set loggers.
443 * @param loggers string of loggers
444 * @return reference to this instance
445 */
447InitOptions::loggers(const char *loggers)
448{
449 if (has_loggers_) {
450 has_loggers_ = false;
451 free(loggers_);
452 }
453 if (loggers) {
454 has_loggers_ = true;
455 loggers_ = strdup(loggers);
456 }
457 return *this;
458}
459
460/** Set log level.
461 * @param log_level desired log level
462 * @return reference to this instance
463 */
466{
467 log_level_ = log_level;
468 return *this;
469}
470
471/** Set to show help.
472 * @param show_help true to request showing help information, false otherwise
473 * @return reference to this instance
474 */
477{
478 show_help_ = show_help;
479 return *this;
480}
481
482/** Enable or disable plugin cache initialization.
483 * @param init_cache true to trigger plugin cache initialization, false to disable
484 * @return reference to this instance
485 */
488{
489 init_plugin_cache_ = init_cache;
490 return *this;
491}
492
493/** Set user name to run as.
494 * @param username user name to run as
495 * @return reference to this instance
496 */
498InitOptions::user(const char *username)
499{
500 if (has_username_) {
501 has_username_ = false;
502 free(username_);
503 }
504 if (username) {
505 has_username_ = true;
506 username_ = strdup(username);
507 }
508 return *this;
509}
510
511/** Set list of plugins to load during startup.
512 * @param plugin_list comma-separated list of names of plugins to load
513 * @return reference to this instance
514 */
516InitOptions::load_plugins(const char *plugin_list)
517{
518 if (has_load_plugin_list_) {
519 has_load_plugin_list_ = false;
520 free(load_plugin_list_);
521 load_plugin_list_ = NULL;
522 }
523 if (plugin_list) {
524 has_load_plugin_list_ = true;
525 load_plugin_list_ = strdup(plugin_list);
526 }
527 return *this;
528}
529
530/** Set group name to run as.
531 * @param groupname user name to run as
532 * @return reference to this instance
533 */
535InitOptions::group(const char *groupname)
536{
537 if (has_groupname_) {
538 has_groupname_ = false;
539 free(groupname_);
540 }
541 if (groupname) {
542 has_groupname_ = true;
543 groupname_ = strdup(groupname);
544 }
545 return *this;
546}
547
548/** Set config file path.
549 * @param config_file config file path
550 * @return reference to this instance
551 */
553InitOptions::config_file(const char *config_file)
554{
555 if (config_file_) {
556 free(config_file_);
557 config_file_ = NULL;
558 }
559 if (config_file) {
560 config_file_ = strdup(config_file);
561 }
562 return *this;
563}
564
565/** Set blackboard cleanup.
566 * @param bb_cleanup true to run blackboard cleanup, false otherwise
567 * @return reference to this instance
568 */
571{
572 bb_cleanup_ = bb_cleanup;
573 return *this;
574}
575
576/** Set module flags.
577 * @param flags flags to open plugin modules with
578 * @return reference to this instance
579 */
582{
583 plugin_module_flags_ = flags;
584 return *this;
585}
586
587/** Set default signal handlers.
588 * @param enable true to enable default signal handlers, false to disable. Note
589 * that if you disable the signal handlers you must stop the Fawkes main thread
590 * execution by yourself by some other means.
591 * @return reference to this instance
592 */
595{
596 default_signal_handlers_ = enable;
597 return *this;
598}
599
600/** Get program basename.
601 * @return program base name
602 */
603const char *
605{
606 return basename_;
607}
608
609/** Get name of default plugin.
610 * This is usually the name of a meta plugin to load the appropriate
611 * plugins. It may have a specialized name on a specific robot
612 * platform. It defaults to "default". Note that "default" is always
613 * loaded to avoid confusion.
614 * @return default plugin name
615 */
616const char *
618{
619 return default_plugin_;
620}
621
622/** Check if TCP port has been passed.
623 * @return true if the parameter has been set, false otherwise
624 */
625bool
627{
628 return has_net_tcp_port_;
629}
630
631/** Get Fawkes network TCP port.
632 * @return Fawkes network TCP port
633 */
634unsigned short int
636{
637 return net_tcp_port_;
638}
639
640/** Check if network service name has been passed.
641 * @return true if the parameter has been set, false otherwise
642 */
643bool
645{
646 return has_net_service_name_;
647}
648
649/** Get network service name.
650 * @return network service name
651 */
652const char *
654{
655 return net_service_name_;
656}
657
658/** Check if plugin load list has been set.
659 * @return true if the parameter has been set, false otherwise
660 */
661bool
663{
664 return has_load_plugin_list_;
665}
666
667/** Get plugin load list.
668 * @return plugin load list
669 */
670const char *
672{
673 return load_plugin_list_;
674}
675
676/** Check if logger string has been passed.
677 * @return true if the parameter has been set, false otherwise
678 */
679bool
681{
682 return has_loggers_;
683}
684
685/** Get logger string.
686 * @return logger stirng
687 */
688const char *
690{
691 return loggers_;
692}
693
694/** Get log level.
695 * @return log level
696 */
699{
700 return log_level_;
701}
702
703/** Check if help has been requested.
704 * @return true if help has been requested, false otherwise
705 */
706bool
708{
709 return show_help_;
710}
711
712/** Check if blackboard cleanup has been requested.
713 * @return true if blackboard cleanup has been requested, false otherwise
714 */
715bool
717{
718 return bb_cleanup_;
719}
720
721/** Check if plugin cache initialization has been requested.
722 * @return true if plugin cache initialization has been requested, false otherwise
723 */
724bool
726{
727 return init_plugin_cache_;
728}
729
730/** Check if default signal handlers should be enabled.
731 * @return true if default signal handlers have been requested, false otherwise
732 */
733bool
735{
736 return default_signal_handlers_;
737}
738
739/** Check if daemonization has been requested.
740 * @return true if daemonization has been requested, false otherwise
741 */
742bool
744{
745 return daemonize_;
746}
747
748/** Check if killing of daemon has been requested.
749 * @return true if killing of daemon has been requested, false otherwise
750 */
751bool
753{
754 return daemonize_kill_;
755}
756
757/** Check if status of daemon has been requested.
758 * @return true if status of daemon has been requested, false otherwise
759 */
760bool
762{
763 return daemonize_status_;
764}
765
766/** Get daemon PID file.
767 * @return daemon PID file path
768 */
769const char *
771{
772 return daemon_pid_file_;
773}
774
775/** Check if user name has been passed.
776 * @return true if the parameter has been set, false otherwise
777 */
778bool
780{
781 return has_username_;
782}
783
784/** Get user name to run as.
785 * @return user name to run as
786 */
787const char *
789{
790 return username_;
791}
792
793/** Check if group name has been passed.
794 * @return true if the parameter has been set, false otherwise
795 */
796bool
798{
799 return has_groupname_;
800}
801
802/** Get group name to run as.
803 * @return group name to run as
804 */
805const char *
807{
808 return groupname_;
809}
810
811/** Get config file path.
812 * @return config file path
813 */
814const char *
816{
817 return config_file_;
818}
819
820/** Get plugin module flags.
821 * @return plugin module flags
822 */
825{
826 return plugin_module_flags_;
827}
828
829} // end namespace runtime
830} // end namespace fawkes
Parse command line arguments.
Definition: argparser.h:64
const char * program_name() const
Get name of program.
Definition: argparser.cpp:483
const std::vector< const char * > & items() const
Get non-option items.
Definition: argparser.cpp:447
const char * arg(const char *argn)
Get argument value.
Definition: argparser.cpp:177
std::vector< constchar * >::size_type num_items() const
Get number of non-option items.
Definition: argparser.cpp:456
long int parse_int(const char *argn)
Parse argument as integer.
Definition: argparser.cpp:359
bool has_arg(const char *argn)
Check if argument has been supplied.
Definition: argparser.cpp:165
LogLevel
Log level.
Definition: logger.h:51
@ LL_INFO
informational output about normal procedures
Definition: logger.h:53
@ LL_WARN
warning, should be investigated but software still functions, an example is that something was reques...
Definition: logger.h:54
@ LL_NONE
use this to disable log output
Definition: logger.h:60
@ LL_ERROR
error, may be recoverable (software still running) or not (software has to terminate).
Definition: logger.h:57
@ LL_DEBUG
debug output, relevant only when tracking down problems
Definition: logger.h:52
ModuleFlags
Flags for the loading process.
Definition: module.h:44
@ MODULE_FLAGS_DEFAULT
Default flags, these are MODULE_BIND_GLOBAL, MODULE_BIND_NOW and MODULE_BIND_DEEP.
Definition: module.h:46
Initialization options class.
Definition: init_options.h:34
bool has_net_tcp_port() const
Check if TCP port has been passed.
bool daemonize_kill() const
Check if killing of daemon has been requested.
bool has_loggers() const
Check if logger string has been passed.
const char * daemon_pid_file() const
Get daemon PID file.
const char * load_plugin_list() const
Get plugin load list.
InitOptions & operator=(const InitOptions &options)
Assignment operator.
bool daemonize_status() const
Check if status of daemon has been requested.
bool daemonize() const
Check if daemonization has been requested.
const char * username() const
Get user name to run as.
const char * net_service_name() const
Get network service name.
Module::ModuleFlags plugin_module_flags() const
Get plugin module flags.
InitOptions & group(const char *groupname)
Set group name to run as.
Logger::LogLevel log_level() const
Get log level.
bool has_net_service_name() const
Check if network service name has been passed.
InitOptions & load_plugins(const char *plugin_list)
Set list of plugins to load during startup.
unsigned short int net_tcp_port() const
Get Fawkes network TCP port.
bool init_plugin_cache() const
Check if plugin cache initialization has been requested.
bool default_signal_handlers() const
Check if default signal handlers should be enabled.
const char * config_file() const
Get config file path.
bool has_username() const
Check if user name has been passed.
bool bb_cleanup() const
Check if blackboard cleanup has been requested.
const char * default_plugin() const
Get name of default plugin.
const char * basename() const
Get program basename.
bool show_help() const
Check if help has been requested.
InitOptions & user(const char *username)
Set user name to run as.
bool has_groupname() const
Check if group name has been passed.
bool has_load_plugin_list() const
Check if plugin load list has been set.
const char * loggers() const
Get logger string.
InitOptions(const char *basename)
Constructor.
const char * groupname() const
Get group name to run as.
Fawkes library namespace.