summaryrefslogtreecommitdiffhomepage
path: root/digital
diff options
context:
space:
mode:
authorNicolas Schodet2013-02-21 19:44:32 +0100
committerNicolas Schodet2013-03-01 22:58:03 +0100
commitda2c8f50ee5caafd73470ef2e33cf2d42be23c6c (patch)
tree2a8f447f45d6294992d214335db9b55527a55792 /digital
parented853465a281b6f29bf2036d643d24b2ae367d12 (diff)
digital/ucoolib/ucoolib/arch/host: add host support class
Diffstat (limited to 'digital')
-rw-r--r--digital/ucoolib/ucoolib/arch/arch.hh8
-rw-r--r--digital/ucoolib/ucoolib/arch/arch.host.cc12
-rw-r--r--digital/ucoolib/ucoolib/arch/host/Module2
-rw-r--r--digital/ucoolib/ucoolib/arch/host/host.hh81
-rw-r--r--digital/ucoolib/ucoolib/arch/host/host.host.cc179
-rw-r--r--digital/ucoolib/ucoolib/arch/host/test/Makefile9
-rw-r--r--digital/ucoolib/ucoolib/arch/host/test/test_host.cc49
7 files changed, 339 insertions, 1 deletions
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 <string>
+#include <list>
+#include <memory>
+
+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<mex::Node> node_;
+ /// Store options definitions and values.
+ struct Option
+ {
+ const char *metavar;
+ const char *help;
+ bool set;
+ std::string value;
+ };
+ typedef std::map<char, Option> 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 <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <algorithm>
+
+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<char **> (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 <cstdio>
+#include <cstdlib>
+
+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;
+}