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 <cstring>
29 #include <cstdlib>
30 
31 namespace fawkes {
32  namespace runtime {
33 #if 0 /* just to make Emacs auto-indent happy */
34  }
35 }
36 #endif
37 
38 
39 /** @class InitOptions <baseapp/init_options.h>
40  * Initialization options class.
41  * This class provides a container for initialization options that can be
42  * passed to the Fawkes runtime. It uses the named parameter idiom which
43  * allows to set only the parameters which divert from the default value.
44  * @author Tim Niemueller
45  */
46 
47 
48 /** Constructor.
49  * Initializes the default options.
50  * @param basename program base name
51  */
52 InitOptions::InitOptions(const char *basename)
53 {
54  __basename = strdup(basename);
55  __default_plugin = strdup("default");
56  __has_net_tcp_port = false;
57  __net_tcp_port = 0;
58  __has_loggers = false;
59  __loggers = NULL;
60  __log_level = Logger::LL_DEBUG;
61  __has_net_service_name = false;
62  __net_service_name = NULL;
63  __has_username = false;
64  __username = NULL;
65  __has_groupname = false;
66  __groupname = NULL;
67  __default_config = NULL;
68  __host_config = NULL;
69  __daemonize = false;
70  __daemon_pid_file = NULL;
71  __daemonize_kill = false;
72  __daemonize_status = false;
73  __show_help = false;
74  __bb_cleanup = false;
75  __default_signal_handlers = true;
76  __init_plugin_cache = true;
77  __has_load_plugin_list = false;
78  __load_plugin_list = NULL;
79  __plugin_module_flags = Module::MODULE_FLAGS_DEFAULT;
80 }
81 
82 
83 /** Copy constructor.
84  * @param options options object to copy
85  */
86 InitOptions::InitOptions(const InitOptions &options)
87 {
88  __basename = strdup(options.__basename);
89  __default_plugin = strdup(options.__default_plugin);
90  __net_tcp_port = 0;
91  __has_net_tcp_port = options.__has_net_tcp_port;
92  if (__has_net_tcp_port) {
93  __net_tcp_port = options.__net_tcp_port;
94  }
95  __loggers = NULL;
96  __has_loggers = options.__has_loggers;
97  if (__has_loggers) {
98  __loggers = strdup(options.__loggers);
99  }
100 
101  __log_level = options.__log_level;
102 
103  __net_service_name = NULL;
104  __has_net_service_name = options.__has_net_service_name;
105  if (__has_net_service_name) {
106  __net_service_name = strdup(options.__net_service_name);
107  }
108 
109  __username = NULL;
110  __has_username = options.__has_username;
111  if (__has_username) {
112  __username = strdup(options.__username);
113  }
114  __groupname = NULL;
115  __has_groupname = options.__has_groupname;
116  if (__has_groupname) {
117  __groupname = strdup(options.__groupname);
118  }
119 
120  __default_config = NULL;
121  if (options.__default_config) {
122  __default_config = strdup(options.__default_config);
123  }
124  __host_config = NULL;
125  if (options.__host_config) {
126  __host_config = strdup(options.__host_config);
127  }
128  __daemonize = options.__daemonize;
129  __daemon_pid_file = NULL;
130  if (__daemonize && options.__daemon_pid_file) {
131  __daemon_pid_file = strdup(options.__daemon_pid_file);
132  }
133  __daemonize_kill = options.__daemonize_kill;
134  __daemonize_status = options.__daemonize_status;
135  __show_help = options.__show_help;
136  __bb_cleanup = options.__bb_cleanup;
137  __default_signal_handlers = options.__default_signal_handlers;
138  __init_plugin_cache = options.__init_plugin_cache;
139  __load_plugin_list = NULL;
140  __has_load_plugin_list = options.__has_load_plugin_list;
141  if (__has_load_plugin_list) {
142  __load_plugin_list = strdup(options.__load_plugin_list);
143  }
144 
145  __plugin_module_flags = options.__plugin_module_flags;
146 }
147 
148 
149 /** Constructor from arguments.
150  * Initializes the options from arguments passed from the command line.
151  * @param argc number of elements in @p argv
152  * @param argv argument array
153  */
154 InitOptions::InitOptions(int argc, char **argv)
155 {
156 
157  option long_options[] = {
158  {"net-service-name", 1, 0, 0},
159  {0, 0, 0, 0}
160  };
161 
162  fawkes::runtime::argument_parser =
163  new ArgumentParser(argc, argv,
164  "hCc:d:q::l:L:p:P:u:g:D::ks",
165  long_options);
166 
167  ArgumentParser *argp = fawkes::runtime::argument_parser;
168 
169  __basename = strdup(argp->program_name());
170  __default_plugin = strdup("default");
171 
172  __has_net_tcp_port = argp->has_arg("P");
173  if (__has_net_tcp_port) {
174  __net_tcp_port = argp->parse_int("P");
175  }
176  __has_loggers = argp->has_arg("L");
177  if (__has_loggers) {
178  __loggers = strdup(argp->arg("L"));
179  }
180 
181  const char *tmp;
182  __log_level = Logger::LL_DEBUG;
183  if ( argp->has_arg("q") ) {
184  __log_level = Logger::LL_INFO;
185  if ( (tmp = argp->arg("q")) != NULL ) {
186  for (unsigned int i = 0; i < strlen(tmp); ++i) {
187  if ( tmp[i] == 'q' ) {
188  switch (__log_level) {
189  case Logger::LL_INFO: __log_level = Logger::LL_WARN; break;
190  case Logger::LL_WARN: __log_level = Logger::LL_ERROR; break;
191  case Logger::LL_ERROR: __log_level = Logger::LL_NONE; break;
192  default: break;
193  }
194  }
195  }
196  }
197  } else if ( (tmp = argp->arg("l")) != NULL ) {
198  if ( strcmp(tmp, "debug") == 0 ) {
199  __log_level = Logger::LL_DEBUG;
200  } else if ( strcmp(tmp, "info") == 0 ) {
201  __log_level = Logger::LL_INFO;
202  } else if ( strcmp(tmp, "warn") == 0 ) {
203  __log_level = Logger::LL_WARN;
204  } else if ( strcmp(tmp, "error") == 0 ) {
205  __log_level = Logger::LL_ERROR;
206  } else if ( strcmp(tmp, "none") == 0 ) {
207  __log_level = Logger::LL_NONE;
208  }
209  }
210 
211  __has_net_service_name = argp->has_arg("net-service-name");
212  if (__has_net_service_name) {
213  __net_service_name = strdup(argp->arg("net-service-name"));
214  } else {
215  __net_service_name = NULL;
216  }
217 
218  __has_username = argp->has_arg("u");
219  if (__has_username) {
220  __username = strdup(argp->arg("u"));
221  } else {
222  __username = NULL;
223  }
224 
225  __has_groupname = argp->has_arg("u");
226  if (__has_groupname) {
227  __groupname = strdup(argp->arg("u"));
228  } else {
229  __groupname = NULL;
230  }
231 
232 
233  __default_config = NULL;
234  __host_config = NULL;
235  if (argp->arg("d")) {
236  __default_config = strdup(argp->arg("d"));
237  }
238  if (argp->arg("c")) {
239  __host_config = strdup(argp->arg("c"));
240  }
241 
242  __daemonize = argp->has_arg("D");
243  __daemonize_kill = __daemonize && argp->has_arg("k");
244  __daemonize_status = __daemonize && argp->has_arg("s");
245  __daemon_pid_file = NULL;
246  if (__daemonize && argp->arg("D")) {
247  __daemon_pid_file = strdup(argp->arg("D"));
248  } else {
249  __daemon_pid_file = NULL;
250  }
251  __show_help = argp->has_arg("h");
252  __bb_cleanup = argp->has_arg("C");
253 
254  __has_load_plugin_list = argp->has_arg("p");
255  if (__has_load_plugin_list) {
256  __load_plugin_list = strdup(argp->arg("p"));
257  } else {
258  __load_plugin_list = NULL;
259  }
260 
261  __init_plugin_cache = true;
262  __plugin_module_flags = Module::MODULE_FLAGS_DEFAULT;
263  __default_signal_handlers = true;
264 }
265 
266 
267 /** Destructor. */
268 InitOptions::~InitOptions()
269 {
270  free(__basename);
271  free(__default_plugin);
272  if (__has_loggers) free(__loggers);
273  if (__has_net_service_name) free(__net_service_name);
274  if (__has_username) free(__username);
275  if (__has_groupname) free(__groupname);
276  if (__has_load_plugin_list) free(__load_plugin_list);
277  if (__default_config) free(__default_config);
278  if (__host_config) free(__host_config);
279  if (__daemon_pid_file) free(__daemon_pid_file);
280 }
281 
282 
283 /** Assignment operator.
284  * @param options options object to copy
285  * @return reference to this instance
286  */
287 InitOptions &
288 InitOptions::operator=(const InitOptions &options)
289 {
290  free(__basename);
291  __basename = strdup(options.__basename);
292  free(__default_plugin);
293  __default_plugin = strdup(options.__default_plugin);
294  __net_tcp_port = 0;
295  __has_net_tcp_port = options.__has_net_tcp_port;
296  if (__has_net_tcp_port) {
297  __net_tcp_port = options.__net_tcp_port;
298  }
299  if (__has_loggers) {
300  __has_loggers = false;
301  free(__loggers);
302  __loggers = NULL;
303  }
304  __has_loggers = options.__has_loggers;
305  if (__has_loggers) {
306  __loggers = strdup(options.__loggers);
307  }
308 
309  __log_level = options.__log_level;
310 
311  if (__has_net_service_name) {
312  __has_net_service_name = false;
313  free(__net_service_name);
314  __net_service_name = NULL;
315  }
316  __has_net_service_name = options.__has_net_service_name;
317  if (__has_net_service_name) {
318  __net_service_name = strdup(options.__net_service_name);
319  }
320 
321  if (__has_username) {
322  __has_username = false;
323  free(__username);
324  __username = NULL;
325  }
326  __has_username = options.__has_username;
327  if (__has_username) {
328  __username = strdup(options.__username);
329  }
330 
331  if (__has_groupname) {
332  __has_groupname = false;
333  free(__groupname);
334  __groupname = NULL;
335  }
336  __groupname = NULL;
337  __has_groupname = options.__has_groupname;
338  if (__has_groupname) {
339  __groupname = strdup(options.__groupname);
340  }
341 
342  if (__default_config) {
343  free(__default_config);
344  __default_config = NULL;
345  }
346  if (options.__default_config) {
347  __default_config = strdup(options.__default_config);
348  }
349 
350  if (__host_config) {
351  free(__host_config);
352  __host_config = NULL;
353  }
354  if (options.__host_config) {
355  __host_config = strdup(options.__host_config);
356  }
357 
358  __daemonize = options.__daemonize;
359  if (__daemon_pid_file) {
360  free(__daemon_pid_file);
361  __daemon_pid_file = NULL;
362  }
363  if (__daemonize && options.__daemon_pid_file) {
364  __daemon_pid_file = strdup(options.__daemon_pid_file);
365  }
366  __daemonize_kill = options.__daemonize_kill;
367  __daemonize_status = options.__daemonize_status;
368  __show_help = options.__show_help;
369  __bb_cleanup = options.__bb_cleanup;
370 
371  if (__load_plugin_list) {
372  free(__load_plugin_list);
373  __load_plugin_list = NULL;
374  }
375  __has_load_plugin_list = options.__has_load_plugin_list;
376  if (__has_load_plugin_list) {
377  __load_plugin_list = strdup(options.__load_plugin_list);
378  }
379 
380  __init_plugin_cache = options.__init_plugin_cache;
381  __plugin_module_flags = options.__plugin_module_flags;
382  __default_signal_handlers = options.__default_signal_handlers;
383 
384  return *this;
385 }
386 
387 
388 /** Set additional default plugin name.
389  * @param default_plugin_ additional default plugin name
390  * @return reference to this instance
391  */
392 InitOptions &
393 InitOptions::default_plugin(const char *default_plugin_)
394 {
395  free(__default_plugin);
396  __default_plugin = strdup(default_plugin_);
397  return *this;
398 }
399 
400 
401 /** Set Fawkes network TCP port.
402  * @param port TCP port
403  * @return reference to this instance
404  */
405 InitOptions &
406 InitOptions::net_tcp_port(unsigned short int port)
407 {
408  __has_net_tcp_port = true;
409  __net_tcp_port = port;
410  return *this;
411 }
412 
413 /** Set Fawkes network service name.
414  * @param service_name service name
415  * @return reference to this instance
416  */
417 InitOptions &
418 InitOptions::net_service_name(const char *service_name)
419 {
420  if (__has_net_service_name) {
421  __has_net_service_name = false;
422  free(__net_service_name);
423  }
424  if (service_name) {
425  __has_net_service_name = true;
426  __net_service_name = strdup(service_name);
427  }
428  return *this;
429 }
430 
431 /** Set daemonization options.
432  * @param daemonize daemonization requested
433  * @param kill kill a running daemon
434  * @param status print status about running daemon
435  * @param pid_file path to file to write PID to
436  * @return reference to this instance
437  */
438 InitOptions &
439 InitOptions::daemonize(bool daemonize, bool kill, bool status,
440  const char *pid_file)
441 {
442  __daemonize = daemonize;
443  __daemonize_kill = daemonize && kill;
444  __daemonize_status = daemonize && status;
445  if (daemonize && pid_file) {
446  __daemon_pid_file = strdup(pid_file);
447  }
448  return *this;
449 }
450 
451 /** Set loggers.
452  * @param loggers string of loggers
453  * @return reference to this instance
454  */
455 InitOptions &
456 InitOptions::loggers(const char *loggers)
457 {
458  if (__has_loggers) {
459  __has_loggers = false;
460  free(__loggers);
461  }
462  if (loggers) {
463  __has_loggers = true;
464  __loggers = strdup(loggers);
465  }
466  return *this;
467 }
468 
469 /** Set log level.
470  * @param log_level desired log level
471  * @return reference to this instance
472  */
473 InitOptions &
474 InitOptions::log_level(Logger::LogLevel log_level)
475 {
476  __log_level = log_level;
477  return *this;
478 }
479 
480 /** Set to show help.
481  * @param show_help true to request showing help information, false otherwise
482  * @return reference to this instance
483  */
484 InitOptions &
485 InitOptions::show_help(bool show_help)
486 {
487  __show_help = show_help;
488  return *this;
489 }
490 
491 
492 /** Enable or disable plugin cache initialization.
493  * @param init_cache true to trigger plugin cache initialization, false to disable
494  * @return reference to this instance
495  */
496 InitOptions &
497 InitOptions::init_plugin_cache(bool init_cache)
498 {
499  __init_plugin_cache = init_cache;
500  return *this;
501 }
502 
503 /** Set user name to run as.
504  * @param username user name to run as
505  * @return reference to this instance
506  */
507 InitOptions &
508 InitOptions::user(const char *username)
509 {
510  if (__has_username) {
511  __has_username = false;
512  free(__username);
513  }
514  if (username) {
515  __has_username = true;
516  __username = strdup(username);
517  }
518  return *this;
519 }
520 
521 
522 /** Set list of plugins to load during startup.
523  * @param plugin_list comma-separated list of names of plugins to load
524  * @return reference to this instance
525  */
526 InitOptions &
527 InitOptions::load_plugins(const char *plugin_list)
528 {
529  if (__has_load_plugin_list) {
530  __has_load_plugin_list = false;
531  free(__load_plugin_list);
532  __load_plugin_list = NULL;
533  }
534  if (plugin_list) {
535  __has_load_plugin_list = true;
536  __load_plugin_list = strdup(plugin_list);
537  }
538  return *this;
539 }
540 
541 
542 /** Set group name to run as.
543  * @param groupname user name to run as
544  * @return reference to this instance
545  */
546 InitOptions &
547 InitOptions::group(const char *groupname)
548 {
549  if (__has_groupname) {
550  __has_groupname = false;
551  free(__groupname);
552  }
553  if (groupname) {
554  __has_groupname = true;
555  __groupname = strdup(groupname);
556  }
557  return *this;
558 }
559 
560 /** Set default config name.
561  * @param default_config default config name
562  * @return reference to this instance
563  */
564 InitOptions &
565 InitOptions::default_config(const char *default_config)
566 {
567  if (__default_config) {
568  free(__default_config);
569  __default_config = NULL;
570  }
571  if (default_config) {
572  __default_config = strdup(default_config);
573  }
574  return *this;
575 }
576 
577 /** Set host config name.
578  * @param host_config host config name
579  * @return reference to this instance
580  */
581 InitOptions &
582 InitOptions::host_config(const char *host_config)
583 {
584  if (__host_config) {
585  free(__host_config);
586  __host_config = NULL;
587  }
588  if (host_config) {
589  __host_config = strdup(host_config);
590  }
591  return *this;
592 }
593 
594 /** Set blackboard cleanup.
595  * @param bb_cleanup true to run blackboard cleanup, false otherwise
596  * @return reference to this instance
597  */
598 InitOptions &
599 InitOptions::bb_cleanup(bool bb_cleanup)
600 {
601  __bb_cleanup = bb_cleanup;
602  return *this;
603 }
604 
605 
606 /** Set module flags.
607  * @param flags flags to open plugin modules with
608  * @return reference to this instance
609  */
610 InitOptions &
611 InitOptions::plugin_module_flags(Module::ModuleFlags flags)
612 {
613  __plugin_module_flags = flags;
614  return *this;
615 }
616 
617 
618 /** Set default signal handlers.
619  * @param enable true to enable default signal handlers, false to disable. Note
620  * that if you disable the signal handlers you must stop the Fawkes main thread
621  * execution by yourself by some other means.
622  * @return reference to this instance
623  */
624 InitOptions &
625 InitOptions::default_signal_handlers(bool enable)
626 {
627  __default_signal_handlers = enable;
628  return *this;
629 }
630 
631 
632 /** Get program basename.
633  * @return program base name
634  */
635 const char *
636 InitOptions::basename() const
637 {
638  return __basename;
639 }
640 
641 
642 /** Get name of default plugin.
643  * This is usually the name of a meta plugin to load the appropriate
644  * plugins. It may have a specialized name on a specific robot
645  * platform. It defaults to "default". Note that "default" is always
646  * loaded to avoid confusion.
647  * @return default plugin name
648  */
649 const char *
650 InitOptions::default_plugin() const
651 {
652  return __default_plugin;
653 }
654 
655 
656 /** Check if TCP port has been passed.
657  * @return true if the parameter has been set, false otherwise
658  */
659 bool
660 InitOptions::has_net_tcp_port() const
661 {
662  return __has_net_tcp_port;
663 }
664 
665 /** Get Fawkes network TCP port.
666  * @return Fawkes network TCP port
667  */
668 unsigned short int
669 InitOptions::net_tcp_port() const
670 {
671  return __net_tcp_port;
672 }
673 
674 /** Check if network service name has been passed.
675  * @return true if the parameter has been set, false otherwise
676  */
677 bool
678 InitOptions::has_net_service_name() const
679 {
680  return __has_net_service_name;
681 }
682 
683 /** Get network service name.
684  * @return network service name
685  */
686 const char *
687 InitOptions::net_service_name() const
688 {
689  return __net_service_name;
690 }
691 
692 /** Check if plugin load list has been set.
693  * @return true if the parameter has been set, false otherwise
694  */
695 bool
696 InitOptions::has_load_plugin_list() const
697 {
698  return __has_load_plugin_list;
699 }
700 
701 /** Get plugin load list.
702  * @return plugin load list
703  */
704 const char *
705 InitOptions::load_plugin_list() const
706 {
707  return __load_plugin_list;
708 }
709 
710 /** Check if logger string has been passed.
711  * @return true if the parameter has been set, false otherwise
712  */
713 bool
714 InitOptions::has_loggers() const
715 {
716  return __has_loggers;
717 }
718 
719 /** Get logger string.
720  * @return logger stirng
721  */
722 const char *
723 InitOptions::loggers() const
724 {
725  return __loggers;
726 }
727 
728 /** Get log level.
729  * @return log level
730  */
732 InitOptions::log_level() const
733 {
734  return __log_level;
735 }
736 
737 /** Check if help has been requested.
738  * @return true if help has been requested, false otherwise
739  */
740 bool
741 InitOptions::show_help() const
742 {
743  return __show_help;
744 }
745 
746 /** Check if blackboard cleanup has been requested.
747  * @return true if blackboard cleanup has been requested, false otherwise
748  */
749 bool
750 InitOptions::bb_cleanup() const
751 {
752  return __bb_cleanup;
753 }
754 
755 
756 /** Check if plugin cache initialization has been requested.
757  * @return true if plugin cache initialization has been requested, false otherwise
758  */
759 bool
760 InitOptions::init_plugin_cache() const
761 {
762  return __init_plugin_cache;
763 }
764 
765 
766 /** Check if default signal handlers should be enabled.
767  * @return true if default signal handlers have been requested, false otherwise
768  */
769 bool
770 InitOptions::default_signal_handlers() const
771 {
772  return __default_signal_handlers;
773 }
774 
775 /** Check if daemonization has been requested.
776  * @return true if daemonization has been requested, false otherwise
777  */
778 bool
779 InitOptions::daemonize() const
780 {
781  return __daemonize;
782 }
783 
784 /** Check if killing of daemon has been requested.
785  * @return true if killing of daemon has been requested, false otherwise
786  */
787 bool
788 InitOptions::daemonize_kill() const
789 {
790  return __daemonize_kill;
791 }
792 
793 /** Check if status of daemon has been requested.
794  * @return true if status of daemon has been requested, false otherwise
795  */
796 bool
797 InitOptions::daemonize_status() const
798 {
799  return __daemonize_status;
800 }
801 
802 
803 /** Get daemon PID file.
804  * @return daemon PID file path
805  */
806 const char *
807 InitOptions::daemon_pid_file() const
808 {
809  return __daemon_pid_file;
810 }
811 
812 
813 /** Check if user name has been passed.
814  * @return true if the parameter has been set, false otherwise
815  */
816 bool
817 InitOptions::has_username() const
818 {
819  return __has_username;
820 }
821 
822 
823 /** Get user name to run as.
824  * @return user name to run as
825  */
826 const char *
827 InitOptions::username() const
828 {
829  return __username;
830 }
831 
832 /** Check if group name has been passed.
833  * @return true if the parameter has been set, false otherwise
834  */
835 bool
836 InitOptions::has_groupname() const
837 {
838  return __has_groupname;
839 }
840 
841 /** Get group name to run as.
842  * @return group name to run as
843  */
844 const char *
845 InitOptions::groupname() const
846 {
847  return __groupname;
848 }
849 
850 
851 /** Get default config.
852  * @return default config
853  */
854 const char *
855 InitOptions::default_config() const
856 {
857  return __default_config;
858 }
859 
860 
861 /** Get host config.
862  * @return host config
863  */
864 const char *
865 InitOptions::host_config() const
866 {
867  return __host_config;
868 }
869 
870 
871 /** Get plugin module flags.
872  * @return plugin module flags
873  */
875 InitOptions::plugin_module_flags() const
876 {
877  return __plugin_module_flags;
878 }
879 
880 
881 } // end namespace runtime
882 } // end namespace fawkes
LogLevel
Log level.
Definition: logger.h:45
const char * arg(const char *argn)
Get argument value.
Definition: argparser.cpp:182
Fawkes library namespace.
Parse command line arguments.
Definition: argparser.h:66
ModuleFlags
Flags for the loading process.
Definition: module.h:44
long int parse_int(const char *argn)
Parse argument as integer.
Definition: argparser.cpp:306
Initialization options class.
Definition: init_options.h:37
const char * program_name() const
Get name of program.
Definition: argparser.cpp:438
bool has_arg(const char *argn)
Check if argument has been supplied.
Definition: argparser.cpp:169