diff options
-rw-r--r-- | pmt/ChangeLog | 6 | ||||
-rw-r--r-- | pmt/src/lib/Makefile.am | 33 | ||||
-rwxr-xr-x | pmt/src/lib/generate_unv.py | 138 | ||||
-rw-r--r-- | pmt/src/lib/pmt.cc | 33 | ||||
-rw-r--r-- | pmt/src/lib/pmt.h | 24 | ||||
-rw-r--r-- | pmt/src/lib/pmt_int.h | 25 | ||||
-rw-r--r-- | pmt/src/lib/unv_template.cc.t | 118 | ||||
-rw-r--r-- | pmt/src/lib/unv_template.h.t | 23 |
8 files changed, 387 insertions, 13 deletions
diff --git a/pmt/ChangeLog b/pmt/ChangeLog index 385dbc6d6..9f401c8d4 100644 --- a/pmt/ChangeLog +++ b/pmt/ChangeLog @@ -1,3 +1,9 @@ +2006-07-31 Eric Blossom <eb@comsec.com> + + * src/lib/generate_unv.py, src/lib/unv_template.cc.t, + src/lib/unv_template.h.t: machine generate code to support uniform + numeric vectors. + # # Copyright 2006 Free Software Foundation, Inc. # diff --git a/pmt/src/lib/Makefile.am b/pmt/src/lib/Makefile.am index 2f3eab730..1c084dead 100644 --- a/pmt/src/lib/Makefile.am +++ b/pmt/src/lib/Makefile.am @@ -25,9 +25,36 @@ TESTS = test_pmt lib_LTLIBRARIES = libpmt.la libpmt-qa.la +# ---------------------------------------------------------------- +# these scripts generate code + +CODE_GENERATOR = \ + generate_unv.py \ + unv_template.h.t \ + unv_template.cc.t + +GENERATED_H = \ + pmt_unv_int.h + +GENERATED_CC = \ + pmt_unv.cc + + +$(GENERATED_H) $(GENERATED_I) $(GENERATED_CC): $(CODE_GENERATOR) + PYTHONPATH=$(top_srcdir)/src/lib srcdir=$(srcdir) $(srcdir)/generate_unv.py + +BUILT_SOURCES = $(GENERATED_H) $(GENERATED_CC) + +# ---------------------------------------------------------------- + +EXTRA_DIST = \ + $(CODE_GENERATOR) + + # These are the source files that go into the pmt shared library libpmt_la_SOURCES = \ - pmt.cc + pmt.cc \ + $(GENERATED_CC) # magic flags libpmt_la_LDFLAGS = $(NO_UNDEFINED) -avoid-version @@ -40,6 +67,7 @@ include_HEADERS = \ pmt.h noinst_HEADERS = \ + $(GENERATED_H) \ pmt_int.h \ qa_pmt.h \ qa_pmt_prims.h @@ -69,3 +97,6 @@ LIBPMTQA = libpmt-qa.la $(LIBPMT) test_pmt_SOURCES = test_pmt.cc test_pmt_LDADD = $(LIBPMTQA) + + +CLEANFILES = $(BUILT_SOURCES) *.pyc diff --git a/pmt/src/lib/generate_unv.py b/pmt/src/lib/generate_unv.py new file mode 100755 index 000000000..46a168a1d --- /dev/null +++ b/pmt/src/lib/generate_unv.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python +# +# Copyright 2006 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 2, 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., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# + +""" +Generate code for uniform numeric vectors +""" + +import re, os, os.path + + +unv_types = ( + ('u8', 'uint8_t'), + ('s8', 'int8_t'), + ('u16', 'uint16_t'), + ('s16', 'int16_t'), + ('u32', 'uint32_t'), + ('s32', 'int32_t'), + ('u64', 'uint64_t'), + ('s64', 'int64_t'), + ('f32', 'float'), + ('f64', 'double'), + ('c32', 'std::complex<float>'), + ('c64', 'std::complex<double>') + ) + +header = """\ +/* -*- c++ -*- */ +/* + * Copyright 2006 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 2, 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +""" + +guard_head = """ +#ifndef INCLUDED_PMT_UNV_INT_H +#define INCLUDED_PMT_UNV_INT_H +""" + +guard_tail = """ +#endif +""" + +includes = """ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <vector> +#include <pmt.h> +#include "pmt_int.h" + +""" + + +# set srcdir to the directory that contains Makefile.am +try: + srcdir = os.environ['srcdir'] +except KeyError, e: + srcdir = "." +srcdir = srcdir + '/' + + +def open_src (name, mode): + global srcdir + return open(os.path.join (srcdir, name), mode) + + +def do_substitution (d, input, out_file): + def repl (match_obj): + key = match_obj.group (1) + # print key + return d[key] + + out = re.sub (r"@([a-zA-Z0-9_]+)@", repl, input) + out_file.write (out) + + +def generate_h(): + template = open_src('unv_template.h.t', 'r').read() + output = open('pmt_unv_int.h', 'w') + output.write(header) + output.write(guard_head) + for tag, typ in unv_types: + d = { 'TAG' : tag, 'TYPE' : typ } + do_substitution(d, template, output) + output.write(guard_tail) + + +def generate_cc(): + template = open_src('unv_template.cc.t', 'r').read() + output = open('pmt_unv.cc', 'w') + output.write(header) + output.write(includes) + for tag, typ in unv_types: + d = { 'TAG' : tag, 'TYPE' : typ } + do_substitution(d, template, output) + + +def main(): + generate_h() + generate_cc() + +if __name__ == '__main__': + main() diff --git a/pmt/src/lib/pmt.cc b/pmt/src/lib/pmt.cc index a1569e414..093f6fb22 100644 --- a/pmt/src/lib/pmt.cc +++ b/pmt/src/lib/pmt.cc @@ -91,6 +91,12 @@ _vector(pmt_t x) return dynamic_cast<pmt_vector*>(x.get()); } +static pmt_uniform_vector * +_uniform_vector(pmt_t x) +{ + return dynamic_cast<pmt_uniform_vector*>(x.get()); +} + static pmt_dict * _dict(pmt_t x) { @@ -432,6 +438,32 @@ pmt_vector_fill(pmt_t vector, pmt_t obj) } //////////////////////////////////////////////////////////////////////////// +// Uniform Numeric Vectors +//////////////////////////////////////////////////////////////////////////// + +bool +pmt_is_uniform_vector(pmt_t x) +{ + return x->is_uniform_vector(); +} + +const void * +pmt_uniform_vector_elements(pmt_t vector, size_t &len) +{ + if (!vector->is_uniform_vector()) + throw pmt_wrong_type("pmt_uniform_vector_elements", vector); + return _uniform_vector(vector)->uniform_elements(len); +} + +void * +pmt_uniform_vector_writeable_elements(pmt_t vector, size_t &len) +{ + if (!vector->is_uniform_vector()) + throw pmt_wrong_type("pmt_uniform_vector_writeable_elements", vector); + return _uniform_vector(vector)->uniform_writeable_elements(len); +} + +//////////////////////////////////////////////////////////////////////////// // Dictionaries //////////////////////////////////////////////////////////////////////////// @@ -703,3 +735,4 @@ pmt_reverse_x(pmt_t list) // FIXME do it destructively return pmt_reverse(list); } + diff --git a/pmt/src/lib/pmt.h b/pmt/src/lib/pmt.h index b27b7ce1c..4fd6c2907 100644 --- a/pmt/src/lib/pmt.h +++ b/pmt/src/lib/pmt.h @@ -303,18 +303,18 @@ 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, uint8_t *data); -pmt_t pmt_init_s8vector(size_t k, int8_t *data); -pmt_t pmt_init_u16vector(size_t k, uint16_t *data); -pmt_t pmt_init_s16vector(size_t k, int16_t *data); -pmt_t pmt_init_u32vector(size_t k, uint32_t *data); -pmt_t pmt_init_s32vector(size_t k, int32_t *data); -pmt_t pmt_init_u64vector(size_t k, uint64_t *data); -pmt_t pmt_init_s64vector(size_t k, int64_t *data); -pmt_t pmt_init_f32vector(size_t k, float *data); -pmt_t pmt_init_f64vector(size_t k, double *data); -pmt_t pmt_init_c32vector(size_t k, std::complex<float> *data); -pmt_t pmt_init_c64vector(size_t k, std::complex<double> *data); +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_u64vector(size_t k, const uint64_t *data); +pmt_t pmt_init_s64vector(size_t k, const int64_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); diff --git a/pmt/src/lib/pmt_int.h b/pmt/src/lib/pmt_int.h index 733546412..e6ee5ec9f 100644 --- a/pmt/src/lib/pmt_int.h +++ b/pmt/src/lib/pmt_int.h @@ -51,6 +51,21 @@ public: virtual bool is_pair() const { return false; } virtual bool is_vector() const { return false; } virtual bool is_dict() const { return false; } + + virtual bool is_uniform_vector() const { return false; } + virtual bool is_u8vector() const { return false; } + virtual bool is_s8vector() const { return false; } + virtual bool is_u16vector() const { return false; } + virtual bool is_s16vector() const { return false; } + virtual bool is_u32vector() const { return false; } + virtual bool is_s32vector() const { return false; } + virtual bool is_u64vector() const { return false; } + virtual bool is_s64vector() const { return false; } + virtual bool is_f32vector() const { return false; } + virtual bool is_f64vector() const { return false; } + virtual bool is_c32vector() const { return false; } + virtual bool is_c64vector() const { return false; } + }; class pmt_bool : public pmt_base @@ -175,4 +190,14 @@ public: pmt_t values() const; }; +class pmt_uniform_vector : public pmt_base +{ +public: + bool is_uniform_vector() const { return true; } + virtual const void *uniform_elements(size_t &len) = 0; + virtual void *uniform_writeable_elements(size_t &len) = 0; +}; + +#include "pmt_unv_int.h" + #endif /* INCLUDED_PMT_INT_H */ diff --git a/pmt/src/lib/unv_template.cc.t b/pmt/src/lib/unv_template.cc.t new file mode 100644 index 000000000..904829da7 --- /dev/null +++ b/pmt/src/lib/unv_template.cc.t @@ -0,0 +1,118 @@ +//////////////////////////////////////////////////////////////////////////// +// pmt_@TAG@vector +//////////////////////////////////////////////////////////////////////////// + +static pmt_@TAG@vector * +_@TAG@vector(pmt_t x) +{ + return dynamic_cast<pmt_@TAG@vector*>(x.get()); +} + + +pmt_@TAG@vector::pmt_@TAG@vector(size_t k, @TYPE@ fill) + : d_v(k) +{ + for (size_t i = 0; i < k; i++) + d_v[i] = fill; +} + +pmt_@TAG@vector::pmt_@TAG@vector(size_t k, const @TYPE@ *data) + : d_v(k) +{ + for (size_t i = 0; i < k; i++) + d_v[i] = data[i]; +} + +@TYPE@ +pmt_@TAG@vector::ref(size_t k) const +{ + if (k >= length()) + throw pmt_out_of_range("pmt_@TAG@vector_ref", pmt_from_long(k)); + return d_v[k]; +} + +void +pmt_@TAG@vector::set(size_t k, @TYPE@ x) +{ + if (k >= length()) + throw pmt_out_of_range("pmt_@TAG@vector_set", pmt_from_long(k)); + d_v[k] = x; +} + +const @TYPE@ * +pmt_@TAG@vector::elements(size_t &len) +{ + len = length(); + return &d_v[0]; +} + +@TYPE@ * +pmt_@TAG@vector::writeable_elements(size_t &len) +{ + len = length(); + return &d_v[0]; +} + +const void* +pmt_@TAG@vector::uniform_elements(size_t &len) +{ + len = length() * sizeof(@TYPE@); + return &d_v[0]; +} + +void* +pmt_@TAG@vector::uniform_writeable_elements(size_t &len) +{ + len = length() * sizeof(@TYPE@); + return &d_v[0]; +} + +bool +pmt_is_@TAG@vector(pmt_t obj) +{ + return obj->is_@TAG@vector(); +} + +pmt_t +pmt_make_@TAG@vector(size_t k, @TYPE@ fill) +{ + return pmt_t(new pmt_@TAG@vector(k, fill)); +} + +pmt_t +pmt_init_@TAG@vector(size_t k, const @TYPE@ *data) +{ + return pmt_t(new pmt_@TAG@vector(k, data)); +} + +@TYPE@ +pmt_@TAG@vector_ref(pmt_t vector, size_t k) +{ + if (!vector->is_@TAG@vector()) + throw pmt_wrong_type("pmt_@TAG@vector_ref", vector); + return _@TAG@vector(vector)->ref(k); +} + +void +pmt_@TAG@vector_set(pmt_t vector, size_t k, @TYPE@ obj) +{ + if (!vector->is_@TAG@vector()) + throw pmt_wrong_type("pmt_@TAG@vector_set", vector); + _@TAG@vector(vector)->set(k, obj); +} + +const @TYPE@ * +pmt_@TAG@vector_elements(pmt_t vector, size_t &len) +{ + if (!vector->is_@TAG@vector()) + throw pmt_wrong_type("pmt_@TAG@vector_elements", vector); + return _@TAG@vector(vector)->elements(len); +} + +@TYPE@ * +pmt_@TAG@vector_writeable_elements(pmt_t vector, size_t &len) +{ + if (!vector->is_@TAG@vector()) + throw pmt_wrong_type("pmt_@TAG@vector_writeable_elements", vector); + return _@TAG@vector(vector)->writeable_elements(len); +} diff --git a/pmt/src/lib/unv_template.h.t b/pmt/src/lib/unv_template.h.t new file mode 100644 index 000000000..6a084ec50 --- /dev/null +++ b/pmt/src/lib/unv_template.h.t @@ -0,0 +1,23 @@ + +//////////////////////////////////////////////////////////////////////////// +// pmt_@TAG@vector +//////////////////////////////////////////////////////////////////////////// + +class pmt_@TAG@vector : public pmt_uniform_vector +{ + std::vector< @TYPE@ > d_v; + +public: + pmt_@TAG@vector(size_t k, @TYPE@ fill); + pmt_@TAG@vector(size_t k, const @TYPE@ *data); + // ~pmt_@TAG@vector(); + + bool is_@TAG@vector() const { return true; } + size_t length() const { return d_v.size(); } + @TYPE@ ref(size_t k) const; + void set(size_t k, @TYPE@ x); + const @TYPE@ *elements(size_t &len); + @TYPE@ *writeable_elements(size_t &len); + const void *uniform_elements(size_t &len); + void *uniform_writeable_elements(size_t &len); +}; |