From da2c8f50ee5caafd73470ef2e33cf2d42be23c6c Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Thu, 21 Feb 2013 19:44:32 +0100 Subject: digital/ucoolib/ucoolib/arch/host: add host support class --- digital/ucoolib/ucoolib/arch/arch.hh | 8 + digital/ucoolib/ucoolib/arch/arch.host.cc | 12 ++ digital/ucoolib/ucoolib/arch/host/Module | 2 +- digital/ucoolib/ucoolib/arch/host/host.hh | 81 ++++++++++ digital/ucoolib/ucoolib/arch/host/host.host.cc | 179 +++++++++++++++++++++ digital/ucoolib/ucoolib/arch/host/test/Makefile | 9 ++ .../ucoolib/ucoolib/arch/host/test/test_host.cc | 49 ++++++ 7 files changed, 339 insertions(+), 1 deletion(-) create mode 100644 digital/ucoolib/ucoolib/arch/host/host.hh create mode 100644 digital/ucoolib/ucoolib/arch/host/host.host.cc create mode 100644 digital/ucoolib/ucoolib/arch/host/test/Makefile create mode 100644 digital/ucoolib/ucoolib/arch/host/test/test_host.cc (limited to 'digital') diff --git a/digital/ucoolib/ucoolib/arch/arch.hh b/digital/ucoolib/ucoolib/arch/arch.hh index dbbeb51f..92aa115f 100644 --- a/digital/ucoolib/ucoolib/arch/arch.hh +++ b/digital/ucoolib/ucoolib/arch/arch.hh @@ -30,6 +30,14 @@ namespace ucoo { void arch_init (int argc, const char **argv); +#ifdef TARGET_host + +/// Retrieve program arguments. +void +arch_get_args (int &argc, const char **&argv); + +#endif + } // namespace ucoo #endif // ucoolib_arch_arch_hh diff --git a/digital/ucoolib/ucoolib/arch/arch.host.cc b/digital/ucoolib/ucoolib/arch/arch.host.cc index 4b16d4ad..1e242544 100644 --- a/digital/ucoolib/ucoolib/arch/arch.host.cc +++ b/digital/ucoolib/ucoolib/arch/arch.host.cc @@ -29,9 +29,21 @@ namespace ucoo { +static int arch_stored_argc; +static const char **arch_stored_argv; + void arch_init (int argc, const char **argv) { + arch_stored_argc = argc; + arch_stored_argv = argv; +} + +void +arch_get_args (int &argc, const char **&argv) +{ + argc = arch_stored_argc; + argv = arch_stored_argv; } void diff --git a/digital/ucoolib/ucoolib/arch/host/Module b/digital/ucoolib/ucoolib/arch/host/Module index 64d12a80..6c5a9fad 100644 --- a/digital/ucoolib/ucoolib/arch/host/Module +++ b/digital/ucoolib/ucoolib/arch/host/Module @@ -1 +1 @@ -arch_host_SOURCES := host_stream.host.cc +arch_host_SOURCES := host.host.cc host_stream.host.cc diff --git a/digital/ucoolib/ucoolib/arch/host/host.hh b/digital/ucoolib/ucoolib/arch/host/host.hh new file mode 100644 index 00000000..4cb47b25 --- /dev/null +++ b/digital/ucoolib/ucoolib/arch/host/host.hh @@ -0,0 +1,81 @@ +#ifndef ucoolib_arch_host_host_hh +#define ucoolib_arch_host_host_hh +// ucoolib - Microcontroller object oriented library. {{{ +// +// Copyright (C) 2013 Nicolas Schodet +// +// APBTeam: +// Web: http://apbteam.org/ +// Email: team AT apbteam DOT org +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// }}} +#include "ucoolib/arch/host/mex/mex_node.hh" + +#include +#include +#include + +namespace ucoo { + +/// Host support class. +class Host +{ + public: + /// Constructor, with default instance name. + Host (const std::string &default_instance_name); + /// Get instance name, strip a number of tail components if requested. + std::string get_instance (int strip = 0) const; + /// Get Mex node. Connect if not done yet. + mex::Node &get_node (); + /// Declare a command line option without value. + void add_option (char opt, const char *help); + /// Declare a command line option with value. + void add_option (char opt, const char *metavar, const char *help, + const std::string &default_value); + /// Test if option was set. + bool is_option_set (char opt) const; + /// Get value for option. + const std::string &get_option (char opt) const; + /// To be done once, parse options. + void parse_options (); + private: + /// Display usage message and exit. + void usage (int ret); + private: + /// Instance name, from default or from command line. + std::string instance_name_; + /// Mex node, or 0 if not connected yet. + std::auto_ptr node_; + /// Store options definitions and values. + struct Option + { + const char *metavar; + const char *help; + bool set; + std::string value; + }; + typedef std::map Options; + Options options_; + /// Program name, used for messages. + const char *program_name_; + /// Option parsing is done. + bool option_parsed_; +}; + +} // namespace ucoo + +#endif // ucoolib_arch_host_host_hh diff --git a/digital/ucoolib/ucoolib/arch/host/host.host.cc b/digital/ucoolib/ucoolib/arch/host/host.host.cc new file mode 100644 index 00000000..62af11cd --- /dev/null +++ b/digital/ucoolib/ucoolib/arch/host/host.host.cc @@ -0,0 +1,179 @@ +// ucoolib - Microcontroller object oriented library. {{{ +// +// Copyright (C) 2013 Nicolas Schodet +// +// APBTeam: +// Web: http://apbteam.org/ +// Email: team AT apbteam DOT org +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// }}} +#include "host.hh" + +#include "ucoolib/arch/arch.hh" + +#include +#include +#include +#include + +namespace ucoo { + +Host::Host (const std::string &default_instance_name) + : program_name_ ("program"), option_parsed_ (false) +{ + add_option ('i', "NAME", "instance name", default_instance_name); + add_option ('h', "display this help message"); +} + +std::string +Host::get_instance (int strip) const +{ + assert (strip >= 0); + std::string instance = get_option ('i'); + if (strip) + { + std::string::size_type end = std::string::npos; + do + { + end = instance.rfind (':', end - 1); + if (end == std::string::npos) + end = 0; + } while (end != 0 && --strip); + instance.erase (end); + } + return instance; +} + +mex::Node & +Host::get_node () +{ + if (!node_.get ()) + node_.reset (new mex::Node); + return *node_; +} + +void +Host::add_option (char opt, const char *help) +{ + Option o; + o.metavar = 0; + o.help = help; + o.set = false; + if (!options_.insert (Options::value_type (opt, o)).second) + assert_unreachable (); +} + +void +Host::add_option (char opt, const char *metavar, const char *help, + const std::string &default_value) +{ + Option o; + o.metavar = metavar; + o.help = help; + o.set = false; + o.value = default_value; + if (!options_.insert (Options::value_type (opt, o)).second) + assert_unreachable (); +} + +bool +Host::is_option_set (char opt) const +{ + assert (option_parsed_); + Options::const_iterator i = options_.find (opt); + assert (i != options_.end ()); + return i->second.set; +} + +const std::string & +Host::get_option (char opt) const +{ + assert (option_parsed_); + Options::const_iterator i = options_.find (opt); + assert (i != options_.end ()); + return i->second.value; +} + +void +Host::parse_options () +{ + // Get program arguments. + int argc; + const char **argv; + arch_get_args (argc, argv); + // Save program name. + const char *slash = std::strrchr (argv[0], '/'); + program_name_ = slash ? slash + 1 : argv[0]; + // Parse. + std::string getoptdesc; + for (Options::const_iterator i = options_.begin (); + i != options_.end (); ++i) + { + getoptdesc.push_back (i->first); + if (i->second.metavar) + getoptdesc.push_back (':'); + } + int c; + const char *getoptdescs = getoptdesc.c_str (); + char **getopt_argv = const_cast (argv); + while ((c = getopt (argc, getopt_argv, getoptdescs)) != -1) + { + if (c == '?') + usage (1); + else + { + Options::iterator i = options_.find (c); + assert (i != options_.end ()); + i->second.set = true; + if (i->second.metavar) + i->second.value = optarg; + } + } + if (optind != argc) + { + fprintf (stderr, "%s: too many arguments\n", argv[0]); + usage (1); + } + option_parsed_ = true; + if (is_option_set ('h')) + usage (0); +} + +void +Host::usage (int ret) +{ + FILE *out = ret == 0 ? stdout : stderr; + fprintf (out, "Usage: %s [options...]\n\nOptions:\n", program_name_); + unsigned int max_meta = 0; + for (Options::const_iterator i = options_.begin (); + i != options_.end (); ++i) + { + if (i->second.metavar) + max_meta = std::max (max_meta, + std::strlen (i->second.metavar) + 1); + } + for (Options::const_iterator i = options_.begin (); + i != options_.end (); ++i) + { + const Option &o = i->second; + fprintf (out, " -%c %-*s %s\n", i->first, max_meta, + o.metavar ? o.metavar : "", o.help); + } + exit (ret); +} + +} // namespace ucoo diff --git a/digital/ucoolib/ucoolib/arch/host/test/Makefile b/digital/ucoolib/ucoolib/arch/host/test/Makefile new file mode 100644 index 00000000..9a329a3b --- /dev/null +++ b/digital/ucoolib/ucoolib/arch/host/test/Makefile @@ -0,0 +1,9 @@ +BASE = ../../../.. + +TARGETS = host +host_PROGS = test_host +test_host_SOURCES = test_host.cc + +MODULES = + +include $(BASE)/build/top.mk diff --git a/digital/ucoolib/ucoolib/arch/host/test/test_host.cc b/digital/ucoolib/ucoolib/arch/host/test/test_host.cc new file mode 100644 index 00000000..bb328929 --- /dev/null +++ b/digital/ucoolib/ucoolib/arch/host/test/test_host.cc @@ -0,0 +1,49 @@ +// ucoolib - Microcontroller object oriented library. {{{ +// +// Copyright (C) 2013 Nicolas Schodet +// +// APBTeam: +// Web: http://apbteam.org/ +// Email: team AT apbteam DOT org +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// }}} +#include "ucoolib/arch/host/host.hh" +#include "ucoolib/arch/arch.hh" + +#include +#include + +int +main (int argc, const char **argv) +{ + ucoo::arch_init (argc, argv); + ucoo::Host host ("test_host"); + host.add_option ('c', "connect to mex hub"); + host.add_option ('p', "FOO", "print FOO", "Hello world!"); + host.add_option ('s', "STRIP", "print striped instance", ""); + host.parse_options (); + puts (host.get_option ('p').c_str ()); + if (host.is_option_set ('s')) + { + const std::string &strips = host.get_option ('s'); + int strip = atoi (strips.c_str ()); // Quick'n dirty convertion. + puts (host.get_instance (strip).c_str ()); + } + if (host.is_option_set ('c')) + host.get_node (); + return 0; +} -- cgit v1.2.3