summaryrefslogtreecommitdiff
path: root/gruel
diff options
context:
space:
mode:
authorJohnathan Corgan2011-03-16 08:18:30 -0700
committerJohnathan Corgan2011-03-16 08:18:30 -0700
commit4cd06fadac972d4cac559c15488bc39823063afe (patch)
tree6fe57896bc216d8c9e672194f2e4e0e75aedb645 /gruel
parent4ad736e21f45f64fd616bb53f54e45e1c63e7330 (diff)
parent1d70ed2bd928d52a383e688949cc7f747dd584fa (diff)
downloadgnuradio-4cd06fadac972d4cac559c15488bc39823063afe.tar.gz
gnuradio-4cd06fadac972d4cac559c15488bc39823063afe.tar.bz2
gnuradio-4cd06fadac972d4cac559c15488bc39823063afe.zip
Merge remote branch 'gnuradio/next'
* gnuradio/next: (806 commits) gruel: added missing ignores gruel: fixed swig interface file to dereference pmt_t. qtgui: fix distcheck error gruel: fixing structure. Passes make check. gruel: SWIGing Gruel into Python to access PMTs. gnuradio-examples: add C++ audio examples using new gr-audio created gruel/attributes.h to house compiler specific attribute macros audio: remove obsoleted individual top-level components gr-audio: added README and default config fix volk: simplify the get new method for the aligned pool grc: moved all usrp1 and usrp2 stuff out of grc and into gr-usrp*/grc grc: swap store the subprocess object rather than the pid when executing qtgui: removed python directory that was added, never used uhd: use %ignore to hide warnings and fix errors Added/updated ignore files. Fixing gr_filter_design program to import from gnuradio Python package. audio: high prio for platform specific audio osx audio: added windows and osx audio source files audio: added config checks for other audios, added jack and port audio: make prefs look like old audio, removed old audio.py ...
Diffstat (limited to 'gruel')
-rw-r--r--gruel/Makefile.am4
-rw-r--r--gruel/src/Makefile.am8
-rw-r--r--gruel/src/include/gruel/Makefile.am8
-rw-r--r--gruel/src/include/gruel/attributes.h56
-rw-r--r--gruel/src/include/gruel/pmt.h16
-rw-r--r--gruel/src/include/gruel/thread.h16
-rw-r--r--gruel/src/lib/Makefile.am5
-rw-r--r--gruel/src/lib/pmt/Makefile.am10
-rw-r--r--gruel/src/lib/pmt/pmt_io.cc10
-rw-r--r--gruel/src/lib/pmt/pmt_serialize.cc107
-rw-r--r--gruel/src/lib/test_gruel.cc53
-rw-r--r--gruel/src/lib/thread.cc35
-rw-r--r--gruel/src/python/.gitignore2
-rw-r--r--gruel/src/python/Makefile.am39
-rw-r--r--gruel/src/python/__init__.py25
-rwxr-xr-xgruel/src/python/qa_pmt.py42
-rw-r--r--gruel/src/python/run_tests.in17
-rw-r--r--gruel/src/scheme/gnuradio/Makefile.am10
-rw-r--r--gruel/src/scheme/gnuradio/gen-serial-tags.py53
-rwxr-xr-xgruel/src/scheme/gnuradio/gen-serial-tags.scm118
-rw-r--r--gruel/src/swig/.gitignore2
-rw-r--r--gruel/src/swig/Makefile.am55
-rw-r--r--gruel/src/swig/Makefile.swig.gen115
-rw-r--r--gruel/src/swig/__init__.py0
-rw-r--r--gruel/src/swig/pmt_swig.i760
25 files changed, 1335 insertions, 231 deletions
diff --git a/gruel/Makefile.am b/gruel/Makefile.am
index 93f56a7db..c43e461f2 100644
--- a/gruel/Makefile.am
+++ b/gruel/Makefile.am
@@ -1,5 +1,5 @@
#
-# Copyright 2008 Free Software Foundation, Inc.
+# Copyright 2008,2010 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -21,7 +21,7 @@
include $(top_srcdir)/Makefile.common
-EXTRA_DIST = \
+EXTRA_DIST += \
gruel.pc.in
SUBDIRS = src
diff --git a/gruel/src/Makefile.am b/gruel/src/Makefile.am
index 71bdd8573..93b17d6db 100644
--- a/gruel/src/Makefile.am
+++ b/gruel/src/Makefile.am
@@ -19,5 +19,11 @@
# Boston, MA 02110-1301, USA.
#
-SUBDIRS = lib include scheme
+SUBDIRS = lib include scheme
+
+if PYTHON
+
+SUBDIRS += . swig python
+
+endif
diff --git a/gruel/src/include/gruel/Makefile.am b/gruel/src/include/gruel/Makefile.am
index 67dd12995..89a9da7f0 100644
--- a/gruel/src/include/gruel/Makefile.am
+++ b/gruel/src/include/gruel/Makefile.am
@@ -1,5 +1,5 @@
#
-# Copyright 2008,2009 Free Software Foundation, Inc.
+# Copyright 2008-2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -21,13 +21,13 @@
include $(top_srcdir)/Makefile.common
-BUILT_SOURCES = \
- inet.h
+EXTRA_DIST += inet.h.in
gruelincludedir = $(prefix)/include/gruel
gruelinclude_HEADERS = \
- $(BUILT_SOURCES) \
+ attributes.h \
+ inet.h \
msg_accepter.h \
msg_accepter_msgq.h \
msg_queue.h \
diff --git a/gruel/src/include/gruel/attributes.h b/gruel/src/include/gruel/attributes.h
new file mode 100644
index 000000000..fdf48c977
--- /dev/null
+++ b/gruel/src/include/gruel/attributes.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRUEL_ATTRIBUTES_H
+#define INCLUDED_GRUEL_ATTRIBUTES_H
+
+////////////////////////////////////////////////////////////////////////
+// Cross-platform attribute macros
+////////////////////////////////////////////////////////////////////////
+#if defined __GNUC__
+# define __GR_ATTR_ALIGNED(x) __attribute__((aligned(x)))
+# define __GR_ATTR_UNUSED __attribute__((unused))
+# define __GR_ATTR_INLINE __attribute__((always_inline))
+# define __GR_ATTR_DEPRECATED __attribute__((deprecated))
+# if __GNUC__ >= 4
+# define __GR_ATTR_EXPORT __attribute__((visibility("default")))
+# define __GR_ATTR_IMPORT __attribute__((visibility("default")))
+# else
+# define __GR_ATTR_EXPORT
+# define __GR_ATTR_IMPORT
+# endif
+#elif _MSC_VER
+# define __GR_ATTR_ALIGNED(x) __declspec(align(x))
+# define __GR_ATTR_UNUSED
+# define __GR_ATTR_INLINE __forceinline
+# define __GR_ATTR_DEPRECATED __declspec(deprecated)
+# define __GR_ATTR_EXPORT __declspec(dllexport)
+# define __GR_ATTR_IMPORT __declspec(dllimport)
+#else
+# define __GR_ATTR_ALIGNED(x)
+# define __GR_ATTR_UNUSED
+# define __GR_ATTR_INLINE
+# define __GR_ATTR_DEPRECATED
+# define __GR_ATTR_EXPORT
+# define __GR_ATTR_IMPORT
+#endif
+
+#endif /* INCLUDED_GRUEL_ATTRIBUTES_H */
diff --git a/gruel/src/include/gruel/pmt.h b/gruel/src/include/gruel/pmt.h
index 514b24d8b..2948abb39 100644
--- a/gruel/src/include/gruel/pmt.h
+++ b/gruel/src/include/gruel/pmt.h
@@ -770,6 +770,11 @@ std::string pmt_write_string(pmt_t obj);
std::ostream& operator<<(std::ostream &os, pmt_t obj);
+/*!
+ * \brief Write pmt string representation to stdout.
+ */
+void pmt_print(pmt_t v);
+
/*
* ------------------------------------------------------------------------
@@ -789,8 +794,17 @@ pmt_t pmt_deserialize(std::streambuf &source);
void pmt_dump_sizeof(); // debugging
-} /* namespace pmt */
+/*!
+ * \brief Provide a simple string generating interface to pmt's serialize function
+ */
+std::string pmt_serialize_str(pmt_t obj);
+/*!
+ * \brief Provide a simple string generating interface to pmt's deserialize function
+ */
+pmt_t pmt_deserialize_str(std::string str);
+
+} /* namespace pmt */
#include <gruel/pmt_sugar.h>
diff --git a/gruel/src/include/gruel/thread.h b/gruel/src/include/gruel/thread.h
index d72e5520c..5a8ab1876 100644
--- a/gruel/src/include/gruel/thread.h
+++ b/gruel/src/include/gruel/thread.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2009,2010 Free Software Foundation, Inc.
+ * Copyright 2009,2010,2011 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -21,21 +21,17 @@
#ifndef INCLUDED_THREAD_H
#define INCLUDED_THREAD_H
-#include <boost/thread.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/condition_variable.hpp>
namespace gruel {
typedef boost::thread thread;
typedef boost::mutex mutex;
- typedef boost::unique_lock<boost::mutex> scoped_lock;
+ typedef boost::mutex::scoped_lock scoped_lock;
typedef boost::condition_variable condition_variable;
- typedef boost::posix_time::time_duration duration;
-
- /*!
- * Returns absolute time 'secs' into the future
- */
- boost::system_time get_new_timeout(double secs);
} /* namespace gruel */
diff --git a/gruel/src/lib/Makefile.am b/gruel/src/lib/Makefile.am
index 5c3302f19..f37ab27a1 100644
--- a/gruel/src/lib/Makefile.am
+++ b/gruel/src/lib/Makefile.am
@@ -1,5 +1,5 @@
#
-# Copyright 2008,2009,2010 Free Software Foundation, Inc.
+# Copyright 2008,2009,2010,2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -45,12 +45,13 @@ MSG_LIB = msg/libmsg.la
libgruel_la_SOURCES = \
realtime.cc \
sys_pri.cc \
- thread.cc \
thread_body_wrapper.cc \
thread_group.cc
libgruel_la_LIBADD = \
$(BOOST_THREAD_LIB) \
+ $(BOOST_SYSTEM_LIB) \
+ $(BOOST_FILESYSTEM_LIB) \
$(PMT_LIB) \
$(MSG_LIB) \
-lstdc++
diff --git a/gruel/src/lib/pmt/Makefile.am b/gruel/src/lib/pmt/Makefile.am
index d3efc1afa..0c8e12dc3 100644
--- a/gruel/src/lib/pmt/Makefile.am
+++ b/gruel/src/lib/pmt/Makefile.am
@@ -1,5 +1,5 @@
#
-# Copyright 2008,2009,2010 Free Software Foundation, Inc.
+# Copyright 2008,2009,2010,2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -48,7 +48,7 @@ python_built_sources = $(GENERATED_H) $(GENERATED_CC)
PMT_SERIAL_TAGS_H = $(abs_top_builddir)/gruel/src/include/gruel/pmt_serial_tags.h
BUILT_SOURCES = $(python_built_sources) $(PMT_SERIAL_TAGS_H)
-EXTRA_DIST = $(code_generator)
+EXTRA_DIST += $(code_generator)
# ----------------------------------------------------------------
@@ -99,7 +99,7 @@ gen_sources_deps = $(core_generator)
par_gen_command = PYTHONPATH=$(top_srcdir)/gruel/src/lib/pmt srcdir=$(srcdir) $(PYTHON) $(srcdir)/generate_unv.py
include $(top_srcdir)/Makefile.par.gen
-# Rule to create the build header file using GUILE
+# Rule to create the build header file using python
# Doesn't need parallel protections because there is a single target
-$(PMT_SERIAL_TAGS_H): $(srcdir)/../../scheme/gnuradio/gen-serial-tags.scm $(srcdir)/../../scheme/gnuradio/pmt-serial-tags.scm
- $(RUN_GUILE) $(srcdir)/../../scheme/gnuradio/gen-serial-tags.scm $(srcdir)/../../scheme/gnuradio/pmt-serial-tags.scm $(PMT_SERIAL_TAGS_H)
+$(PMT_SERIAL_TAGS_H): $(top_srcdir)/gruel/src/scheme/gnuradio/gen-serial-tags.py $(top_srcdir)/gruel/src/scheme/gnuradio/pmt-serial-tags.scm
+ $(PYTHON) $^ $@
diff --git a/gruel/src/lib/pmt/pmt_io.cc b/gruel/src/lib/pmt/pmt_io.cc
index b909c1b64..1214ff588 100644
--- a/gruel/src/lib/pmt/pmt_io.cc
+++ b/gruel/src/lib/pmt/pmt_io.cc
@@ -26,6 +26,7 @@
#include <gruel/pmt.h>
#include "pmt_int.h"
#include <sstream>
+#include <iostream>
namespace pmt {
@@ -156,3 +157,12 @@ pmt_deserialize(std::istream &source)
}
} /* namespace pmt */
+
+
+void
+pmt::pmt_print(pmt_t v)
+{
+ std::cout << pmt_write_string(v) << std::endl;
+}
+
+
diff --git a/gruel/src/lib/pmt/pmt_serialize.cc b/gruel/src/lib/pmt/pmt_serialize.cc
index 937423a93..184a31e6b 100644
--- a/gruel/src/lib/pmt/pmt_serialize.cc
+++ b/gruel/src/lib/pmt/pmt_serialize.cc
@@ -59,6 +59,26 @@ serialize_untagged_u32(unsigned int i, std::streambuf &sb)
return sb.sputc((i >> 0) & 0xff) != std::streambuf::traits_type::eof();
}
+static bool
+serialize_untagged_f64(double i, std::streambuf &sb)
+{
+ typedef union {
+ double id;
+ uint64_t ii;
+ } iu_t;
+ iu_t iu;
+ iu.id = i;
+ sb.sputc((iu.ii >> 56) & 0xff);
+ sb.sputc((iu.ii >> 48) & 0xff);
+ sb.sputc((iu.ii >> 40) & 0xff);
+ sb.sputc((iu.ii >> 32) & 0xff);
+ sb.sputc((iu.ii >> 24) & 0xff);
+ sb.sputc((iu.ii >> 16) & 0xff);
+ sb.sputc((iu.ii >> 8) & 0xff);
+ return sb.sputc((iu.ii >> 0) & 0xff) != std::streambuf::traits_type::eof();
+}
+
+
#if 0
// always writes big-endian
static bool
@@ -163,6 +183,41 @@ deserialize_untagged_u64(uint64_t *ip, std::streambuf &sb)
}
#endif
+static bool
+deserialize_untagged_f64(double *ip, std::streambuf &sb)
+{
+ std::streambuf::traits_type::int_type t;
+
+ typedef union {
+ double id;
+ uint64_t ii;
+ } iu_t;
+
+ iu_t iu;
+
+ t = sb.sbumpc();
+ iu.ii = t & 0xff;
+
+ t = sb.sbumpc();
+ iu.ii = (iu.ii<<8) | (t & 0xff);
+ t = sb.sbumpc();
+ iu.ii = (iu.ii<<8) | (t & 0xff);
+ t = sb.sbumpc();
+ iu.ii = (iu.ii<<8) | (t & 0xff);
+ t = sb.sbumpc();
+ iu.ii = (iu.ii<<8) | (t & 0xff);
+ t = sb.sbumpc();
+ iu.ii = (iu.ii<<8) | (t & 0xff);
+ t = sb.sbumpc();
+ iu.ii = (iu.ii<<8) | (t & 0xff);
+ t = sb.sbumpc();
+ iu.ii = (iu.ii<<8) | (t & 0xff);
+
+ *ip = iu.id;
+ return t != std::streambuf::traits_type::eof();
+}
+
+
/*
* Write portable byte-serial representation of \p obj to \p sb
*
@@ -172,7 +227,7 @@ bool
pmt_serialize(pmt_t obj, std::streambuf &sb)
{
bool ok = true;
-
+
tail_recursion:
if (pmt_is_bool(obj)){
@@ -217,11 +272,21 @@ pmt_serialize(pmt_t obj, std::streambuf &sb)
return ok;
}
- if (pmt_is_real(obj))
- throw pmt_notimplemented("pmt_serialize (real)", obj);
+ if (pmt_is_real(obj)){
+ float i = pmt_to_double(obj);
+ ok = serialize_untagged_u8(PST_DOUBLE, sb);
+ ok &= serialize_untagged_f64(i, sb);
+ return ok;
+ }
+
+ if (pmt_is_complex(obj)){
+ std::complex<double> i = pmt_to_complex(obj);
+ ok = serialize_untagged_u8(PST_COMPLEX, sb);
+ ok &= serialize_untagged_f64(i.real(), sb);
+ ok &= serialize_untagged_f64(i.imag(), sb);
+ return ok;
+ }
- if (pmt_is_complex(obj))
- throw pmt_notimplemented("pmt_serialize (complex)", obj);
}
if (pmt_is_vector(obj))
@@ -251,6 +316,7 @@ pmt_deserialize(std::streambuf &sb)
uint16_t u16;
uint32_t u32;
//uint32_t u64;
+ double f64;
static char tmpbuf[1024];
if (!deserialize_untagged_u8(&tag, sb))
@@ -285,7 +351,18 @@ pmt_deserialize(std::streambuf &sb)
return parse_pair(sb);
case PST_DOUBLE:
+ if(!deserialize_untagged_f64(&f64, sb))
+ goto error;
+ return pmt_from_double( f64 );
+
case PST_COMPLEX:
+ {
+ double r,i;
+ if(!deserialize_untagged_f64(&r, sb) && !deserialize_untagged_f64(&i, sb))
+ goto error;
+ return pmt_make_rectangular( r,i );
+ }
+
case PST_VECTOR:
case PST_DICT:
case PST_UNIFORM_VECTOR:
@@ -302,6 +379,26 @@ pmt_deserialize(std::streambuf &sb)
throw pmt_exception("pmt_deserialize: malformed input stream", PMT_F);
}
+
+/*
+ * provide a simple string accessor to the serialized pmt form
+ */
+std::string pmt_serialize_str(pmt_t obj){
+ std::stringbuf sb;
+ pmt_serialize(obj, sb);
+ return sb.str();
+}
+
+
+/*
+ * provide a simple string accessor to the deserialized pmt form
+ */
+pmt_t pmt_deserialize_str(std::string s){
+ std::stringbuf sb(s);
+ return pmt_deserialize(sb);
+}
+
+
/*
* This is a mostly non-recursive implementation that allows us to
* deserialize very long lists w/o exhausting the evaluation stack.
diff --git a/gruel/src/lib/test_gruel.cc b/gruel/src/lib/test_gruel.cc
index 2c9528b0a..7ef3520e6 100644
--- a/gruel/src/lib/test_gruel.cc
+++ b/gruel/src/lib/test_gruel.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006,2009,2010 Free Software Foundation, Inc.
+ * Copyright 2006,2009,2010,2011 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -28,16 +28,19 @@
#include "pmt/qa_pmt.h"
-static void get_unittest_path (const char *filename, char *fullpath, size_t pathsize);
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/path.hpp>
+namespace fs = boost::filesystem;
int
main(int argc, char **argv)
{
- char path[200];
- get_unittest_path ("gruel.xml", path, 200);
-
+ fs::path path = fs::current_path() / ".unittests";
+ if (!fs::is_directory(path)) fs::create_directory(path);
+ path = path / "gruel.xml";
+
CppUnit::TextTestRunner runner;
- std::ofstream xmlfile(path);
+ std::ofstream xmlfile(path.string().c_str());
CppUnit::XmlOutputter *xmlout = new CppUnit::XmlOutputter(&runner.result(), xmlfile);
runner.addTest(qa_pmt::suite ());
@@ -47,41 +50,3 @@ main(int argc, char **argv)
return was_successful ? 0 : 1;
}
-
-
-// NOTE: These are defined in gr_unittest.h for the rest of the project;
-// rewriting here since we don't depend on gnuradio-core in gruel
-
-#ifdef MKDIR_TAKES_ONE_ARG
-#define gr_mkdir(pathname, mode) mkdir(pathname)
-#else
-#define gr_mkdir(pathname, mode) mkdir((pathname), (mode))
-#endif
-
-/*
- * Mostly taken from gr_preferences.cc/h
- * The simplest thing that could possibly work:
- * the key is the filename; the value is the file contents.
- */
-
-static void
-ensure_unittest_path (const char *path)
-{
- struct stat statbuf;
- if (stat (path, &statbuf) == 0 && S_ISDIR (statbuf.st_mode))
- return;
-
- // blindly try to make it // FIXME make this robust. C++ SUCKS!
- gr_mkdir (path, 0750);
-}
-
-static void
-get_unittest_path (const char *filename, char *fullpath, size_t pathsize)
-{
- char path[200];
- snprintf (path, sizeof(path), "./.unittests");
- snprintf (fullpath, pathsize, "%s/%s", path, filename);
-
- ensure_unittest_path(path);
-}
-
diff --git a/gruel/src/lib/thread.cc b/gruel/src/lib/thread.cc
deleted file mode 100644
index d8f77b506..000000000
--- a/gruel/src/lib/thread.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2010 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio 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 3, or (at your option)
- * any later version.
- *
- * GNU Radio 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <gruel/thread.h>
-
-namespace gruel {
-
- boost::system_time
- get_new_timeout(double secs)
- {
- return boost::get_system_time() + boost::posix_time::milliseconds(long(secs*1e3));
- }
-
-}
diff --git a/gruel/src/python/.gitignore b/gruel/src/python/.gitignore
new file mode 100644
index 000000000..b336cc7ce
--- /dev/null
+++ b/gruel/src/python/.gitignore
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gruel/src/python/Makefile.am b/gruel/src/python/Makefile.am
new file mode 100644
index 000000000..5a45510d5
--- /dev/null
+++ b/gruel/src/python/Makefile.am
@@ -0,0 +1,39 @@
+#
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio 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 3, or (at your option)
+# any later version.
+#
+# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+include $(top_srcdir)/Makefile.common
+
+TESTS =
+EXTRA_DIST += run_tests.in
+
+if PYTHON
+TESTS += run_tests
+
+grueldir = $(pythondir)/gruel
+
+noinst_PYTHON = \
+ qa_pmt.py
+
+gruel_PYTHON = \
+ __init__.py
+
+endif
+
diff --git a/gruel/src/python/__init__.py b/gruel/src/python/__init__.py
new file mode 100644
index 000000000..421a9aaa8
--- /dev/null
+++ b/gruel/src/python/__init__.py
@@ -0,0 +1,25 @@
+#
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio 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 3, or (at your option)
+# any later version.
+#
+# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+# The presence of this file turns this directory into a Python package
+
+from pmt_swig import *
+
diff --git a/gruel/src/python/qa_pmt.py b/gruel/src/python/qa_pmt.py
new file mode 100755
index 000000000..00cdb064e
--- /dev/null
+++ b/gruel/src/python/qa_pmt.py
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+#
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio 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 3, or (at your option)
+# any later version.
+#
+# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import unittest
+import pmt_swig
+
+class test_gruel_pmt(unittest.TestCase):
+
+ def test01 (self):
+ a = pmt_swig.pmt_intern("a")
+ b = pmt_swig.pmt_from_double(123765)
+ d1 = pmt_swig.pmt_make_dict()
+ d2 = pmt_swig.pmt_dict_add(d1, a, b)
+ pmt_swig.pmt_print(d2)
+
+ def test02 (self):
+ const = 123765
+ x_pmt = pmt_swig.pmt_from_double(const)
+ x_int = pmt_swig.pmt_to_double(x_pmt)
+ self.assertEqual(x_int, const)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/gruel/src/python/run_tests.in b/gruel/src/python/run_tests.in
new file mode 100644
index 000000000..ff399bcc6
--- /dev/null
+++ b/gruel/src/python/run_tests.in
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+# 1st parameter is absolute path to component source directory
+# 2nd parameter is absolute path to component build directory
+# 3rd parameter is path to Python QA directory
+
+# For OS/X
+DYLD_LIBRARY_PATH=@abs_top_builddir@/gruel/src/lib/:@abs_top_builddir@/gruel/src/swig/.libs:$DYLD_LIBRARY_PATH
+export DYLD_LIBRARY_PATH
+
+# For Win32
+PATH=@abs_top_builddir@/gruel/:@abs_top_builddir@/gruel/.libs:$PATH
+
+@top_builddir@/run_tests.sh \
+ @abs_top_srcdir@/gruel/src \
+ @abs_top_builddir@/gruel/src \
+ @srcdir@
diff --git a/gruel/src/scheme/gnuradio/Makefile.am b/gruel/src/scheme/gnuradio/Makefile.am
index 0ce01f6f8..e7b6bf744 100644
--- a/gruel/src/scheme/gnuradio/Makefile.am
+++ b/gruel/src/scheme/gnuradio/Makefile.am
@@ -1,5 +1,5 @@
#
-# Copyright 2007,2009 Free Software Foundation, Inc.
+# Copyright 2007,2009,2010,2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -18,12 +18,14 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
+include $(top_srcdir)/Makefile.common
+
#pkgdatadir = $(datadir)/gnuradio
-EXTRA_DIST = \
- gen-serial-tags.scm
+EXTRA_DIST += \
+ gen-serial-tags.py
-# really scheme source files
+# really scheme source files FIXME wrong location
dist_pkgdata_DATA = \
pmt-serial-tags.scm \
pmt-serialize.scm \
diff --git a/gruel/src/scheme/gnuradio/gen-serial-tags.py b/gruel/src/scheme/gnuradio/gen-serial-tags.py
new file mode 100644
index 000000000..18e927beb
--- /dev/null
+++ b/gruel/src/scheme/gnuradio/gen-serial-tags.py
@@ -0,0 +1,53 @@
+"""
+//
+// Copyright 2011 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio 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 3, or (at your option)
+// any later version.
+//
+// GNU Radio 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.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+//
+// THIS FILE IS MACHINE GENERATED FROM %s. DO NOT EDIT BY HAND.
+// See %s for additional commentary.
+//
+
+#ifndef INCLUDED_PMT_SERIAL_TAGS_H
+#define INCLUDED_PMT_SERIAL_TAGS_H
+
+enum pst_tags {
+%s
+};
+#endif /* INCLUDED_PMT_SERIAL_TAGS_H */
+"""
+
+import sys, os, re
+
+if __name__ == '__main__':
+ if len(sys.argv) != 3:
+ print "Usage %s <input_scm_file> <output_hdr_file>"%__file__
+ exit()
+ input_scm_file, output_hdr_file = sys.argv[1:]
+ enums = list()
+ for line in open(input_scm_file).readlines():
+ match = re.match('^\s*\(define\s+([\w|-]+)\s+#x([0-9a-fA-F]+)\)', line)
+ if not match: continue
+ name, value = match.groups()
+ name = name.upper().replace('-', '_')
+ enums.append(' %s = 0x%s'%(name, value))
+ open(output_hdr_file, 'w').write(__doc__%(
+ os.path.basename(__file__),
+ os.path.basename(input_scm_file),
+ ',\n'.join(enums),
+ ))
diff --git a/gruel/src/scheme/gnuradio/gen-serial-tags.scm b/gruel/src/scheme/gnuradio/gen-serial-tags.scm
deleted file mode 100755
index 7b9087228..000000000
--- a/gruel/src/scheme/gnuradio/gen-serial-tags.scm
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/usr/bin/guile \
--e main -s
-!#
-;;; -*-scheme-*-
-;;;
-;;; Copyright 2007 Free Software Foundation, Inc.
-;;;
-;;; This file is part of GNU Radio
-;;;
-;;; GNU Radio 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 3, or (at your option)
-;;; any later version.
-;;;
-;;; GNU Radio 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.,
-;;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-;;;
-
-(use-modules (ice-9 format))
-
-(defmacro when (pred . body)
- `(if ,pred (begin ,@body) #f))
-
-;; ----------------------------------------------------------------
-
-(define (main args)
-
- (define (usage)
- (format 0
- "usage: ~a <pmt-serial-tags.scm> <pmt_serial_tags.h>~%"
- (car args)))
-
- (when (not (= (length args) 3))
- (usage)
- (format 0 "args: ~s~%" args)
- (exit 1))
-
- (let ((i-file (open-input-file (cadr args)))
- (h-file (open-output-file (caddr args))))
-
- (write-header-comment h-file "// ")
- (display "#ifndef INCLUDED_PMT_SERIAL_TAGS_H\n" h-file)
- (display "#define INCLUDED_PMT_SERIAL_TAGS_H\n" h-file)
- (newline h-file)
- (display "enum pst_tags {\n" h-file)
-
- (for-each-in-file i-file
- (lambda (form)
- (let* ((name (cadr form))
- (c-name (string-upcase (c-ify name)))
- (value (caddr form)))
- ;;(format h-file "static const int ~a\t= 0x~x;~%" c-name value)
- (format h-file " ~a\t= 0x~x,~%" c-name value))))
-
- (display "};\n" h-file)
- (display "#endif\n" h-file)))
-
-(define (c-ify name)
- (list->string (map (lambda (c)
- (if (eqv? c #\-) #\_ c))
- (string->list (symbol->string name)))))
-
-
-(define (write-header-comment o-port prefix)
- (for-each (lambda (comment)
- (format o-port "~a~a~%" prefix comment))
- header-comment))
-
-(define header-comment
- '(
- ""
- "Copyright 2007 Free Software Foundation, Inc."
- ""
- "This file is part of GNU Radio"
- ""
- "GNU Radio 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 3, or (at your option)"
- "any later version."
- ""
- "GNU Radio 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.,"
- "51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA."
- ""
- ""
- "THIS FILE IS MACHINE GENERATED FROM pmt-serial-tags.scm. DO NOT EDIT BY HAND."
- "See pmt-serial-tags.scm for additional commentary."
- ""))
-
-
-
-(define (for-each-in-file file f)
- (let ((port (if (port? file)
- file
- (open-input-file file))))
- (letrec
- ((loop
- (lambda (port form)
- (cond ((eof-object? form)
- (when (not (eq? port file))
- (close-input-port port))
- #t)
- (else
- (f form)
- (set! form #f) ; for GC
- (loop port (read port)))))))
- (loop port (read port)))))
diff --git a/gruel/src/swig/.gitignore b/gruel/src/swig/.gitignore
new file mode 100644
index 000000000..b336cc7ce
--- /dev/null
+++ b/gruel/src/swig/.gitignore
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gruel/src/swig/Makefile.am b/gruel/src/swig/Makefile.am
new file mode 100644
index 000000000..294045567
--- /dev/null
+++ b/gruel/src/swig/Makefile.am
@@ -0,0 +1,55 @@
+#
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio 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 3, or (at your option)
+# any later version.
+#
+# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+include $(top_srcdir)/Makefile.common
+include $(top_srcdir)/Makefile.swig
+
+TESTS =
+
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/gruel/src/lib \
+ $(STD_DEFINES_AND_INCLUDES) \
+ $(PYTHON_CPPFLAGS) \
+ $(WITH_INCLUDES)
+
+TOP_SWIG_IFILES = \
+ pmt_swig.i
+
+##############################
+# SWIG interface and library
+TOP_SWIG_IFILES = \
+ pmt_swig.i
+
+# Install so that they end up available as:
+# import gruel.pmt
+# This ends up at:
+# ${prefix}/lib/python${python_version}/site-packages/gruel/pmt
+pmt_swig_pythondir_category = \
+ gruel/pmt
+
+# additional libraries for linking with the SWIG-generated library
+pmt_swig_la_swig_libadd = \
+ $(abs_top_builddir)/gruel/src/lib/pmt/libpmt.la
+
+# additional SWIG files to be installed
+pmt_swig_swiginclude_headers =
+
+
diff --git a/gruel/src/swig/Makefile.swig.gen b/gruel/src/swig/Makefile.swig.gen
new file mode 100644
index 000000000..c6a2fb956
--- /dev/null
+++ b/gruel/src/swig/Makefile.swig.gen
@@ -0,0 +1,115 @@
+# -*- Makefile -*-
+#
+# Copyright 2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio 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 3, or (at your option)
+# any later version.
+#
+# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+# Makefile.swig.gen for gnuradio_core_runtime.i
+
+## Default install locations for these files:
+##
+## Default location for the Python directory is:
+## ${prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_core_runtime
+## Default location for the Python exec directory is:
+## ${exec_prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_core_runtime
+##
+## The following can be overloaded to change the install location, but
+## this has to be done in the including Makefile.am -before-
+## Makefile.swig is included.
+
+pmt_swig_pythondir_category ?= gruel/pmt_swig
+pmt_swig_pylibdir_category ?= $(pmt_swig_pythondir_category)
+pmt_swig_pythondir = $(pythondir)/$(pmt_swig_pythondir_category)
+pmt_swig_pylibdir = $(pyexecdir)/$(pmt_swig_pylibdir_category)
+
+# The .so libraries for the guile modules get installed whereever guile
+# is installed, usually /usr/lib/guile/gnuradio/
+# FIXME: determince whether these should be installed with gnuradio.
+pmt_swig_scmlibdir = $(libdir)
+
+# The scm files for the guile modules get installed where ever guile
+# is installed, usually /usr/share/guile/site/gnuradio_core_runtime
+# FIXME: determince whether these should be installed with gnuradio.
+pmt_swig_scmdir = $(guiledir)
+
+## SWIG headers are always installed into the same directory.
+
+pmt_swig_swigincludedir = $(swigincludedir)
+
+## This is a template file for a "generated" Makefile addition (in
+## this case, "Makefile.swig.gen"). By including the top-level
+## Makefile.swig, this file will be used to generate the SWIG
+## dependencies. Assign the variable TOP_SWIG_FILES to be the list of
+## SWIG .i files to generated wrappings for; there can be more than 1
+## so long as the names are unique (no sorting is done on the
+## TOP_SWIG_FILES list). This file explicitly assumes that a SWIG .i
+## file will generate .cc, .py, and possibly .h files -- meaning that
+## all of these files will have the same base name (that provided for
+## the SWIG .i file).
+##
+## This code is setup to ensure parallel MAKE ("-j" or "-jN") does the
+## right thing. For more info, see <
+## http://sources.redhat.com/automake/automake.html#Multiple-Outputs >
+
+## Other cleaned files: dependency files generated by SWIG or this Makefile
+
+MOSTLYCLEANFILES += $(DEPDIR)/*.S*
+
+## Various SWIG variables. These can be overloaded in the including
+## Makefile.am by setting the variable value there, then including
+## Makefile.swig .
+
+pmt_swig_swiginclude_HEADERS = \
+ pmt_swig.i \
+ $(pmt_swig_swiginclude_headers)
+
+if PYTHON
+pmt_swig_pylib_LTLIBRARIES = \
+ _pmt_swig.la
+
+_pmt_swig_la_SOURCES = \
+ python/pmt_swig.cc \
+ $(pmt_swig_la_swig_sources)
+
+pmt_swig_python_PYTHON = \
+ pmt_swig.py \
+ $(pmt_swig_python)
+
+_pmt_swig_la_LIBADD = \
+ $(STD_SWIG_LA_LIB_ADD) \
+ $(pmt_swig_la_swig_libadd)
+
+_pmt_swig_la_LDFLAGS = \
+ $(STD_SWIG_LA_LD_FLAGS) \
+ $(pmt_swig_la_swig_ldflags)
+
+_pmt_swig_la_CXXFLAGS = \
+ $(STD_SWIG_CXX_FLAGS) \
+ -I$(top_builddir) \
+ $(pmt_swig_la_swig_cxxflags)
+
+python/pmt_swig.cc: pmt_swig.py
+pmt_swig.py: pmt_swig.i
+
+# Include the python dependencies for this file
+-include python/pmt_swig.d
+
+endif # end of if python
+
+
diff --git a/gruel/src/swig/__init__.py b/gruel/src/swig/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/gruel/src/swig/__init__.py
diff --git a/gruel/src/swig/pmt_swig.i b/gruel/src/swig/pmt_swig.i
new file mode 100644
index 000000000..6435e03cc
--- /dev/null
+++ b/gruel/src/swig/pmt_swig.i
@@ -0,0 +1,760 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%module pmt
+%include "std_string.i"
+%include "stdint.i"
+%{
+#include <boost/intrusive_ptr.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/any.hpp>
+#include <complex>
+#include <string>
+#include <stdint.h>
+#include <iosfwd>
+#include <stdexcept>
+#include <gruel/pmt.h>
+using namespace pmt;
+%}
+
+// Template intrusive_ptr for Swig to avoid dereferencing issues
+class pmt_base;
+%import <intrusive_ptr.i>
+%template(swig_int_ptr) boost::intrusive_ptr<pmt_base>;
+
+typedef boost::intrusive_ptr<pmt_base> pmt_t;
+
+/*
+ * ------------------------------------------------------------------------
+ * Booleans. Two constants, #t and #f.
+ *
+ * In predicates, anything that is not #f is considered true.
+ * I.e., there is a single false value, #f.
+ * ------------------------------------------------------------------------
+ */
+extern const pmt_t PMT_T;
+extern const pmt_t PMT_F;
+
+//! Return true if obj is \#t or \#f, else return false.
+bool pmt_is_bool(pmt_t obj);
+
+//! Return false if obj is \#f, else return true.
+bool pmt_is_true(pmt_t obj);
+
+//! Return true if obj is \#f, else return true.
+bool pmt_is_false(pmt_t obj);
+
+//! Return \#f is val is false, else return \#t.
+pmt_t pmt_from_bool(bool val);
+
+//! Return true if val is PMT_T, return false when val is PMT_F,
+// else raise wrong_type exception.
+bool pmt_to_bool(pmt_t val);
+
+/*
+ * ------------------------------------------------------------------------
+ * Symbols
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if obj is a symbol, else false.
+bool pmt_is_symbol(const pmt_t& obj);
+
+//! Return the symbol whose name is \p s.
+pmt_t pmt_string_to_symbol(const std::string &s);
+
+//! Alias for pmt_string_to_symbol
+pmt_t pmt_intern(const std::string &s);
+
+
+/*!
+ * If \p is a symbol, return the name of the symbol as a string.
+ * Otherwise, raise the wrong_type exception.
+ */
+const std::string pmt_symbol_to_string(const pmt_t& sym);
+
+/*
+ * ------------------------------------------------------------------------
+ * Numbers: we support integer, real and complex
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if obj is any kind of number, else false.
+bool pmt_is_number(pmt_t obj);
+
+/*
+ * ------------------------------------------------------------------------
+ * Integers
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if \p x is an integer number, else false
+bool pmt_is_integer(pmt_t x);
+
+//! Return the pmt value that represents the integer \p x.
+pmt_t pmt_from_long(long x);
+
+/*!
+ * \brief Convert pmt to long if possible.
+ *
+ * When \p x represents an exact integer that fits in a long,
+ * return that integer. Else raise an exception, either wrong_type
+ * when x is not an exact integer, or out_of_range when it doesn't fit.
+ */
+long pmt_to_long(pmt_t x);
+
+/*
+ * ------------------------------------------------------------------------
+ * uint64_t
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if \p x is an uint64 number, else false
+bool pmt_is_uint64(pmt_t x);
+
+//! Return the pmt value that represents the uint64 \p x.
+pmt_t pmt_from_uint64(uint64_t x);
+
+/*!
+ * \brief Convert pmt to uint64 if possible.
+ *
+ * When \p x represents an exact integer that fits in a uint64,
+ * return that uint64. Else raise an exception, either wrong_type
+ * when x is not an exact uint64, or out_of_range when it doesn't fit.
+ */
+uint64_t pmt_to_uint64(pmt_t x);
+
+/*
+ * ------------------------------------------------------------------------
+ * Reals
+ * ------------------------------------------------------------------------
+ */
+
+/*
+ * \brief Return true if \p obj is a real number, else false.
+ */
+bool pmt_is_real(pmt_t obj);
+
+//! Return the pmt value that represents double \p x.
+pmt_t pmt_from_double(double x);
+
+/*!
+ * \brief Convert pmt to double if possible.
+ *
+ * Returns the number closest to \p val that is representable
+ * as a double. The argument \p val must be a real or integer, otherwise
+ * a wrong_type exception is raised.
+ */
+double pmt_to_double(pmt_t x);
+
+/*
+ * ------------------------------------------------------------------------
+ * Complex
+ * ------------------------------------------------------------------------
+ */
+
+/*!
+ * \brief return true if \p obj is a complex number, false otherwise.
+ */
+bool pmt_is_complex(pmt_t obj);
+
+//! Return a complex number constructed of the given real and imaginary parts.
+pmt_t pmt_make_rectangular(double re, double im);
+
+/*!
+ * If \p z is complex, real or integer, return the closest complex<double>.
+ * Otherwise, raise the wrong_type exception.
+ */
+std::complex<double> pmt_to_complex(pmt_t z);
+
+/*
+ * ------------------------------------------------------------------------
+ * Pairs
+ * ------------------------------------------------------------------------
+ */
+
+extern const pmt_t PMT_NIL; //< the empty list
+
+//! Return true if \p x is the empty list, otherwise return false.
+bool pmt_is_null(const pmt_t& x);
+
+//! Return true if \p obj is a pair, else false.
+bool pmt_is_pair(const pmt_t& obj);
+
+//! Return a newly allocated pair whose car is \p x and whose cdr is \p y.
+pmt_t pmt_cons(const pmt_t& x, const pmt_t& y);
+
+//! If \p pair is a pair, return the car of the \p pair, otherwise raise wrong_type.
+pmt_t pmt_car(const pmt_t& pair);
+
+//! If \p pair is a pair, return the cdr of the \p pair, otherwise raise wrong_type.
+pmt_t pmt_cdr(const pmt_t& pair);
+
+//! Stores \p value in the car field of \p pair.
+void pmt_set_car(pmt_t pair, pmt_t value);
+
+//! Stores \p value in the cdr field of \p pair.
+void pmt_set_cdr(pmt_t pair, pmt_t value);
+
+pmt_t pmt_caar(pmt_t pair);
+pmt_t pmt_cadr(pmt_t pair);
+pmt_t pmt_cdar(pmt_t pair);
+pmt_t pmt_cddr(pmt_t pair);
+pmt_t pmt_caddr(pmt_t pair);
+pmt_t pmt_cadddr(pmt_t pair);
+
+/*
+ * ------------------------------------------------------------------------
+ * Tuples
+ *
+ * Store a fixed number of objects. Tuples are not modifiable, and thus
+ * are excellent for use as messages. Indexing is zero based.
+ * Access time to an element is O(1).
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if \p x is a tuple, othewise false.
+bool pmt_is_tuple(pmt_t x);
+
+pmt_t pmt_make_tuple();
+pmt_t pmt_make_tuple(const pmt_t &e0);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, const pmt_t &e8);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, const pmt_t &e8, const pmt_t &e9);
+
+/*!
+ * If \p x is a vector or proper list, return a tuple containing the elements of x
+ */
+pmt_t pmt_to_tuple(const pmt_t &x);
+
+/*!
+ * Return the contents of position \p k of \p tuple.
+ * \p k must be a valid index of \p tuple.
+ */
+pmt_t pmt_tuple_ref(const pmt_t &tuple, size_t k);
+
+/*
+ * ------------------------------------------------------------------------
+ * Vectors
+ *
+ * These vectors can hold any kind of objects. Indexing is zero based.
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if \p x is a vector, othewise false.
+bool pmt_is_vector(pmt_t x);
+
+//! Make a vector of length \p k, with initial values set to \p fill
+pmt_t pmt_make_vector(size_t k, pmt_t fill);
+
+/*!
+ * Return the contents of position \p k of \p vector.
+ * \p k must be a valid index of \p vector.
+ */
+pmt_t pmt_vector_ref(pmt_t vector, size_t k);
+
+//! Store \p obj in position \p k.
+void pmt_vector_set(pmt_t vector, size_t k, pmt_t obj);
+
+//! Store \p fill in every position of \p vector
+void pmt_vector_fill(pmt_t vector, pmt_t fill);
+
+/*
+ * ------------------------------------------------------------------------
+ * Binary Large Objects (BLOBs)
+ *
+ * Handy for passing around uninterpreted chunks of memory.
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if \p x is a blob, othewise false.
+bool pmt_is_blob(pmt_t x);
+
+/*!
+ * \brief Make a blob given a pointer and length in bytes
+ *
+ * \param buf is the pointer to data to use to create blob
+ * \param len is the size of the data in bytes.
+ *
+ * The data is copied into the blob.
+ */
+pmt_t pmt_make_blob(const void *buf, size_t len);
+
+//! Return a pointer to the blob's data
+const void *pmt_blob_data(pmt_t blob);
+
+//! Return the blob's length in bytes
+size_t pmt_blob_length(pmt_t blob);
+
+/*!
+ * <pre>
+ * ------------------------------------------------------------------------
+ * Uniform Numeric Vectors
+ *
+ * A uniform numeric vector is a vector whose elements are all of single
+ * numeric type. pmt offers uniform numeric vectors for signed and
+ * unsigned 8-bit, 16-bit, 32-bit, and 64-bit integers, two sizes of
+ * floating point values, and complex floating-point numbers of these
+ * two sizes. Indexing is zero based.
+ *
+ * The names of the functions include these tags in their names:
+ *
+ * u8 unsigned 8-bit integers
+ * s8 signed 8-bit integers
+ * u16 unsigned 16-bit integers
+ * s16 signed 16-bit integers
+ * u32 unsigned 32-bit integers
+ * s32 signed 32-bit integers
+ * u64 unsigned 64-bit integers
+ * s64 signed 64-bit integers
+ * f32 the C++ type float
+ * f64 the C++ type double
+ * c32 the C++ type complex<float>
+ * c64 the C++ type complex<double>
+ * ------------------------------------------------------------------------
+ * </pre>
+ */
+
+//! true if \p x is any kind of uniform numeric vector
+bool pmt_is_uniform_vector(pmt_t x);
+
+bool pmt_is_u8vector(pmt_t x);
+bool pmt_is_s8vector(pmt_t x);
+bool pmt_is_u16vector(pmt_t x);
+bool pmt_is_s16vector(pmt_t x);
+bool pmt_is_u32vector(pmt_t x);
+bool pmt_is_s32vector(pmt_t x);
+bool pmt_is_u64vector(pmt_t x);
+bool pmt_is_s64vector(pmt_t x);
+bool pmt_is_f32vector(pmt_t x);
+bool pmt_is_f64vector(pmt_t x);
+bool pmt_is_c32vector(pmt_t x);
+bool pmt_is_c64vector(pmt_t x);
+
+pmt_t pmt_make_u8vector(size_t k, uint8_t fill);
+pmt_t pmt_make_s8vector(size_t k, int8_t fill);
+pmt_t pmt_make_u16vector(size_t k, uint16_t fill);
+pmt_t pmt_make_s16vector(size_t k, int16_t fill);
+pmt_t pmt_make_u32vector(size_t k, uint32_t fill);
+pmt_t pmt_make_s32vector(size_t k, int32_t fill);
+pmt_t pmt_make_u64vector(size_t k, uint64_t fill);
+pmt_t pmt_make_s64vector(size_t k, int64_t fill);
+pmt_t pmt_make_f32vector(size_t k, float fill);
+pmt_t pmt_make_f64vector(size_t k, double fill);
+pmt_t pmt_make_c32vector(size_t k, std::complex<float> fill);
+pmt_t pmt_make_c64vector(size_t k, std::complex<double> fill);
+
+pmt_t pmt_init_u8vector(size_t k, const uint8_t *data);
+pmt_t pmt_init_s8vector(size_t k, const int8_t *data);
+pmt_t pmt_init_u16vector(size_t k, const uint16_t *data);
+pmt_t pmt_init_s16vector(size_t k, const int16_t *data);
+pmt_t pmt_init_u32vector(size_t k, const uint32_t *data);
+pmt_t pmt_init_s32vector(size_t k, const int32_t *data);
+pmt_t pmt_init_f32vector(size_t k, const float *data);
+pmt_t pmt_init_f64vector(size_t k, const double *data);
+pmt_t pmt_init_c32vector(size_t k, const std::complex<float> *data);
+pmt_t pmt_init_c64vector(size_t k, const std::complex<double> *data);
+
+uint8_t pmt_u8vector_ref(pmt_t v, size_t k);
+int8_t pmt_s8vector_ref(pmt_t v, size_t k);
+uint16_t pmt_u16vector_ref(pmt_t v, size_t k);
+int16_t pmt_s16vector_ref(pmt_t v, size_t k);
+uint32_t pmt_u32vector_ref(pmt_t v, size_t k);
+int32_t pmt_s32vector_ref(pmt_t v, size_t k);
+uint64_t pmt_u64vector_ref(pmt_t v, size_t k);
+int64_t pmt_s64vector_ref(pmt_t v, size_t k);
+float pmt_f32vector_ref(pmt_t v, size_t k);
+double pmt_f64vector_ref(pmt_t v, size_t k);
+std::complex<float> pmt_c32vector_ref(pmt_t v, size_t k);
+std::complex<double> pmt_c64vector_ref(pmt_t v, size_t k);
+
+void pmt_u8vector_set(pmt_t v, size_t k, uint8_t x); //< v[k] = x
+void pmt_s8vector_set(pmt_t v, size_t k, int8_t x);
+void pmt_u16vector_set(pmt_t v, size_t k, uint16_t x);
+void pmt_s16vector_set(pmt_t v, size_t k, int16_t x);
+void pmt_u32vector_set(pmt_t v, size_t k, uint32_t x);
+void pmt_s32vector_set(pmt_t v, size_t k, int32_t x);
+void pmt_u64vector_set(pmt_t v, size_t k, uint64_t x);
+void pmt_s64vector_set(pmt_t v, size_t k, int64_t x);
+void pmt_f32vector_set(pmt_t v, size_t k, float x);
+void pmt_f64vector_set(pmt_t v, size_t k, double x);
+void pmt_c32vector_set(pmt_t v, size_t k, std::complex<float> x);
+void pmt_c64vector_set(pmt_t v, size_t k, std::complex<double> x);
+
+// Return const pointers to the elements
+
+const void *pmt_uniform_vector_elements(pmt_t v, size_t &len); //< works with any; len is in bytes
+
+const uint8_t *pmt_u8vector_elements(pmt_t v, size_t &len); //< len is in elements
+const int8_t *pmt_s8vector_elements(pmt_t v, size_t &len); //< len is in elements
+const uint16_t *pmt_u16vector_elements(pmt_t v, size_t &len); //< len is in elements
+const int16_t *pmt_s16vector_elements(pmt_t v, size_t &len); //< len is in elements
+const uint32_t *pmt_u32vector_elements(pmt_t v, size_t &len); //< len is in elements
+const int32_t *pmt_s32vector_elements(pmt_t v, size_t &len); //< len is in elements
+const uint64_t *pmt_u64vector_elements(pmt_t v, size_t &len); //< len is in elements
+const int64_t *pmt_s64vector_elements(pmt_t v, size_t &len); //< len is in elements
+const float *pmt_f32vector_elements(pmt_t v, size_t &len); //< len is in elements
+const double *pmt_f64vector_elements(pmt_t v, size_t &len); //< len is in elements
+const std::complex<float> *pmt_c32vector_elements(pmt_t v, size_t &len); //< len is in elements
+const std::complex<double> *pmt_c64vector_elements(pmt_t v, size_t &len); //< len is in elements
+
+// Return non-const pointers to the elements
+
+void *pmt_uniform_vector_writable_elements(pmt_t v, size_t &len); //< works with any; len is in bytes
+
+uint8_t *pmt_u8vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+int8_t *pmt_s8vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+uint16_t *pmt_u16vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+int16_t *pmt_s16vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+uint32_t *pmt_u32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+int32_t *pmt_s32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+uint64_t *pmt_u64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+int64_t *pmt_s64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+float *pmt_f32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+double *pmt_f64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+std::complex<float> *pmt_c32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+std::complex<double> *pmt_c64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements
+
+/*
+ * ------------------------------------------------------------------------
+ * Dictionary (a.k.a associative array, hash, map)
+ *
+ * This is a functional data structure that is persistent. Updating a
+ * functional data structure does not destroy the existing version, but
+ * rather creates a new version that coexists with the old.
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if \p obj is a dictionary
+bool pmt_is_dict(const pmt_t &obj);
+
+//! Make an empty dictionary
+pmt_t pmt_make_dict();
+
+//! Return a new dictionary with \p key associated with \p value.
+pmt_t pmt_dict_add(const pmt_t &dict, const pmt_t &key, const pmt_t &value);
+
+//! Return a new dictionary with \p key removed.
+pmt_t pmt_dict_delete(const pmt_t &dict, const pmt_t &key);
+
+//! Return true if \p key exists in \p dict
+bool pmt_dict_has_key(const pmt_t &dict, const pmt_t &key);
+
+//! If \p key exists in \p dict, return associated value; otherwise return \p not_found.
+pmt_t pmt_dict_ref(const pmt_t &dict, const pmt_t &key, const pmt_t &not_found);
+
+//! Return list of (key . value) pairs
+pmt_t pmt_dict_items(pmt_t dict);
+
+//! Return list of keys
+pmt_t pmt_dict_keys(pmt_t dict);
+
+//! Return list of values
+pmt_t pmt_dict_values(pmt_t dict);
+
+/*
+ * ------------------------------------------------------------------------
+ * Any (wraps boost::any -- can be used to wrap pretty much anything)
+ *
+ * Cannot be serialized or used across process boundaries.
+ * See http://www.boost.org/doc/html/any.html
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if \p obj is an any
+bool pmt_is_any(pmt_t obj);
+
+//! make an any
+pmt_t pmt_make_any(const boost::any &any);
+
+//! Return underlying boost::any
+boost::any pmt_any_ref(pmt_t obj);
+
+//! Store \p any in \p obj
+void pmt_any_set(pmt_t obj, const boost::any &any);
+
+
+/*
+ * ------------------------------------------------------------------------
+ * msg_accepter -- pmt representation of gruel::msg_accepter
+ * ------------------------------------------------------------------------
+ */
+//! Return true if \p obj is a msg_accepter
+bool pmt_is_msg_accepter(const pmt_t &obj);
+
+//! make a msg_accepter
+pmt_t pmt_make_msg_accepter(boost::shared_ptr<gruel::msg_accepter> ma);
+
+//! Return underlying msg_accepter
+boost::shared_ptr<gruel::msg_accepter> pmt_msg_accepter_ref(const pmt_t &obj);
+
+/*
+ * ------------------------------------------------------------------------
+ * General functions
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if x and y are the same object; otherwise return false.
+bool pmt_eq(const pmt_t& x, const pmt_t& y);
+
+/*!
+ * \brief Return true if x and y should normally be regarded as the same object, else false.
+ *
+ * <pre>
+ * eqv returns true if:
+ * x and y are the same object.
+ * x and y are both \#t or both \#f.
+ * x and y are both symbols and their names are the same.
+ * x and y are both numbers, and are numerically equal.
+ * x and y are both the empty list (nil).
+ * x and y are pairs or vectors that denote same location in store.
+ * </pre>
+ */
+bool pmt_eqv(const pmt_t& x, const pmt_t& y);
+
+/*!
+ * pmt_equal recursively compares the contents of pairs and vectors,
+ * applying pmt_eqv on other objects such as numbers and symbols.
+ * pmt_equal may fail to terminate if its arguments are circular data
+ * structures.
+ */
+bool pmt_equal(const pmt_t& x, const pmt_t& y);
+
+
+//! Return the number of elements in v
+size_t pmt_length(const pmt_t& v);
+
+/*!
+ * \brief Find the first pair in \p alist whose car field is \p obj
+ * and return that pair.
+ *
+ * \p alist (for "association list") must be a list of pairs. If no pair
+ * in \p alist has \p obj as its car then \#f is returned.
+ * Uses pmt_eq to compare \p obj with car fields of the pairs in \p alist.
+ */
+pmt_t pmt_assq(pmt_t obj, pmt_t alist);
+
+/*!
+ * \brief Find the first pair in \p alist whose car field is \p obj
+ * and return that pair.
+ *
+ * \p alist (for "association list") must be a list of pairs. If no pair
+ * in \p alist has \p obj as its car then \#f is returned.
+ * Uses pmt_eqv to compare \p obj with car fields of the pairs in \p alist.
+ */
+pmt_t pmt_assv(pmt_t obj, pmt_t alist);
+
+/*!
+ * \brief Find the first pair in \p alist whose car field is \p obj
+ * and return that pair.
+ *
+ * \p alist (for "association list") must be a list of pairs. If no pair
+ * in \p alist has \p obj as its car then \#f is returned.
+ * Uses pmt_equal to compare \p obj with car fields of the pairs in \p alist.
+ */
+pmt_t pmt_assoc(pmt_t obj, pmt_t alist);
+
+/*!
+ * \brief Apply \p proc element-wise to the elements of list and returns
+ * a list of the results, in order.
+ *
+ * \p list must be a list. The dynamic order in which \p proc is
+ * applied to the elements of \p list is unspecified.
+ */
+pmt_t pmt_map(pmt_t proc(const pmt_t&), pmt_t list);
+
+/*!
+ * \brief reverse \p list.
+ *
+ * \p list must be a proper list.
+ */
+pmt_t pmt_reverse(pmt_t list);
+
+/*!
+ * \brief destructively reverse \p list.
+ *
+ * \p list must be a proper list.
+ */
+pmt_t pmt_reverse_x(pmt_t list);
+
+/*!
+ * \brief (acons x y a) == (cons (cons x y) a)
+ */
+inline static pmt_t
+pmt_acons(pmt_t x, pmt_t y, pmt_t a)
+{
+ return pmt_cons(pmt_cons(x, y), a);
+}
+
+/*!
+ * \brief locates \p nth element of \n list where the car is the 'zeroth' element.
+ */
+pmt_t pmt_nth(size_t n, pmt_t list);
+
+/*!
+ * \brief returns the tail of \p list that would be obtained by calling
+ * cdr \p n times in succession.
+ */
+pmt_t pmt_nthcdr(size_t n, pmt_t list);
+
+/*!
+ * \brief Return the first sublist of \p list whose car is \p obj.
+ * If \p obj does not occur in \p list, then \#f is returned.
+ * pmt_memq use pmt_eq to compare \p obj with the elements of \p list.
+ */
+pmt_t pmt_memq(pmt_t obj, pmt_t list);
+
+/*!
+ * \brief Return the first sublist of \p list whose car is \p obj.
+ * If \p obj does not occur in \p list, then \#f is returned.
+ * pmt_memv use pmt_eqv to compare \p obj with the elements of \p list.
+ */
+pmt_t pmt_memv(pmt_t obj, pmt_t list);
+
+/*!
+ * \brief Return the first sublist of \p list whose car is \p obj.
+ * If \p obj does not occur in \p list, then \#f is returned.
+ * pmt_member use pmt_equal to compare \p obj with the elements of \p list.
+ */
+pmt_t pmt_member(pmt_t obj, pmt_t list);
+
+/*!
+ * \brief Return true if every element of \p list1 appears in \p list2, and false otherwise.
+ * Comparisons are done with pmt_eqv.
+ */
+bool pmt_subsetp(pmt_t list1, pmt_t list2);
+
+/*!
+ * \brief Return a list of length 1 containing \p x1
+ */
+pmt_t pmt_list1(const pmt_t& x1);
+
+/*!
+ * \brief Return a list of length 2 containing \p x1, \p x2
+ */
+pmt_t pmt_list2(const pmt_t& x1, const pmt_t& x2);
+
+/*!
+ * \brief Return a list of length 3 containing \p x1, \p x2, \p x3
+ */
+pmt_t pmt_list3(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3);
+
+/*!
+ * \brief Return a list of length 4 containing \p x1, \p x2, \p x3, \p x4
+ */
+pmt_t pmt_list4(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3, const pmt_t& x4);
+
+/*!
+ * \brief Return a list of length 5 containing \p x1, \p x2, \p x3, \p x4, \p x5
+ */
+pmt_t pmt_list5(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3, const pmt_t& x4, const pmt_t& x5);
+
+/*!
+ * \brief Return a list of length 6 containing \p x1, \p x2, \p x3, \p x4, \p
+ * x5, \p x6
+ */
+pmt_t pmt_list6(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3, const pmt_t& x4, const pmt_t& x5, const pmt_t& x6);
+
+/*!
+ * \brief Return \p list with \p item added to it.
+ */
+pmt_t pmt_list_add(pmt_t list, const pmt_t& item);
+
+
+/*
+ * ------------------------------------------------------------------------
+ * read / write
+ * ------------------------------------------------------------------------
+ */
+extern const pmt_t PMT_EOF; //< The end of file object
+
+//! return true if obj is the EOF object, otherwise return false.
+bool pmt_is_eof_object(pmt_t obj);
+
+/*!
+ * read converts external representations of pmt objects into the
+ * objects themselves. Read returns the next object parsable from
+ * the given input port, updating port to point to the first
+ * character past the end of the external representation of the
+ * object.
+ *
+ * If an end of file is encountered in the input before any
+ * characters are found that can begin an object, then an end of file
+ * object is returned. The port remains open, and further attempts
+ * to read will also return an end of file object. If an end of file
+ * is encountered after the beginning of an object's external
+ * representation, but the external representation is incomplete and
+ * therefore not parsable, an error is signaled.
+ */
+pmt_t pmt_read(std::istream &port);
+
+/*!
+ * Write a written representation of \p obj to the given \p port.
+ */
+void pmt_write(pmt_t obj, std::ostream &port);
+
+/*!
+ * Return a string representation of \p obj.
+ * This is the same output as would be generated by pmt_write.
+ */
+std::string pmt_write_string(pmt_t obj);
+
+
+/*!
+ * \brief Write pmt string representation to stdout.
+ */
+void pmt_print(pmt_t v);
+
+
+/*
+ * ------------------------------------------------------------------------
+ * portable byte stream representation
+ * ------------------------------------------------------------------------
+ */
+/*!
+ * \brief Write portable byte-serial representation of \p obj to \p sink
+ */
+bool pmt_serialize(pmt_t obj, std::streambuf &sink);
+
+/*!
+ * \brief Create obj from portable byte-serial representation
+ */
+pmt_t pmt_deserialize(std::streambuf &source);
+
+
+void pmt_dump_sizeof(); // debugging
+
+/*!
+ * \brief Provide a simple string generating interface to pmt's serialize function
+ */
+std::string pmt_serialize_str(pmt_t obj);
+
+/*!
+ * \brief Provide a simple string generating interface to pmt's deserialize function
+ */
+pmt_t pmt_deserialize_str(std::string str);