Merge branch 'wip/howto' of git@gnuradio.org:jcorgan
authorJohnathan Corgan <jcorgan@corganenterprises.com>
Tue, 3 Nov 2009 22:24:43 +0000 (14:24 -0800)
committerJohnathan Corgan <jcorgan@corganenterprises.com>
Tue, 3 Nov 2009 22:24:43 +0000 (14:24 -0800)
* 'wip/howto' of git@gnuradio.org:jcorgan:
  howto: moved osbsolete docs directory into limbo
  howto: make swig directory use individual .i files
  howto: reorganized directory structure
  howto: implement dynamic versioning
  howto: update m4 files to match latest master
  howto: updated INSTALL, fixed mode of config.*

63 files changed:
gr-howto-write-a-block/INSTALL
gr-howto-write-a-block/Makefile.am
gr-howto-write-a-block/config.guess [changed mode: 0644->0755]
gr-howto-write-a-block/config.sub [changed mode: 0644->0755]
gr-howto-write-a-block/config/Makefile.am
gr-howto-write-a-block/config/gr_fortran.m4
gr-howto-write-a-block/config/gr_git.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_pwin32.m4
gr-howto-write-a-block/config/gr_python.m4
gr-howto-write-a-block/config/gr_set_md_cpu.m4
gr-howto-write-a-block/config/gr_standalone.m4
gr-howto-write-a-block/config/gr_version.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/lf_warnings.m4
gr-howto-write-a-block/config/usrp_fusb_tech.m4
gr-howto-write-a-block/configure.ac
gr-howto-write-a-block/doc/.gitignore [deleted file]
gr-howto-write-a-block/doc/Makefile.am [deleted file]
gr-howto-write-a-block/doc/howto-write-a-block.xml [deleted file]
gr-howto-write-a-block/doc/howto_1.i [deleted file]
gr-howto-write-a-block/doc/make_numbered_listing.py [deleted file]
gr-howto-write-a-block/doc/qa_howto_1.py [deleted file]
gr-howto-write-a-block/doc/src_lib_Makefile_1.am [deleted file]
gr-howto-write-a-block/doc/src_lib_Makefile_2.am [deleted file]
gr-howto-write-a-block/lib/.gitignore [new file with mode: 0644]
gr-howto-write-a-block/lib/Makefile.am [new file with mode: 0644]
gr-howto-write-a-block/lib/howto_square2_ff.cc [new file with mode: 0644]
gr-howto-write-a-block/lib/howto_square2_ff.h [new file with mode: 0644]
gr-howto-write-a-block/lib/howto_square_ff.cc [new file with mode: 0644]
gr-howto-write-a-block/lib/howto_square_ff.h [new file with mode: 0644]
gr-howto-write-a-block/limbo/doc/.gitignore [new file with mode: 0644]
gr-howto-write-a-block/limbo/doc/Makefile.am [new file with mode: 0644]
gr-howto-write-a-block/limbo/doc/README [new file with mode: 0644]
gr-howto-write-a-block/limbo/doc/howto-write-a-block.xml [new file with mode: 0644]
gr-howto-write-a-block/limbo/doc/howto_1.i [new file with mode: 0644]
gr-howto-write-a-block/limbo/doc/make_numbered_listing.py [new file with mode: 0755]
gr-howto-write-a-block/limbo/doc/qa_howto_1.py [new file with mode: 0755]
gr-howto-write-a-block/limbo/doc/src_lib_Makefile_1.am [new file with mode: 0644]
gr-howto-write-a-block/limbo/doc/src_lib_Makefile_2.am [new file with mode: 0644]
gr-howto-write-a-block/python/.gitignore [new file with mode: 0644]
gr-howto-write-a-block/python/Makefile.am [new file with mode: 0644]
gr-howto-write-a-block/python/qa_howto.py [new file with mode: 0755]
gr-howto-write-a-block/python/run_tests.in [new file with mode: 0644]
gr-howto-write-a-block/src/.gitignore [deleted file]
gr-howto-write-a-block/src/Makefile.am [deleted file]
gr-howto-write-a-block/src/lib/.gitignore [deleted file]
gr-howto-write-a-block/src/lib/Makefile.am [deleted file]
gr-howto-write-a-block/src/lib/Makefile.swig.gen [deleted file]
gr-howto-write-a-block/src/lib/howto.i [deleted file]
gr-howto-write-a-block/src/lib/howto_square2_ff.cc [deleted file]
gr-howto-write-a-block/src/lib/howto_square2_ff.h [deleted file]
gr-howto-write-a-block/src/lib/howto_square_ff.cc [deleted file]
gr-howto-write-a-block/src/lib/howto_square_ff.h [deleted file]
gr-howto-write-a-block/src/python/.gitignore [deleted file]
gr-howto-write-a-block/src/python/Makefile.am [deleted file]
gr-howto-write-a-block/src/python/qa_howto.py [deleted file]
gr-howto-write-a-block/src/python/run_tests.in [deleted file]
gr-howto-write-a-block/swig/.gitignore [new file with mode: 0644]
gr-howto-write-a-block/swig/Makefile.am [new file with mode: 0644]
gr-howto-write-a-block/swig/Makefile.swig.gen [new file with mode: 0644]
gr-howto-write-a-block/swig/howto.i [new file with mode: 0644]
gr-howto-write-a-block/swig/howto_square2_ff.i [new file with mode: 0644]
gr-howto-write-a-block/swig/howto_square_ff.i [new file with mode: 0644]
gr-howto-write-a-block/version.sh [new file with mode: 0644]

index d3c5b40a94091285c27361905f591af64c1f7b21..8b82ade08e87bbfb02fbf4c3b45b181ab6dda8cb 100644 (file)
@@ -2,15 +2,15 @@ Installation Instructions
 *************************
 
 Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
-2006, 2007 Free Software Foundation, Inc.
+2006, 2007, 2008 Free Software Foundation, Inc.
 
-This file is free documentation; the Free Software Foundation gives
+   This file is free documentation; the Free Software Foundation gives
 unlimited permission to copy, distribute and modify it.
 
 Basic Installation
 ==================
 
-Briefly, the shell commands `./configure; make; make install' should
+   Briefly, the shell commands `./configure; make; make install' should
 configure, build, and install this package.  The following
 more-detailed instructions are generic; see the `README' file for
 instructions specific to this package.
@@ -73,9 +73,9 @@ The simplest way to compile this package is:
 Compilers and Options
 =====================
 
-Some systems require unusual options for compilation or linking that the
-`configure' script does not know about.  Run `./configure --help' for
-details on some of the pertinent environment variables.
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  Run `./configure --help'
+for details on some of the pertinent environment variables.
 
    You can give `configure' initial values for configuration parameters
 by setting variables in the command line or in the environment.  Here
@@ -88,7 +88,7 @@ is an example:
 Compiling For Multiple Architectures
 ====================================
 
-You can compile the package for more than one kind of computer at the
+   You can compile the package for more than one kind of computer at the
 same time, by placing the object files for each architecture in their
 own directory.  To do this, you can use GNU `make'.  `cd' to the
 directory where you want the object files and executables to go and run
@@ -100,10 +100,24 @@ architecture at a time in the source code directory.  After you have
 installed the package for one architecture, use `make distclean' before
 reconfiguring for another architecture.
 
+   On MacOS X 10.5 and later systems, you can create libraries and
+executables that work on multiple system types--known as "fat" or
+"universal" binaries--by specifying multiple `-arch' options to the
+compiler but only a single `-arch' option to the preprocessor.  Like
+this:
+
+     ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CPP="gcc -E" CXXCPP="g++ -E"
+
+   This is not guaranteed to produce working output in all cases, you
+may have to build one architecture at a time and combine the results
+using the `lipo' tool if you have problems.
+
 Installation Names
 ==================
 
-By default, `make install' installs the package's commands under
+   By default, `make install' installs the package's commands under
 `/usr/local/bin', include files under `/usr/local/include', etc.  You
 can specify an installation prefix other than `/usr/local' by giving
 `configure' the option `--prefix=PREFIX'.
@@ -126,7 +140,7 @@ option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
 Optional Features
 =================
 
-Some packages pay attention to `--enable-FEATURE' options to
+   Some packages pay attention to `--enable-FEATURE' options to
 `configure', where FEATURE indicates an optional part of the package.
 They may also pay attention to `--with-PACKAGE' options, where PACKAGE
 is something like `gnu-as' or `x' (for the X Window System).  The
@@ -138,14 +152,36 @@ find the X include and library files automatically, but if it doesn't,
 you can use the `configure' options `--x-includes=DIR' and
 `--x-libraries=DIR' to specify their locations.
 
+Particular systems
+==================
+
+   On HP-UX, the default C compiler is not ANSI C compatible.  If GNU
+CC is not installed, it is recommended to use the following options in
+order to use an ANSI C compiler:
+
+     ./configure CC="cc -Ae"
+
+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
+
+   On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
+parse its `<wchar.h>' header file.  The option `-nodtk' can be used as
+a workaround.  If GNU CC is not installed, it is therefore recommended
+to try
+
+     ./configure CC="cc"
+
+and if that doesn't work, try
+
+     ./configure CC="cc -nodtk"
+
 Specifying the System Type
 ==========================
 
-There may be some features `configure' cannot figure out automatically,
-but needs to determine by the type of machine the package will run on.
-Usually, assuming the package is built to be run on the _same_
-architectures, `configure' can figure that out, but if it prints a
-message saying it cannot guess the machine type, give it the
+   There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+message saying it cannot guess the machine type, give it the
 `--build=TYPE' option.  TYPE can either be a short name for the system
 type, such as `sun4', or a canonical name which has the form:
 
@@ -171,9 +207,9 @@ eventually be run) with `--host=TYPE'.
 Sharing Defaults
 ================
 
-If you want to set default values for `configure' scripts to share, you
-can create a site shell script called `config.site' that gives default
-values for variables like `CC', `cache_file', and `prefix'.
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
 `configure' looks for `PREFIX/share/config.site' if it exists, then
 `PREFIX/etc/config.site' if it exists.  Or, you can set the
 `CONFIG_SITE' environment variable to the location of the site script.
@@ -182,7 +218,7 @@ A warning: not all `configure' scripts look for a site script.
 Defining Variables
 ==================
 
-Variables not defined in a site shell script can be set in the
+   Variables not defined in a site shell script can be set in the
 environment passed to `configure'.  However, some packages may run
 configure again during the build, and the customized values of these
 variables may be lost.  In order to avoid this problem, you should set
@@ -201,11 +237,19 @@ an Autoconf bug.  Until the bug is fixed you can use this workaround:
 `configure' Invocation
 ======================
 
-`configure' recognizes the following options to control how it operates.
+   `configure' recognizes the following options to control how it
+operates.
 
 `--help'
 `-h'
-     Print a summary of the options to `configure', and exit.
+     Print a summary of all of the options to `configure', and exit.
+
+`--help=short'
+`--help=recursive'
+     Print a summary of the options unique to this package's
+     `configure', and exit.  The `short' variant lists options used
+     only in the top level, while the `recursive' variant lists options
+     also present in any nested packages.
 
 `--version'
 `-V'
@@ -232,6 +276,16 @@ an Autoconf bug.  Until the bug is fixed you can use this workaround:
      Look for the package's source code in directory DIR.  Usually
      `configure' can determine that directory automatically.
 
+`--prefix=DIR'
+     Use DIR as the installation prefix.  *Note Installation Names::
+     for more details, including other options available for fine-tuning
+     the installation locations.
+
+`--no-create'
+`-n'
+     Run the configure checks, but stop before creating any output
+     files.
+
 `configure' also accepts some other, not widely useful, options.  Run
 `configure --help' for more details.
 
index 56307aada053766671445349e8256bbd2c8620d6..ce2e4e8ca2c6ea94a0499b842eff1bc0b544abdb 100644 (file)
@@ -23,11 +23,17 @@ ACLOCAL_AMFLAGS = -I config
 
 include $(top_srcdir)/Makefile.common
 
-EXTRA_DIST = bootstrap configure config.h.in \
-       Makefile.swig Makefile.swig.gen.t
+EXTRA_DIST = \
+       bootstrap \
+       configure \
+       config.h.in \
+       Makefile.swig \
+       Makefile.swig.gen.t \
+       version.sh
 
-SUBDIRS = config src
-DIST_SUBDIRS = config src doc
+SUBDIRS = config lib swig python
 
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA =
+
+DISTCLEANFILES = gr-howto-write-a-block*.tar.gz
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 5858d2219b3b8567b02ff29e20c3896563c91a99..23f4a4b16e68fa10ea6cb394bd92d91f9285b242 100644 (file)
@@ -49,6 +49,7 @@ m4macros = \
        gr_check_usrp.m4 \
        gr_doxygen.m4 \
        gr_fortran.m4 \
+       gr_git.m4 \
        gr_gprof.m4 \
        gr_lib64.m4 \
        gr_libgnuradio_core_extra_ldflags.m4 \
@@ -63,6 +64,7 @@ m4macros = \
        gr_subversion.m4 \
        gr_swig.m4 \
        gr_sysv_shm.m4 \
+       gr_version.m4 \
        lf_cc.m4 \
        lf_cxx.m4 \
        lf_warnings.m4 \
index b5b0470f45c2ce78cb525490bf56d32b0548f140..033ef0307820e4987a2be810a9acc54e4f5a45bc 100644 (file)
@@ -29,4 +29,5 @@ AC_DEFUN([GR_FORTRAN],[
         AC_PROG_F77
         AC_F77_LIBRARY_LDFLAGS
     fi
+    AC_PROG_CC dnl bug fix to restore $ac_ext
 ])
diff --git a/gr-howto-write-a-block/config/gr_git.m4 b/gr-howto-write-a-block/config/gr_git.m4
new file mode 100644 (file)
index 0000000..5fe4248
--- /dev/null
@@ -0,0 +1,35 @@
+dnl Copyright 2009 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+
+
+AC_DEFUN([GR_GIT],[
+  dnl Identify git binary
+  AC_PATH_PROG([GIT],[git])
+  
+  dnl If it exists, get either 'git describe' or fallback to current commit
+  if test x$GIT != x ; then
+    if (cd $srcdir && $GIT describe >/dev/null 2>&1); then
+      GIT_VERSION=`cd $srcdir && $GIT describe --abbrev=8 | cut -f 2- -d '-'`
+    else
+      if (cd $srcdir && $GIT describe --always --abbrev=8 >/dev/null 2>&1); then
+        GIT_VERSION=`cd $srcdir && $GIT describe --always --abbrev=8`
+      fi
+    fi
+  fi
+])
index 7b99cba6b7301de4f0c2720ab8d096cfd6e85b91..495e9dd4d39dba2246bbe9a48ef9fbd6715c2ec6 100644 (file)
@@ -99,6 +99,9 @@ struct timespec {
        long    tv_nsec;
 };
 #endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
 static inline int nanosleep(const struct timespec *req, struct timespec *rem) { return usleep(req->tv_sec*1000000+req->tv_nsec/1000); }
 #endif
 
index 6c862bba397b2516ef92f92c5f8a403ab8a7d2c7..43ccfc01575f5e0c53cab03a12f603e92c10c64b 100644 (file)
@@ -123,6 +123,50 @@ print path
              ;;
            esac
 
+           case $host_os in
+                *mingw* )
+             # Python 2.5 requires ".pyd" instead of ".dll" for extensions
+             PYTHON_LDFLAGS="-shrext .pyd ${PYTHON_LDFLAGS}"
+           esac
+
            AC_SUBST(PYTHON_LDFLAGS)
        fi
 ])
+
+# PYTHON_CHECK_MODULE
+#
+# Determines if a particular Python module can be imported
+#
+# $1 - module name
+# $2 - module description
+# $3 - action if found
+# $4 - action if not found
+# $5 - test command
+
+AC_DEFUN([PYTHON_CHECK_MODULE],[
+    AC_MSG_CHECKING([for $2])
+    dnl ########################################
+    dnl # import and test checking
+    dnl ########################################
+    if test "$5"; then
+        python_cmd='
+try:
+    import $1
+    assert $5
+except: exit(1)'
+    dnl ########################################
+    dnl # import checking only
+    dnl ########################################
+    else
+        python_cmd='
+try: import $1
+except: exit(1)'
+    fi
+    if ! $PYTHON -c "$python_cmd" 2> /dev/null; then
+        AC_MSG_RESULT([no])
+        $4
+    else
+        AC_MSG_RESULT([yes])
+        $3
+    fi
+])
index b9c570eded395c28cbe3a36638cb6088df37776d..7ebf88a66428d73309c626e6467686d43bed9457 100644 (file)
@@ -1,5 +1,5 @@
 dnl
-dnl Copyright 2003,2008 Free Software Foundation, Inc.
+dnl Copyright 2003,2008,2009 Free Software Foundation, Inc.
 dnl 
 dnl This file is part of GNU Radio
 dnl 
@@ -19,20 +19,89 @@ dnl the Free Software Foundation, Inc., 51 Franklin Street,
 dnl Boston, MA 02110-1301, USA.
 dnl 
 
+AC_DEFUN([_TRY_ADD_ALTIVEC],
+[
+  LF_CHECK_CC_FLAG([-mabi=altivec -maltivec])
+  LF_CHECK_CXX_FLAG([-mabi=altivec -maltivec])
+])
+
+AC_DEFUN([_FIND_ARM_ISA],
+[
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+  [[#ifndef __ARM_ARCH_5__
+    #error "Not armv5"
+    #endif
+  ]])],
+    [is_armv5=yes],
+    [is_armv5=no])
+
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+  [[#ifndef __ARM_ARCH_7A__
+    #error "Not armv7-a"
+    #endif
+  ]])],
+    [is_armv7_a=yes],
+    [is_armv7_a=no])
+
+])
+
 AC_DEFUN([GR_SET_MD_CPU],[
   AC_REQUIRE([AC_CANONICAL_HOST])
   AC_ARG_WITH(md-cpu,
-       [  --with-md-cpu=ARCH      set machine dependent speedups (auto)],
+       AC_HELP_STRING([--with-md-cpu=ARCH],[set machine dependent speedups (auto)]),
                [cf_with_md_cpu="$withval"],
-               [cf_with_md_cpu="$host_cpu"])
-
-  AC_MSG_CHECKING([for machine dependent speedups])
+               [
+  dnl see if the user has specified --host or --build, via 'cross_compiling'
+  if test "$cross_compiling" != no; then
+    dnl when cross-compiling, because the user specified it either via
+    dnl --target or --build, just keep the user's specs & hope for the best.
+    cf_with_md_cpu="$host_cpu"
+  else
+    dnl when the user didn't specify --target or --build, on Darwin 10
+    dnl (OSX 10.6.0 and .1) and GNU libtoool 2.2.6, 'configure' doesn't
+    dnl figure out the CPU type correctly, so do it by hand here using
+    dnl the sizeof (void*): if 4 then use i386, and otherwise use x86_64.
+    case "$host_os" in
+     *darwin*10*)
+      AC_CHECK_SIZEOF(void*)
+      if test "$ac_cv_sizeof_voidp" = 4; then
+       cf_with_md_cpu="i386"
+      else
+       cf_with_md_cpu="x86_64"
+      fi
+      ;;
+     *)
+      cf_with_md_cpu="$host_cpu"
+      ;;
+    esac
+  fi
+  ])
   case "$cf_with_md_cpu" in
    x86 | i[[3-7]]86)   MD_CPU=x86      MD_SUBCPU=x86 ;;
    x86_64)             MD_CPU=x86      MD_SUBCPU=x86_64 ;;
    powerpc*)            MD_CPU=powerpc ;;
+   arm)
+       _FIND_ARM_ISA
+       if test $is_armv5 = yes; then MD_CPU=armv5;
+       elif test $is_armv7_a = yes; then MD_CPU=armv7_a;
+       else MD_CPU=generic; fi
+       ;;
    *)                  MD_CPU=generic ;;
   esac
+
+  AC_ARG_ENABLE(altivec,
+    AC_HELP_STRING([--enable-altivec],[enable altivec on PowerPC (yes)]),
+    [ if test $MD_CPU = powerpc; then
+        case "$enableval" in
+          (no)  MD_CPU=generic ;;
+          (yes) _TRY_ADD_ALTIVEC ;;
+          (*) AC_MSG_ERROR([Invalid argument ($enableval) to --enable-altivec]) ;;
+        esac
+      fi],
+    [ if test $MD_CPU = powerpc; then _TRY_ADD_ALTIVEC fi])
+
+
+  AC_MSG_CHECKING([for machine dependent speedups])
   AC_MSG_RESULT($MD_CPU)
   AC_SUBST(MD_CPU)
   AC_SUBST(MD_SUBCPU) 
@@ -40,5 +109,7 @@ AC_DEFUN([GR_SET_MD_CPU],[
   AM_CONDITIONAL(MD_CPU_x86,     test "$MD_CPU" = "x86")
   AM_CONDITIONAL(MD_SUBCPU_x86_64,  test "$MD_SUBCPU" = "x86_64")
   AM_CONDITIONAL(MD_CPU_powerpc, test "$MD_CPU" = "powerpc")
+  AM_CONDITIONAL(MD_CPU_armv5, test "$MD_CPU" = "armv5")
+  AM_CONDITIONAL(MD_CPU_armv7_a, test "$MD_CPU" = "armv7_a")
   AM_CONDITIONAL(MD_CPU_generic, test "$MD_CPU" = "generic")
 ])
index 2f8851676d1def6f0c138eb7c6aa808b5df17379..593583e2dde56f23f64f047113af335285d84bfb 100644 (file)
@@ -31,12 +31,6 @@ m4_define([GR_STANDALONE],
   AC_CONFIG_SRCDIR([config/gr_standalone.m4])
   AM_CONFIG_HEADER(config.h)
 
-  AC_CANONICAL_BUILD
-  AC_CANONICAL_HOST
-  AC_CANONICAL_TARGET
-
-  AM_INIT_AUTOMAKE
-
   dnl Remember if the user explicity set CXXFLAGS
   if test -n "${CXXFLAGS}"; then
     user_set_cxxflags=yes
diff --git a/gr-howto-write-a-block/config/gr_version.m4 b/gr-howto-write-a-block/config/gr_version.m4
new file mode 100644 (file)
index 0000000..3360b7d
--- /dev/null
@@ -0,0 +1,74 @@
+dnl Copyright 2009 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+
+AC_DEFUN([GR_VERSION],[
+  dnl Computed version based on version.sh
+  dnl Does not force recompile on rev change
+  dnl
+  dnl Source the variables describing the release version
+  dnl 
+  dnl MAJOR_VERSION          Major release generation (2.x, 3.x, etc.)
+  dnl API_COMPAT             API compatibility version (3.2.x, 3.3.x, etc.)
+  dnl MINOR_VERSION          Minor release version
+  dnl MAINT_VERSION          Pure bugfix additions to make maintenance release
+  dnl
+  dnl The last two fields can have 'git' instead of a number to indicate
+  dnl that this branch is between versions.
+  . $srcdir/version.sh
+  RELEASE=$MAJOR_VERSION.$API_COMPAT
+  
+  dnl Get git version if available
+  GR_GIT
+
+  dnl Test if we should use git version
+  if test "$MINOR_VERSION" == "git"; then
+    dnl 3.3git-xxx-gxxxxxxxx
+    RELEASE=$RELEASE$MINOR_VERSION
+    DOCVER=$RELEASE
+    if test "$GIT_VERSION" != "" ; then
+      RELEASE=$RELEASE-$GIT_VERSION
+    fi
+  else
+    if test "$MAINT_VERSION" == "git" ; then
+      dnl 3.3.1git-xxx-gxxxxxxxx
+      RELEASE=$RELEASE.$MINOR_VERSION$MAINT_VERSION
+      DOCVER=$RELEASE
+      if test "$GIT_VERSION" != "" ; then
+        RELEASE=$RELEASE-$GIT_VERSION
+      fi
+    else
+      dnl This is a numbered reelase.
+      dnl Test if minor version is 0, which we don't encode, unless it is also
+      dnl a maintenance release
+      if test "$MINOR_VERSION" != "0" -o "$MAINT_VERSION" != "0"; then
+        dnl 3.3.1
+        RELEASE=$RELEASE.$MINOR_VERSION                          
+        if test "$MAINT_VERSION" != "0"; then
+          dnl 3.3.0.1, 3.3.1.1
+          RELEASE=$RELEASE.$MAINT_VERSION
+        fi
+       DOCVER=$RELEASE
+      fi
+    fi
+  fi
+
+  AC_MSG_NOTICE([GNU Radio Release $RELEASE])
+  AC_SUBST(RELEASE)
+  AC_SUBST(DOCVER)
+])
index 4e2ca9111736a862f029f9e21d3117f16325f945..d40c77f14d56206e56334727bc35d438a03cbece 100644 (file)
@@ -1,4 +1,5 @@
 dnl Copyright (C) 1988 Eleftherios Gkioulekas <lf@amath.washington.edu>
+dnl Copyright (C) 2009 Free Software Foundation, Inc.
 dnl  
 dnl This program is free software; you can redistribute it and/or modify
 dnl it under the terms of the GNU General Public License as published by
@@ -21,7 +22,7 @@ dnl distribution terms that you use for the rest of that program.
 
 # --------------------------------------------------------------------------
 # Check whether the C++ compiler accepts a certain flag
-# If it does it adds the flag to CXXFLAGS
+# If it does it adds the flag to lf_CXXFLAGS
 # If it does not then it returns an error to lf_ok
 # Usage:
 #   LF_CHECK_CXX_FLAG(-flag1 -flag2 -flag3 ...)
@@ -34,18 +35,19 @@ AC_DEFUN([LF_CHECK_CXX_FLAG],[
     AC_MSG_CHECKING([whether $CXX accepts $i])
     if test -z "`${CXX} $i -c conftest.cc 2>&1`"
     then
-      CXXFLAGS="${CXXFLAGS} $i"
+      lf_CXXFLAGS="${lf_CXXFLAGS} $i"
       AC_MSG_RESULT(yes)
     else
       AC_MSG_RESULT(no)
     fi
   done
   rm -f conftest.cc conftest.o
+  AC_SUBST(lf_CXXFLAGS)
 ])
 
 # --------------------------------------------------------------------------
 # Check whether the C compiler accepts a certain flag
-# If it does it adds the flag to CFLAGS
+# If it does it adds the flag to lf_CFLAGS
 # If it does not then it returns an error to lf_ok
 # Usage:
 #  LF_CHECK_CC_FLAG(-flag1 -flag2 -flag3 ...)
@@ -58,18 +60,19 @@ AC_DEFUN([LF_CHECK_CC_FLAG],[
     AC_MSG_CHECKING([whether $CC accepts $i])
     if test -z "`${CC} $i -c conftest.c 2>&1`"
     then
-      CFLAGS="${CFLAGS} $i"
+      lf_CFLAGS="${lf_CFLAGS} $i"
       AC_MSG_RESULT(yes)
     else
       AC_MSG_RESULT(no)
     fi
   done
   rm -f conftest.c conftest.o
+  AC_SUBST(lf_CFLAGS)
 ])
 
 # --------------------------------------------------------------------------
 # Check whether the Fortran compiler accepts a certain flag
-# If it does it adds the flag to FFLAGS
+# If it does it adds the flag to lf_FFLAGS
 # If it does not then it returns an error to lf_ok
 # Usage:
 #  LF_CHECK_F77_FLAG(-flag1 -flag2 -flag3 ...)
@@ -87,42 +90,32 @@ EOF
     AC_MSG_CHECKING([whether $F77 accepts $i])
     if test -z "`${F77} $i -c conftest.f 2>&1`"
     then
-      FFLAGS="${FFLAGS} $i"
+      lf_FFLAGS="${lf_FFLAGS} $i"
       AC_MSG_RESULT(yes)  
     else
       AC_MSG_RESULT(no)
     fi
   done
   rm -f conftest.f conftest.o
+  AC_SUBST(lf_FFLAGS)
 ])
 
 # ----------------------------------------------------------------------
-# Provide the configure script with an --with-warnings option that
-# turns on warnings. Call this command AFTER you have configured ALL your
-# compilers. 
+# Enable compiler warnings. 
+# Call this command AFTER you have configured ALL your compilers. 
 # ----------------------------------------------------------------------
 
 AC_DEFUN([LF_SET_WARNINGS],[
-  dnl Check for --with-warnings
-  AC_MSG_CHECKING([whether user wants warnings])
-  AC_ARG_WITH(warnings,
-              [  --with-warnings         Turn on warnings],
-              [ lf_warnings=yes ], [ lf_warnings=no ])
-  lf_warnings=yes # hard code for now -eb
-  AC_MSG_RESULT($lf_warnings)
-  
   dnl Warnings for the two main compilers
-  cc_warning_flags="-Wall"
+  dnl add -Wextra when you're got time to fix a bunch of them ;-)
+  cc_warning_flags="-Wall -Werror-implicit-function-declaration"
   cxx_warning_flags="-Wall -Woverloaded-virtual"
-  if test $lf_warnings = yes
+  if test -n "${CC}"
   then
-    if test -n "${CC}"
-    then
-      LF_CHECK_CC_FLAG($cc_warning_flags)
-    fi
-    if test -n "${CXX}" 
-    then
-      LF_CHECK_CXX_FLAG($cxx_warning_flags)
-    fi
+    LF_CHECK_CC_FLAG($cc_warning_flags)
+  fi
+  if test -n "${CXX}" 
+  then
+    LF_CHECK_CXX_FLAG($cxx_warning_flags)
   fi
 ])
index db857249b0d0f126b74f367afb795551bd0631e5..b99cf243207c43ba9210732e7346172d0c994a93 100644 (file)
@@ -1,5 +1,5 @@
 dnl
-dnl Copyright 2003,2008 Free Software Foundation, Inc.
+dnl Copyright 2003,2008,2009 Free Software Foundation, Inc.
 dnl 
 dnl This file is part of GNU Radio
 dnl 
@@ -25,6 +25,8 @@ dnl
 #   ""  : do these tests
 
 AC_DEFUN([USRP_SET_FUSB_TECHNIQUE],[
+  req_libusb1=no
+  USE_LIBUSB1=0
   AC_ARG_WITH([fusb-tech],
               AC_HELP_STRING([--with-fusb-tech=OS],
                             [Set fast USB technique (default=auto)]),
@@ -32,6 +34,11 @@ AC_DEFUN([USRP_SET_FUSB_TECHNIQUE],[
              [cf_with_fusb_tech="$host_os"])
   if test [x]$1 != xno; then
       case "$cf_with_fusb_tech" in
+        libusb1*)
+          FUSB_TECH=libusb1
+          req_libusb1=yes
+         USE_LIBUSB1=1
+          ;;
         linux*)
           AC_CHECK_HEADER([linux/usbdevice_fs.h],
                          [x_have_usbdevice_fs_h=yes],
@@ -70,5 +77,11 @@ AC_DEFUN([USRP_SET_FUSB_TECHNIQUE],[
   AM_CONDITIONAL(FUSB_TECH_win32,    test x$FUSB_TECH = xwin32)
   AM_CONDITIONAL(FUSB_TECH_generic,  test x$FUSB_TECH = xgeneric)
   AM_CONDITIONAL(FUSB_TECH_linux,    test x$FUSB_TECH = xlinux)
+  AM_CONDITIONAL(FUSB_TECH_libusb1,  test x$FUSB_TECH = xlibusb1)
   AM_CONDITIONAL(FUSB_TECH_ra_wb,    test x$FUSB_TECH = xra_wb)
+
+  AC_SUBST(USE_LIBUSB1)
+  AC_CONFIG_FILES([\
+       usrp/host/include/usrp/libusb_types.h \
+  ])
 ])
index bfb431526ba722199c094ef41f2e62f6111d27ec..8241f7ec1aaea4ae1589065c3199a3e4c43e1957 100644 (file)
@@ -19,10 +19,20 @@ dnl  the Free Software Foundation, Inc., 51 Franklin Street,
 dnl  Boston, MA 02110-1301, USA.
 dnl 
 
-AC_INIT(gr-howto-write-a-block,3.3svn)
+
+AC_INIT
 AC_PREREQ(2.57)
 AC_CONFIG_AUX_DIR([.]) 
 
+AC_CANONICAL_BUILD
+AC_CANONICAL_HOST
+AC_CANONICAL_TARGET
+
+GR_VERSION
+dnl ustar required to have pathnames > 99 chars
+_AM_SET_OPTION([tar-ustar])
+AM_INIT_AUTOMAKE(gr-howto-write-a-block,$RELEASE)
+
 dnl This is kind of non-standard, but it sure shortens up this file :-)
 m4_include([config/gr_standalone.m4])
 GR_STANDALONE
@@ -62,14 +72,15 @@ dnl AX_BOOST_WSERIALIZATION
 AC_CONFIG_FILES([\
          Makefile \
          config/Makefile \
-         doc/Makefile \
-         src/Makefile \
-         src/lib/Makefile \
-         src/python/Makefile \
-         src/python/run_tests \
+         lib/Makefile \
+         python/Makefile \
+         python/run_tests \
+         swig/Makefile \
        ])
 
 dnl run_tests is created from run_tests.in.  Make it executable.
-AC_CONFIG_COMMANDS([run_tests], [chmod +x src/python/run_tests])
+AC_CONFIG_COMMANDS([run_tests], [chmod +x python/run_tests])
 
 AC_OUTPUT
+
+echo Configured gr-howto-write-a-block release $RELEASE for build.
diff --git a/gr-howto-write-a-block/doc/.gitignore b/gr-howto-write-a-block/doc/.gitignore
deleted file mode 100644 (file)
index f65ab6c..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/Makefile
-/Makefile.in
-/.deps
-/.libs
-/*.la
-/*.lo
-/autom4te.cache
-/*.cache
-/howto-write-a-block.html
-/gr_block.h.xml
-/howto_1.i.xml
-/howto_square_ff.cc.xml
-/howto_square_ff.h.xml
-/qa_howto_1.py.xml
-/src_lib_Makefile_1.am.xml
-/src_lib_Makefile_2.am.xml
-/howto_square2_ff.cc.xml
-/howto_square2_ff.h.xml
diff --git a/gr-howto-write-a-block/doc/Makefile.am b/gr-howto-write-a-block/doc/Makefile.am
deleted file mode 100644 (file)
index 0152eca..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-#
-# Copyright 2004,2005,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 GNU Radio; see the file COPYING.  If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-# 
-
-TARGETS = howto-write-a-block.html
-
-
-# To avoid build problems for folks who don't have xmlto installed, we
-# don't build the docs by default.
-
-# html: $(TARGETS)
-all: $(TARGETS)
-
-
-EXTRA_DIST =                           \
-       howto-write-a-block.xml         \
-       howto_1.i                       \
-       make_numbered_listing.py        \
-       qa_howto_1.py                   \
-       src_lib_Makefile_1.am           \
-       src_lib_Makefile_2.am           
-
-
-BUILT_XML_FILES =                      \
-       gr_block.h.xml                  \
-       howto_1.i.xml                   \
-       howto_square_ff.cc.xml          \
-       howto_square_ff.h.xml           \
-       howto_square2_ff.cc.xml         \
-       howto_square2_ff.h.xml          \
-       qa_howto_1.py.xml               \
-       src_lib_Makefile_1.am.xml       \
-       src_lib_Makefile_2.am.xml       
-
-
-howto-write-a-block.html : howto-write-a-block.xml $(BUILT_XML_FILES)
-
-
-gr_block.h.xml: $(GNURADIO_CORE_INCLUDEDIR)/gr_block.h make_numbered_listing.py
-       $(PYTHON) ./make_numbered_listing.py $(GNURADIO_CORE_INCLUDEDIR)/gr_block.h
-
-howto_square_ff.cc.xml: $(top_srcdir)/src/lib/howto_square_ff.cc make_numbered_listing.py
-       $(PYTHON) ./make_numbered_listing.py $(top_srcdir)/src/lib/howto_square_ff.cc 
-
-howto_square_ff.h.xml: $(top_srcdir)/src/lib/howto_square_ff.h make_numbered_listing.py
-       $(PYTHON) ./make_numbered_listing.py $(top_srcdir)/src/lib/howto_square_ff.h 
-
-howto_square2_ff.cc.xml: $(top_srcdir)/src/lib/howto_square2_ff.cc make_numbered_listing.py
-       $(PYTHON) ./make_numbered_listing.py $(top_srcdir)/src/lib/howto_square2_ff.cc 
-
-howto_square2_ff.h.xml: $(top_srcdir)/src/lib/howto_square2_ff.h make_numbered_listing.py
-       $(PYTHON) ./make_numbered_listing.py $(top_srcdir)/src/lib/howto_square2_ff.h 
-
-
-# ----------------------------------------------------------------
-
-clean:
-       -${RM} -f $(TARGETS) $(BUILT_XML_FILES)
-
-%.html : %.xml
-       xmlto html-nochunks $<
-
-%.xml : % make_numbered_listing.py
-       $(PYTHON) ./make_numbered_listing.py $<
diff --git a/gr-howto-write-a-block/doc/howto-write-a-block.xml b/gr-howto-write-a-block/doc/howto-write-a-block.xml
deleted file mode 100644 (file)
index f8027b4..0000000
+++ /dev/null
@@ -1,959 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-          "docbookx.dtd" [
-  <!ENTITY gnuradio "<application>GNU Radio</application>">
-  <!ENTITY SWIG "<application>SWIG</application>">
-  <!ENTITY gr_block "<classname>gr_block</classname>">
-  <!ENTITY square "<classname>howto_square_ff</classname>">
-
-  <!ENTITY were "we&apos;re">
-  <!ENTITY well "we&apos;ll">
-  <!ENTITY thats "that&apos;s">
-  <!ENTITY its "it&apos;s">
-  <!ENTITY lets "let&apos;s">
-  <!ENTITY youre "you&apos;re">
-
-  <!ENTITY gr_block_listing SYSTEM "gr_block.h.xml">
-  <!ENTITY qa_howto_1_listing SYSTEM "qa_howto_1.py.xml">
-  <!ENTITY howto_square_ff_h_listing SYSTEM "howto_square_ff.h.xml">
-  <!ENTITY howto_square_ff_cc_listing SYSTEM "howto_square_ff.cc.xml">
-  <!ENTITY howto_square2_ff_h_listing SYSTEM "howto_square2_ff.h.xml">
-  <!ENTITY howto_square2_ff_cc_listing SYSTEM "howto_square2_ff.cc.xml">
-  <!ENTITY howto_1_i_listing SYSTEM "howto_1.i.xml">
-  <!ENTITY src_lib_Makefile_1_am_listing SYSTEM "src_lib_Makefile_1.am.xml">
-  <!ENTITY src_lib_Makefile_2_am_listing SYSTEM "src_lib_Makefile_2.am.xml">
-
-]>
-
-<article>
-
-<articleinfo>
-<title>How to Write a Signal Processing Block</title>
-<author>
-  <firstname>Eric</firstname>
-  <surname>Blossom</surname>
-  <affiliation>
-    <address>
-      <email>eb@comsec.com</email>
-    </address>
-  </affiliation>
-</author>
-
-<revhistory>
-  <revision>
-  <revnumber>0.1</revnumber>
-  <date>2005-01-20</date>
-  </revision>
-  <revision>
-  <revnumber>0.2</revnumber>
-  <date>2005-02-02</date>
-  <revremark>Updated for SWIG 1.3.24</revremark>
-  </revision>
-  <revision>
-  <revnumber>0.3</revnumber>
-  <date>2006-07-21</date>
-  <revremark>Clarification of 1:1 fixed rate vs item size</revremark>
-  </revision>
-</revhistory>
-
-<copyright>
-  <year>2004</year>
-  <year>2005</year>
-  <holder>Free Software Foundation, Inc.</holder>
-</copyright>
-
-<abstract><para>This article explains how to write signal
-processing blocks for <application>GNU Radio</application>.
-</para></abstract>
-
-</articleinfo>
-
-<sect1 id="prereqs"><title>Prerequisites</title>
-<para>This article assumes that the reader has basic familiarity with
-GNU Radio and has read and understood 
-<ulink url="http://www.gnu.org/software/gnuradio/doc/exploring-gnuradio.html">
-<citetitle>Exploring GNU Radio</citetitle></ulink>.
-</para>
-
-<para>There is a tarball of files that accompany this article.  It
-includes the examples, DocBook source for the article and all the
-Makefiles etc it takes to make it work.  Grab it at <ulink
-url="ftp://ftp.gnu.org/gnu/gnuradio">
-ftp://ftp.gnu.org/gnu/gnuradio</ulink> or one of the mirrors.  The
-file you want is
-<filename>gr-howto-write-a-block-X.Y.tar.gz</filename>.  Pick the one
-with the highest version number. 
-See <ulink url="http://comsec.com/wiki?CvsAccess">
-http://comsec.com/wiki?CvsAccess</ulink> for CVS Access.
-</para>
-
-
-</sect1>
-
-<sect1 id="intro"><title>Introduction</title>
-<para>&gnuradio; provides a framework for building software radios.
-Waveforms -- signal processing applications -- are built using a
-combination of Python code for high level organization, policy, GUI and
-other non performance-critical functions, while performance critical
-signal processing blocks are written in C++.</para>
-
-<para>From the Python point of view, &gnuradio; provides a data flow
-abstraction.  The fundamental concepts are signal processing
-blocks and the connections between them.  This abstraction is
-implemented by the Python <classname>gr.flow_graph</classname> class.
-Each block has a set of input ports and output ports.  Each port has
-an associated data type.  The most common port types are
-<classname>float</classname> and <classname>gr_complex</classname>
-(equivalent to std::complex&lt;float&gt;), though other types are used,
-including those representing structures, arrays or other types of
-packetized data.</para>  
-
-<para>From the high level point-of-view, infinite streams of data flow
-through the ports.  At the C++ level, streams are dealt with in
-convenient sized pieces, represented as contiguous arrays of the
-underlying type.</para>
-
-</sect1>
-
-<sect1 id="overview"><title>The View from 30,000 Feet</title>
-
-<para>This article will walk through the construction of several
-simple signal processing blocks, and explain the techniques and idioms
-used.  Later sections cover debugging signal processing blocks in the
-mixed Python/C++ environment and performance measurement and
-optimization.</para>
-
-<para>The example blocks will be built in the style of all &gnuradio;
-extensions. That is, they are built outside of the gnuradio-core build
-tree, and are constructed as shared libraries that may be dynamically
-loaded into Python using the "import" mechanism.  &SWIG;, the
-Simplified Wrapper and Interface Generator, is used to generate the
-glue that allows our code to be used from Python.</para>
-
-</sect1>
-
-
-<sect1 id="gr_block"><title></title>
-
-<para>The C++ class &gr_block; is the base of all signal processing
-blocks in &gnuradio;.  Writing a new signal processing block involves
-creating 3 files: The .h and .cc files that define the new class and
-the .i file that tells &SWIG; how to generate the glue that binds the
-class into Python.  The new class must derive from &gr_block; or
-one of it&apos;s subclasses.</para>
-
-<para>Our first examples will derive directly from &gr_block;.  Later
-we will look at some other subclasses that simplify the process for
-common cases.</para>
-
-</sect1><!-- end gr_block sect1 -->
-
-
-
-<!-- ================================================================ -->
-
-<sect1 id="autotools"><title>Autotools, Makefiles, and Directory Layout</title>
-
-<para>Before we dive into the code, &lets; talk a bit about the
-overall build environment and the directory structure that &well;
-be using.</para>
-
-<para>To reduce the amount of Makefile hacking that we have to do, and
-to facilitate portability across a variety of systems, we use the GNU
-<application>autoconf</application>,
-<application>automake</application>, and
-<application>libtool</application> tools.  These are collectively
-referred to as the autotools, and once you get over the initial
-shock, they will become your friends. (The good news is that we
-provide boilerplate that can be used pretty much as-is.)</para>
-
-<variablelist>
-
-<varlistentry><term>automake</term>
-
-<listitem><para>automake and configure work together to generate GNU
-compliant Makefiles from a much higher level description contained in
-the corresponding Makefile.am file.  <filename>Makefile.am</filename>
-specifies the libraries and programs to build and the source files
-that compose each.  Automake reads <filename>Makefile.am</filename>
-and produces <filename>Makefile.in</filename>.  Configure reads
-<filename>Makefile.in</filename> and produces
-<filename>Makefile</filename>.  The resulting Makefile contains a
-zillion rules that do the right right thing to build, check and
-install your code.  It is not uncommon for the the resulting
-<filename>Makefile</filename> to be 5 or 6 times larger than
-<filename>Makefile.am</filename>.</para>
-
-</listitem>
-</varlistentry>
-
-<varlistentry><term>autoconf</term>
-<listitem><para>autoconf reads <filename>configure.ac</filename>
-and produces the <filename>configure</filename> shell
-script.  <filename>configure</filename> automatically tests for
-features of the underlying system and sets a bunch of variables and
-defines that can be used in the Makefiles and your C++ code to
-conditionalize the build.  If features are required but not found,
-configure will output an error message and stop.</para>
-</listitem>
-</varlistentry>
-
-<varlistentry><term>libtool</term>
-<listitem><para>libtool works behind the scenes and provides the magic
-to construct shared libraries on a wide variety of systems.</para>
-</listitem>
-</varlistentry>
-
-</variablelist>
-
-<para><xref linkend="dir-layout"/> shows the directory layout and
-common files &well; be using.  After renaming the
-<replaceable>topdir</replaceable> directory, use it in your projects
-too.  We'll talk about particular files as they come up later.</para>
-
-
-<table id="dir-layout"><title>Directory Layout</title>
-<tgroup cols="2">
-
-<thead><row>
-<entry>File/Dir Name</entry>
-<entry>Comment</entry>
-</row>
-</thead>
-
-<tbody>
-
-<row>
-<entry><replaceable>topdir</replaceable>/Makefile.am</entry>
-<entry>Top level Makefile.am</entry>
-</row>
-<row>
-<entry><replaceable>topdir</replaceable>/Makefile.common</entry>
-<entry>Common fragment included in sub-Makefiles</entry>
-</row>
-<row>
-<entry><replaceable>topdir</replaceable>/bootstrap</entry>
-<entry>Runs autoconf, automake, libtool first time through</entry>
-</row>
-<row>
-<entry><replaceable>topdir</replaceable>/config</entry>
-<entry>Directory of m4 macros used by configure.ac</entry>
-</row>
-<row>
-<entry><replaceable>topdir</replaceable>/configure.ac</entry>
-<entry>Input to autoconf</entry>
-</row>
-<row>
-<entry><replaceable>topdir</replaceable>/src</entry>
-</row>
-<row>
-<entry><replaceable>topdir</replaceable>/src/lib</entry>
-<entry>C++ code goes here</entry>
-</row>
-<row>
-<entry><replaceable>topdir</replaceable>/src/lib/Makefile.am</entry>
-</row>
-<row>
-<entry><replaceable>topdir</replaceable>/src/python</entry>
-<entry>Python code goes here</entry>
-</row>
-<row>
-<entry><replaceable>topdir</replaceable>/src/python/Makefile.am</entry>
-</row>
-<row>
-<entry><replaceable>topdir</replaceable>/src/python/run_tests</entry>
-<entry>Script to run tests in the build tree</entry>
-</row>
-
-</tbody>
-</tgroup>
-</table>
-
-</sect1>
-
-<!-- ================================================================ -->
-
-<sect1 id="naming"><title>Naming Conventions</title>
-
-<para>&gnuradio; uses a set of naming conventions to assist in
-comprehending the code base and gluing C++ and Python together.
-Please follow them.</para>
-
-<sect2 id="camel-case"><title><emphasis>Death to CamelCaseNames!</emphasis></title>
-
-<para>We've returned to a kinder, gentler era.  We're now using the
-&quot;STL style&quot; naming convention with a couple of modifications
-since we're not using namespaces.</para>
-
-<para>With the exception of macros and other constant values, all
-identifiers shall be lower case with <literal>words_separated_like_this</literal>.</para>
-
-<para>Macros and constant values (e.g., enumerated values,
-<literal>static const int FOO = 23</literal>) shall be in <literal>UPPER_CASE</literal>.</para>
-
-</sect2>
-
-<sect2 id="global_names"><title>Global Names</title>
-
-<para>All globally visible names (types, functions, variables, consts, etc)
-shall begin with a "package prefix", followed by an underscore.  The bulk of
-the code in GNU Radio belongs to the "gr" package, hence
-names look like <literal>gr_open_file (...)</literal>.</para>
-
-<para>Large coherent bodies of code may use other package prefixes, but
-let's try to keep them to a well thought out list.  See the list
-below.</para>
-
-</sect2>
-
-<sect2 id="package_prefixes"><title>Package Prefixes</title>
-
-<para>These are the current package prefixes:
-
-<variablelist>
-
-<varlistentry><term>gr_</term>
-<listitem><para>Almost everything.</para></listitem>
-</varlistentry>
-
-<varlistentry><term>gri_</term>
-<listitem><para>
-Implementation primitives.  Sometimes we
-have both a gr_<replaceable>foo</replaceable> and a gri_<replaceable>foo</replaceable>.  In that case,
-gr_<replaceable>foo</replaceable> would be derived from gr_block and gri_<replaceable>foo</replaceable>
-would be the low level guts of the function.</para></listitem>
-</varlistentry>
-
-<varlistentry><term>atsc_</term>
-<listitem><para>Code related to the Advanced Television Standards Committee HDTV implementation
-</para></listitem>
-</varlistentry>
-
-<varlistentry><term>usrp_</term>
-<listitem><para>Universal Software Radio Peripheral.</para></listitem>
-</varlistentry>
-
-<varlistentry><term>qa_</term>
-<listitem><para>Quality Assurance (Test code.)</para></listitem>
-</varlistentry>
-
-</variablelist>
-
-</para>
-</sect2>
-
-<sect2 id="class-data-members"><title>Class Data Members (instance variables)</title>
-
-<para>All class data members shall begin with d_<replaceable>foo</replaceable>.</para>
-
-<para>The big win is when you're staring at a block of code it's obvious
-which of the things being assigned to persist outside of the block.
-This also keeps you from having to be creative with parameter names
-for methods and constructors.  You just use the same name as the
-instance variable, without the d_. </para>
-
-<literallayout>
-class gr_wonderfulness {
-  std::string   d_name;
-  double        d_wonderfulness_factor;
-
-public:
-  gr_wonderfulness (std::string name, double wonderfulness_factor)
-    : d_name (name), d_wonderfulness_factor (wonderfulness_factor)
-  {
-    ...
-  }
-  ...
-};
-</literallayout>
-
-</sect2>
-
-<sect2 id="static-data-members"><title>Class Static Data Members (class variables)</title>
-
-<para>
-All class static data members shall begin with s_<replaceable>foo</replaceable>.
-</para>
-
-</sect2>
-
-<sect2 id="file-names"><title>File Names</title>
-
-<para>Each significant class shall be contained in its own file.  The
-declaration of class <classname>gr_foo</classname> shall be in 
-<filename>gr_foo.h</filename> and the definition in
-<filename>gr_foo.cc</filename>.</para>
-</sect2>
-
-
-<sect2><title>Suffixes</title>
-
-<para>By convention, we encode the input and output types of signal
-processing blocks in their name using suffixes.  The suffix is
-typically one or two characters long.  Source and sinks have single
-character suffixes.  Regular blocks that have both inputs and outputs
-have two character suffixes.  The first character indicates the type
-of the input streams, the second indicates the type of the output
-streams.  FIR filter blocks have a three character suffix, indicating
-the type of the inputs, outputs and taps, respectively.</para>
-
-<para>These are the suffix characters and their interpretations:
-<itemizedlist>
-<listitem><para>f - single precision floating point</para></listitem>
-<listitem><para>c - complex&lt;float&gt;</para></listitem>
-<listitem><para>s - short (16-bit integer)</para></listitem>
-<listitem><para>i - integer (32-bit integer)</para></listitem>
-</itemizedlist>
-</para>
-
-<para>In addition, for those cases where the block deals with streams
-of vectors, we use the character 'v' as the first character of the
-suffix.  An example of this usage is
-<classname>gr_fft_vcc</classname>.  The FFT block takes a vector of
-complex numbers on its input and produces a vector of complex
-numbers on its output.</para>
-
-</sect2>
-
-</sect1>
-
-
-
-
-<sect1 id="square"><title>First Block: &square;</title>
-
-<para>For our first example &well; create a block that computes
-the square of its single float input.  This block will accept a single
-float input stream and produce a single float output stream.</para>
-
-<para>Following the naming conventions, &well; use
-<literal>howto</literal> as our package prefix, and the block will
-be called <classname>howto_square_ff</classname>.</para>
-
-<para>We are going to arrange that this block, as well as the others
-that we write in this article, end up in the
-<literal>gnuradio.howto</literal> Python module.  This will allow us
-to access it from Python like this:
-<programlisting>
-from gnuradio import howto
-sqr = howto.square_ff ()
-</programlisting>
-</para>
-
-
-<sect2 id="test_driven"><title>Test Driven Programming</title>
-
-<para>We could just start banging out the C++ code, but being highly
-evolved modern programmers, &were; going to write the test code first.
-After all, we do have a good spec for the behavior: take a single
-stream of floats as the input and produce a single stream of floats as
-the output. The output should be the square of the input.</para>
-
-<para>How hard could this be?  Turns out that this is easy! Check out 
-<xref linkend="qa_howto_1.py"/>.</para>
-
-<example id="qa_howto_1.py">
-<title><filename>qa_howto.py</filename> (first version)</title>
-&qa_howto_1_listing;
-</example>
-
-<para>
-<classname>gr_unittest</classname> is an extension to the standard
-python module <classname>unittest</classname>.
-<classname>gr_unittest</classname> adds support for checking
-approximate equality of tuples of float and complex numbers.  
-Unittest uses Python&apos;s reflection mechanism to find all methods that start with
-<methodname>test_</methodname> and runs them.  Unittest wraps each call
-to <methodname>test_*</methodname> with matching calls to 
-<methodname>setUp</methodname> and <methodname>tearDown</methodname>.
-See the python <ulink url="http://docs.python.org/lib/module-unittest.html">
-unittest</ulink> documentation for details.
-</para>
-
-<para>When we run the test,
-gr_unittest.main is going to invoke
-<methodname>setUp</methodname>,
-<methodname>test_001_square_ff</methodname>, and
-<methodname>tearDown</methodname>.</para>
-<para>
-<methodname>test_001_square_ff</methodname> builds a small graph that
-contains three nodes.  gr.vector_source_f(src_data) will source the
-elements of src_data and then say that &its; finished.  howto.square_ff is the block
-&were; testing.  gr.vector_sink_f gathers the output of
-howto.square_ff.</para>
-
-<para>The <methodname>run</methodname> method runs the graph until all
-the blocks indicate they are finished.  Finally, we check that the
-result of executing square_ff on src_data matches what we expect.
-</para>
-
-</sect2>
-
-<sect2 id="build_vs_install"><title>Build Tree vs. Install Tree</title>
-
-<para>The build tree is everything from <replaceable>topdir</replaceable>
-(the one containing configure.ac) down.  The path to the install tree is
-<filename>
-<replaceable>prefix</replaceable>/lib/python<replaceable>version</replaceable>/site-packages</filename>,
-where <replaceable>prefix</replaceable> is the <literal>--prefix</literal>
-argument to configure (default <filename>/usr/local</filename>) and 
-<replaceable>version</replaceable> is the installed version of
-python. A typical value is 
-<filename>/usr/local/lib/python2.3/site-packages</filename>.</para>
-
-
-<para>We normally set our PYTHONPATH environment variable to point at
-the install tree, and do this in <filename>~/.bash_profile</filename> 
-or <filename>~/.profile</filename>.
-This allows our python apps to access all the standard python
-libraries, plus our locally installed stuff like GNU Radio.</para>
-
-<para>We write our applications such that they access the code and
-libraries in the install tree.  On the other hand, we want our test
-code to run on the build tree, where we can detect problems before
-installation.</para>
-
-</sect2>
-
-<sect2 id="make_check"><title>make check</title>
-
-
-<para>We use <command>make check</command> to run our tests.
-Make check invokes the <command>run_tests</command> shell script which 
-sets up the PYTHONPATH environment variable so that 
-our tests use the build tree versions of our code and libraries.
-It then runs all files
-which have names of the form <filename>qa_*.py</filename> and reports
-the overall success or failure.</para>
-
-<para>There is quite a bit of behind-the-scenes action required to use
-the non-installed versions of our code (look at
-<filename>runtest</filename> for a cheap thrill.)</para>
-
-<para>Finally, running <command>make check</command> in the python
-directory produces this result:
-<literallayout>
-  [eb@bufo python]$ make check
-  make  check-TESTS
-  make[1]: Entering directory `/home/eb/gr-build/gr-howto-write-a-block/src/python'
-  Traceback (most recent call last):
-    File "./qa_howto.py", line 24, in ?
-      import howto
-  ImportError: No module named howto
-  Traceback (most recent call last):
-    File "./qa_howto_1.py", line 24, in ?
-      import howto
-  ImportError: No module named howto
-  FAIL: run_tests
-  ===================
-  1 of 1 tests failed
-  ===================
-  make[1]: *** [check-TESTS] Error 1
-  make[1]: Leaving directory `/home/eb/gr-build/gr-howto-write-a-block/src/python'
-  make: *** [check-am] Error 2
-  [eb@bufo python]$
-</literallayout>
-Excellent!  Our test failed, just as we expected.  The ImportError
-indicates that it can't find the module named
-<classname>howto</classname>.  No surprise, since we haven't written it yet.
-</para>
-
-</sect2>
-
-<sect2><title>The C++ code</title>
-<para>Now that we've got a test case written that successfully fails,
-let's write the C++ code.  As we mentioned earlier, all signal
-processing blocks are derived from <classname>gr_block</classname> or
-one of its subclasses.  Let's take a look at 
-<xref linkend="gr_block.h"/>.</para>
-
-<example id="gr_block.h">
-<title><filename>gr_block.h</filename></title>
-&gr_block_listing;
-</example>
-
-<para>A quick scan of <filename>gr_block.h</filename> reveals that
-since <methodname>general_work</methodname> is pure virtual, we
-definitely need to override that. 
-<methodname>general_work</methodname> is the method that does the
-actual signal processing.  For our squaring example we'll
-need to override <methodname>general_work</methodname> and provide a
-constructor and destructor and a bit of stuff to take advantage of
-the <ulink url="http://www.boost.org">boost</ulink>
-<ulink url="http://www.boost.org/libs/smart_ptr/smart_ptr.htm">
-<classname>shared_ptr</classname>s.</ulink>
-
-</para>
-
-
-<para><xref linkend="howto_square_ff.h"/> 
-and <xref linkend="howto_square_ff.cc"/> are the header and c++
-source.</para>
-
-<example id="howto_square_ff.h">
-<title><filename>howto_square_ff.h</filename></title>
-&howto_square_ff_h_listing;
-</example>
-
-<example id="howto_square_ff.cc">
-<title><filename>howto_square_ff.cc</filename></title>
-&howto_square_ff_cc_listing;
-</example>
-
-<para>Now we need a Makefile.am to get all this to build.  
-<xref linkend="src_lib_Makefile_1"/> 
-is enough to build a shared library from our source file.  We'll be
-adding additional rules to use &SWIG; in just a bit.  If you haven't
-already, this is a good time to browse all the Makefile.am&apos;s in
-the build tree and get an idea for how it all hangs together.</para>
-
-<example id="src_lib_Makefile_1">
-<title><filename>src/lib/Makefile.am</filename> (no &SWIG;)</title>
-&src_lib_Makefile_1_am_listing;
-</example>
-
-</sect2>
-
-
-<!-- ==============================
-
-<sect2 id="io_sig"><title><classname>gr_io_signature</classname></title>
-<para></para>
-</sect2>
-
-<sect2 id="forecast"><title><methodname>forecast</methodname></title>
-<para></para>
-</sect2>
-
-<sect2 id="output_multiple">
-<title><methodname>set_output_multiple</methodname></title>
-<para></para>
-</sect2>
-
-  ============================== -->
-
-
-<sect2 id="swig"><title>The &SWIG; .i file</title> 
-
-<para>Now that we've got something that will compile, we need to write
-the &SWIG; .i file.  This is a pared-down version of the .h file, plus
-a bit of magic that has python work with the boost shared_ptr&apos;s.
-To reduce code bloat, we only declare methods that &well; want to
-access from Python.</para>
-
-<para>We&apos;re going to call the .i file
-<filename>howto.i</filename>, and use it to hold the &SWIG;
-declarations for all classes from <literal>howto</literal> that will
-be accessible from python.  It&apos;s quite small:
-&howto_1_i_listing;
-</para>
-
-</sect2>
-
-<sect2><title>Putting it all together</title>
-<para>
-Now we need to modify <filename>src/lib/Makefile.am</filename>
-to run &SWIG; and to add the glue it generates to the shared library.</para>
-
-<example id="src_lib_Makefile_2">
-<title><filename>src/lib/Makefile.am</filename> (with &SWIG;)</title>
-&src_lib_Makefile_2_am_listing;
-</example>
-
-<para><command>make</command> now builds everything successfully.  We get a
-few warnings, but &thats; OK.</para>
-
-<para>Changing directories back to the python directory we try
-<command>make check</command> again:
-<literallayout>
-  [eb@bufo python]$ make check
-  make  check-TESTS
-  make[1]: Entering directory `/home/eb/gr-build/gr-howto-write-a-block/src/python'
-  .
-  ----------------------------------------------------------------------
-  Ran 1 test in 0.004s
-  
-  OK
-  PASS: run_tests
-  ==================
-  All 1 tests passed
-  ==================
-  make[1]: Leaving directory `/home/eb/gr-build/gr-howto-write-a-block/src/python'
-  [eb@bufo python]$
-</literallayout>
-<emphasis>Victory! Our new block works!</emphasis>
-</para>
-
-</sect2>
-
-</sect1><!-- end First Block: square -->
-
-<sect1 id="additional_methods"><title>Additional gr_block methods</title>
-
-<para>In our <classname>howto_square_ff</classname> example above, we only
-had to override the <methodname>general_work</methodname> method to
-accomplish our goal.  <classname>gr_block</classname> provides a few other
-methods that are sometimes useful.</para>
-
-<sect2 id="forecast"><title>forecast</title>
-
-<para>Looking at <methodname>general_work</methodname> you may
-have wondered how the system knows how much data it needs to
-ensure is valid in each of the input arrays.  The
-<methodname>forecast</methodname> method provides this
-information.</para>
-
-<para>The default implementation of <methodname>forecast</methodname>
-says there is a 1:1 relationship between noutput_items and the
-requirements for each input stream.  The size of the items is defined by
-<classname>gr_io_signature</classname>s in the constructor of
-<classname>gr_block</classname>. The sizes of the input and output items
-can of course differ; this still qualifies as a 1:1 relationship.
-<programlisting>
-  // default implementation:  1:1
-
-  void
-  gr_block::forecast (int noutput_items,
-                      gr_vector_int &amp;ninput_items_required)
-  {
-    unsigned ninputs = ninput_items_required.size ();
-    for (unsigned i = 0; i &lt; ninputs; i++)
-      ninput_items_required[i] = noutput_items;
-  }
-</programlisting>
-</para>
-
-<para>Although the 1:1 implementation worked for howto_square_ff, it
-wouldn&apos;t be appropriate for interpolators, decimators, or blocks
-with a more complicated relationship between noutput_items and the
-input requirements.  That said, by deriving your classes from
-<classname>gr_sync_block</classname>,
-<classname>gr_sync_interpolator</classname> or
-<classname>gr_sync_decimator</classname> instead of
-<classname>gr_block</classname>, you can often avoid
-implementing <methodname>forecast</methodname>.</para>
-
-</sect2>
-
-<sect2 id="set_output_multiple"><title>set_output_multiple</title>
-
-<para>When implementing your <methodname>general_work</methodname>
-routine, &its; occasionally convenient to have the run time system
-ensure that you are only asked to produce a number of output items
-that is a multiple of some particular value.  This might occur if your
-algorithm naturally applies to a fixed sized block of data. 
-Call <methodname>set_output_multiple</methodname> in your constructor
-to specify this requirement. The default output multiple is 1.</para>
-
-</sect2>
-
-</sect1>
-
-
-<sect1 id="common_patterns">
-<title>Subclasses for common patterns</title>
-
-<para><classname>gr_block</classname> allows tremendous flexibility
-with regard to the consumption of input streams and the production of
-output streams.  Adroit use of <methodname>forecast</methodname> and
-<methodname>consume</methodname> allows variable rate blocks to be
-built.  It is possible to construct blocks that consume data at
-different rates on each input, and produce output at a rate that
-is a function of the contents of the input data.</para>
-
-<para>On the other hand, it is very common for signal processing
-blocks to have a fixed relationship between the input rate and the
-output rate.  Many are 1:1, while others have 1:N or N:1
-relationships.</para>
-
-<para>Another common requirement is the need to examine more than one
-input sample to produce a single output sample.  This is orthogonal to
-the relationship between input and output rate.  For example, a
-non-decimating, non-interpolating FIR filter needs to examine N input
-samples for each output sample it produces, where N is the number of
-taps in the filter.  However, it only consumes a single input sample
-to produce a single output.  We call this concept "history", but you
-could also think of it as "look-ahead".</para>
-
-<sect2 id="gr_sync_block"><title><classname>gr_sync_block</classname></title>
-
-<para>
-<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__block.html">
-<classname>gr_sync_block</classname></ulink>
-is derived from
-<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__block.html">
-<classname>gr_block</classname></ulink>
-and implements a 1:1 block with
-optional history.  Given that we know the input to output rate,
-certain simplifications are possible.  From the implementor&apos;s
-point-of-view, the primary change is that we define a
-<methodname>work</methodname> method instead of
-<methodname>general_work</methodname>.  <methodname>work</methodname>
-has a slightly different calling sequence;
-It omits the unnecessary ninput_items parameter, and arranges for
-<methodname>consume_each</methodname> to be called on our
-behalf.</para>
-<programlisting>
-  /*!
-   * \brief Just like gr_block::general_work, only this arranges to
-   *  call consume_each for you.
-   *
-   * The user must override work to define the signal processing code
-   */
-  virtual int work (int noutput_items,
-                    gr_vector_const_void_star &amp;input_items,
-                    gr_vector_void_star &amp;output_items) = 0;
-</programlisting>
-
-<para>This gives us fewer things to worry about, and less code to
-write.  If the block requires history greater than 1, call
-<methodname>set_history</methodname> in the constructor, or any time
-the requirement changes.</para>
-
-<para><classname>gr_sync_block</classname> provides a
-version of <methodname>forecast</methodname> that handles the
-history requirement.</para>
-
-</sect2>
-
-<sect2 id="gr_sync_decimator"><title><classname>gr_sync_decimator</classname></title>
-
-<para>
-<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__decimator.html">
-<classname>gr_sync_decimator</classname></ulink>
-is derived from
-<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__block.html">
-<classname>gr_sync_block</classname></ulink>
-and implements a N:1 block with optional history.  
-</para>
-
-</sect2>
-
-<sect2 id="gr_sync_interpolator"><title><classname>gr_sync_interpolator</classname></title>
-
-<para>
-<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__interpolator.html">
-<classname>gr_sync_interpolator</classname></ulink>
-is derived from
-<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__block.html">
-<classname>gr_sync_block</classname></ulink>
-and implements a 1:N block with optional history.  
-</para>
-
-</sect2>
-
-
-</sect1>
-
-<sect1 id="square2">
-<title>Second Block: <classname>howto_square2_ff</classname></title>
-
-<para>Given that we now know about
-<classname>gr_sync_block</classname>, the way 
-<classname>howto_square_ff</classname> should really be implemented is
-by subclassing <classname>gr_sync_block</classname>.</para>
-
-<para>Here are the revised sources: <xref
-linkend="howto_square2_ff.h"/>, 
-<xref linkend="howto_square2_ff.cc"/>.  
-The accompanying files contain the additional test code.
-</para>
-
-<example id="howto_square2_ff.h">
-<title><filename>howto_square2_ff.h</filename></title>
-&howto_square2_ff_h_listing;
-</example>
-
-<example id="howto_square2_ff.cc">
-<title><filename>howto_square2_ff.cc</filename></title>
-&howto_square2_ff_cc_listing;
-</example>
-
-</sect1>
-
-<sect1 id="where_to"><title>Where to from Here?</title>
-
-<para>At this point, we&apos;ve got a basic overview of how the system
-goes together.  For more insight, I suggest that you look at the code
-of the system.  The doxygen generated <ulink
-url="http://www.gnu.org/software/gnuradio/doc/hierarchy.html"> class
-hierarchy</ulink> is a useful way to find things that might interest
-you.</para>
-
-</sect1>
-
-
-<sect1 id="tips"><title>Miscellaneous Tips</title>
-
-<sect2 id="sources_and_sinks"><title>Sources and Sinks</title>
-
-<para>Sources and sinks are derived from
-<classname>gr_sync_block</classname>.  The only thing different about
-them is that sources have no inputs and sinks have no outputs.  This
-is reflected in the <classname>gr_io_signature</classname>s that are
-passed to the <classname>gr_sync_block</classname> constructor.
-Take a look at <filename>gr_file_source.{h,cc}</filename> and
-<filename>gr_file_sink.{h,cc}</filename> for some very straight-forward examples.
-</para>
-
-</sect2>
-
-<sect2 id="debugging">
-<title>Debugging with <application>gdb</application></title>
-
-<para>If your block isn&apos;t working, and you can&apos;t sort it
-out through python test cases or a few printfs in the code, you may want to
-use <application>gdb</application> to debug it.  The trick of course
-is that all of &gnuradio;, including your new block, is dynamically
-loaded into python for execution.</para>
-
-<para>Try this:  In your python test code, after the relevant imports,
-print out the process id and wait for a keystroke.  In another
-window run gdb and tell it to attach to the python process with the
-given process id.  At this point you can set breakpoints or whatever
-in your code.  Go back to the python window and hit Enter so
-it&apos;ll continue.</para>
-
-<programlisting>
-  #!/usr/bin/env python
-  from gnuradio import gr
-  from gnuradio import my_buggy_module
-
-  # insert this in your test code...
-  import os
-  print 'Blocked waiting for GDB attach (pid = %d)' % (os.getpid(),)
-  raw_input ('Press Enter to continue: ')
-  # remainder of your test code follows...
-</programlisting>
-
-<para>Another SNAFU you might run into is that gdb 6.2 isn&apos;t
-able to set breakpoints in the constructors or destructors generated
-by g++ 3.4.  In this case, insert a call to the nop function
-gri_debugger_hook in the constructor and recompile.  Load the code as
-before and set a break point on gri_debugger_hook.</para>
-
-</sect2>
-
-<sect2 id="oprofile">
-<title>Performance Measurement with <application>oprofile</application></title>
-<para>Oprofile is your friend.  
-See <ulink url="http://oprofile.sourceforge.net">http://oprofile.sourceforge.net</ulink>.
-</para>
-</sect2>
-
-</sect1><!-- end tips -->
-
-<sect1 id="futures"><title>Coming Attractions</title>
-<para></para>
-
-<sect2 id="types"><title>Improved Type System</title>
-<para></para>
-</sect2>
-
-<sect2 id="hierarchy"><title>Hierarchical Blocks</title>
-<para></para>
-</sect2>
-
-</sect1><!-- end Coming Attractions -->
-
-</article>
diff --git a/gr-howto-write-a-block/doc/howto_1.i b/gr-howto-write-a-block/doc/howto_1.i
deleted file mode 100644 (file)
index 640d089..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* -*- c++ -*- */
-
-%include "exception.i"
-%import "gnuradio.i"                           // the common stuff
-
-%{
-#include "gnuradio_swig_bug_workaround.h"      // mandatory bug fix
-#include "howto_square_ff.h"
-#include <stdexcept>
-%}
-
-// ----------------------------------------------------------------
-
-/*
- * First arg is the package prefix.
- * Second arg is the name of the class minus the prefix.
- *
- * This does some behind-the-scenes magic so we can
- * access howto_square_ff from python as howto.square_ff
- */
-GR_SWIG_BLOCK_MAGIC(howto,square_ff);
-
-howto_square_ff_sptr howto_make_square_ff ();
-
-class howto_square_ff : public gr_block
-{
-private:
-  howto_square_ff ();
-};
diff --git a/gr-howto-write-a-block/doc/make_numbered_listing.py b/gr-howto-write-a-block/doc/make_numbered_listing.py
deleted file mode 100755 (executable)
index 889c2d7..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-import os, os.path
-from optparse import OptionParser
-
-def quote_line (line):
-    line = line.replace ('&', '&amp;')
-    line = line.replace ('<', '&lt;')
-    line = line.replace ('>', '&gt;')
-    line = line.replace ("'", '&apos;')
-    line = line.replace ('"', '&quot;')
-    return line
-
-def generate_listing (input_filename, title=None):
-    inf = open (input_filename, "r")
-    output_filename = os.path.basename (input_filename) + '.xml'
-    outf = open (output_filename, "w")
-    outf.write ('<?xml version="1.0" encoding="ISO-8859-1"?>\n')
-    # outf.write ('<example id="%s">\n' % (input_filename,))
-    # if not title:
-    #     title = input_filename
-    # outf.write ('<title>')
-    # outf.write (title)
-    # outf.write ('</title>\n')
-    outf.write ('<programlisting>\n');
-
-    lineno = 0
-    for line in inf:
-        line = line.expandtabs (8)
-        line = quote_line (line)
-        lineno = lineno + 1
-        outf.write ('%3d  %s' % (lineno, line))
-
-    outf.write ('</programlisting>\n')
-    # outf.write ('</example>\n')
-
-
-def main ():
-    for file in sys.argv[1:]:
-        generate_listing (file)
-
-if __name__ == '__main__':
-    main ()
-    
diff --git a/gr-howto-write-a-block/doc/qa_howto_1.py b/gr-howto-write-a-block/doc/qa_howto_1.py
deleted file mode 100755 (executable)
index 3173110..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python
-
-from gnuradio import gr, gr_unittest
-import howto
-
-class qa_howto (gr_unittest.TestCase):
-
-    def setUp (self):
-        self.tb = gr.top_block ()
-
-    def tearDown (self):
-        self.tb = None
-
-    def test_001_square_ff (self):
-        src_data = (-3, 4, -5.5, 2, 3)
-        expected_result = (9, 16, 30.25, 4, 9)
-        src = gr.vector_source_f (src_data)
-        sqr = howto.square_ff ()
-        dst = gr.vector_sink_f ()
-        self.tb.connect (src, sqr)
-        self.tb.connect (sqr, dst)
-        self.tb.run ()
-        result_data = dst.data ()
-        self.assertFloatTuplesAlmostEqual (expected_result, result_data, 6)
-        
-if __name__ == '__main__':
-    gr_unittest.main ()
diff --git a/gr-howto-write-a-block/doc/src_lib_Makefile_1.am b/gr-howto-write-a-block/doc/src_lib_Makefile_1.am
deleted file mode 100644 (file)
index e97d70d..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-include $(top_srcdir)/Makefile.common
-
-# Install this stuff so that it ends up as the gnuradio.howto module
-# This usually ends up at:
-#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
-
-ourpythondir = $(grpythondir)
-ourlibdir    = $(grpyexecdir)
-
-INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES)
-
-ourlib_LTLIBRARIES = _howto.la
-
-# These are the source files that go into the shared library
-_howto_la_SOURCES =                    \
-       howto_square_ff.cc              
-
-# magic flags
-_howto_la_LDFLAGS = -module -avoid-version
-
-# These headers get installed in ${prefix}/include/gnuradio
-grinclude_HEADERS =                    \
-       howto_square_ff.h               
-
-MOSTLYCLEANFILES = $(BUILT_SOURCES) *.pyc
diff --git a/gr-howto-write-a-block/doc/src_lib_Makefile_2.am b/gr-howto-write-a-block/doc/src_lib_Makefile_2.am
deleted file mode 100644 (file)
index dca236e..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-#
-# Copyright 2004,2008 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
-
-# Install this stuff so that it ends up as the gnuradio.howto module
-# This usually ends up at:
-#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
-
-ourpythondir = $(grpythondir)
-ourlibdir    = $(grpyexecdir)
-
-INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES)
-
-SWIGCPPPYTHONARGS = -noruntime -c++ -python $(PYTHON_CPPFLAGS) \
-       -I$(swigincludedir) -I$(grincludedir) $(WITH_SWIG_INCLUDES)
-
-ALL_IFILES =                           \
-       $(LOCAL_IFILES)                 \
-       $(NON_LOCAL_IFILES)             
-
-NON_LOCAL_IFILES =                     \
-       $(GNURADIO_CORE_INCLUDEDIR)/swig/gnuradio.i
-
-
-LOCAL_IFILES =                                 \
-       howto.i                         
-
-# These files are built by SWIG.  The first is the C++ glue.
-# The second is the python wrapper that loads the _howto shared library
-# and knows how to call our extensions.
-
-BUILT_SOURCES =                        \
-       howto.cc                        \
-       howto.py                                
-
-# This gets howto.py installed in the right place
-ourpython_PYTHON =                     \
-       howto.py
-
-ourlib_LTLIBRARIES = _howto.la
-
-# These are the source files that go into the shared library
-_howto_la_SOURCES =                    \
-       howto.cc                        \
-       howto_square_ff.cc              
-
-# magic flags
-_howto_la_LDFLAGS = -module -avoid-version
-
-# link the library against some comon swig runtime code and the 
-# c++ standard library
-_howto_la_LIBADD =                     \
-       -lgrswigrunpy                   \
-       -lstdc++                        
-
-howto.cc howto.py: howto.i $(ALL_IFILES)
-       $(SWIG) $(SWIGCPPPYTHONARGS) -module howto -o howto.cc $<
-
-# These headers get installed in ${prefix}/include/gnuradio
-grinclude_HEADERS =                    \
-       howto_square_ff.h               
-
-# These swig headers get installed in ${prefix}/include/gnuradio/swig
-swiginclude_HEADERS =                  \
-       $(LOCAL_IFILES)
-
-MOSTLYCLEANFILES = $(BUILT_SOURCES) *.pyc
diff --git a/gr-howto-write-a-block/lib/.gitignore b/gr-howto-write-a-block/lib/.gitignore
new file mode 100644 (file)
index 0000000..d957a68
--- /dev/null
@@ -0,0 +1,11 @@
+/Makefile
+/Makefile.in
+/.la
+/.lo
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/howto.cc
+/howto.py
diff --git a/gr-howto-write-a-block/lib/Makefile.am b/gr-howto-write-a-block/lib/Makefile.am
new file mode 100644 (file)
index 0000000..e553c19
--- /dev/null
@@ -0,0 +1,42 @@
+#
+# Copyright 2004,2005,2006,2008,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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+###################################
+# howto C++ library
+
+# C/C++ headers get installed in ${prefix}/include/gnuradio
+grinclude_HEADERS =            \
+       howto_square_ff.h       \
+       howto_square2_ff.h
+
+lib_LTLIBRARIES = libgnuradio-howto.la
+
+libgnuradio_howto_la_SOURCES =         \
+       howto_square_ff.cc      \
+       howto_square2_ff.cc
+
+libgnuradio_howto_la_LIBADD =  \
+       $(GNURADIO_CORE_LA)
+
+libgnuradio_howto_la_LDFLAGS = \
+       $(NO_UNDEFINED)
diff --git a/gr-howto-write-a-block/lib/howto_square2_ff.cc b/gr-howto-write-a-block/lib/howto_square2_ff.cc
new file mode 100644 (file)
index 0000000..e86db93
--- /dev/null
@@ -0,0 +1,92 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 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.
+ */
+
+/*
+ * config.h is generated by configure.  It contains the results
+ * of probing for features, options etc.  It should be the first
+ * file included in your .cc file.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <howto_square2_ff.h>
+#include <gr_io_signature.h>
+
+/*
+ * Create a new instance of howto_square2_ff and return
+ * a boost shared_ptr.  This is effectively the public constructor.
+ */
+howto_square2_ff_sptr 
+howto_make_square2_ff ()
+{
+  return howto_square2_ff_sptr (new howto_square2_ff ());
+}
+
+/*
+ * Specify constraints on number of input and output streams.
+ * This info is used to construct the input and output signatures
+ * (2nd & 3rd args to gr_block's constructor).  The input and
+ * output signatures are used by the runtime system to
+ * check that a valid number and type of inputs and outputs
+ * are connected to this block.  In this case, we accept
+ * only 1 input and 1 output.
+ */
+static const int MIN_IN = 1;   // mininum number of input streams
+static const int MAX_IN = 1;   // maximum number of input streams
+static const int MIN_OUT = 1;  // minimum number of output streams
+static const int MAX_OUT = 1;  // maximum number of output streams
+
+/*
+ * The private constructor
+ */
+howto_square2_ff::howto_square2_ff ()
+  : gr_sync_block ("square2_ff",
+                  gr_make_io_signature (MIN_IN, MAX_IN, sizeof (float)),
+                  gr_make_io_signature (MIN_OUT, MAX_OUT, sizeof (float)))
+{
+  // nothing else required in this example
+}
+
+/*
+ * Our virtual destructor.
+ */
+howto_square2_ff::~howto_square2_ff ()
+{
+  // nothing else required in this example
+}
+
+int 
+howto_square2_ff::work (int noutput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items)
+{
+  const float *in = (const float *) input_items[0];
+  float *out = (float *) output_items[0];
+
+  for (int i = 0; i < noutput_items; i++){
+    out[i] = in[i] * in[i];
+  }
+
+  // Tell runtime system how many output items we produced.
+  return noutput_items;
+}
diff --git a/gr-howto-write-a-block/lib/howto_square2_ff.h b/gr-howto-write-a-block/lib/howto_square2_ff.h
new file mode 100644 (file)
index 0000000..536b04f
--- /dev/null
@@ -0,0 +1,77 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 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_HOWTO_SQUARE2_FF_H
+#define INCLUDED_HOWTO_SQUARE2_FF_H
+
+#include <gr_sync_block.h>
+
+class howto_square2_ff;
+
+/*
+ * We use boost::shared_ptr's instead of raw pointers for all access
+ * to gr_blocks (and many other data structures).  The shared_ptr gets
+ * us transparent reference counting, which greatly simplifies storage
+ * management issues.  This is especially helpful in our hybrid
+ * C++ / Python system.
+ *
+ * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
+ *
+ * As a convention, the _sptr suffix indicates a boost::shared_ptr
+ */
+typedef boost::shared_ptr<howto_square2_ff> howto_square2_ff_sptr;
+
+/*!
+ * \brief Return a shared_ptr to a new instance of howto_square2_ff.
+ *
+ * To avoid accidental use of raw pointers, howto_square2_ff's
+ * constructor is private.  howto_make_square2_ff is the public
+ * interface for creating new instances.
+ */
+howto_square2_ff_sptr howto_make_square2_ff ();
+
+/*!
+ * \brief square2 a stream of floats.
+ * \ingroup block
+ *
+ * This uses the preferred technique: subclassing gr_sync_block.
+ */
+class howto_square2_ff : public gr_sync_block
+{
+private:
+  // The friend declaration allows howto_make_square2_ff to
+  // access the private constructor.
+
+  friend howto_square2_ff_sptr howto_make_square2_ff ();
+
+  howto_square2_ff ();         // private constructor
+
+ public:
+  ~howto_square2_ff ();        // public destructor
+
+  // Where all the action really happens
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_HOWTO_SQUARE2_FF_H */
diff --git a/gr-howto-write-a-block/lib/howto_square_ff.cc b/gr-howto-write-a-block/lib/howto_square_ff.cc
new file mode 100644 (file)
index 0000000..5ab45d1
--- /dev/null
@@ -0,0 +1,98 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 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.
+ */
+
+/*
+ * config.h is generated by configure.  It contains the results
+ * of probing for features, options etc.  It should be the first
+ * file included in your .cc file.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <howto_square_ff.h>
+#include <gr_io_signature.h>
+
+/*
+ * Create a new instance of howto_square_ff and return
+ * a boost shared_ptr.  This is effectively the public constructor.
+ */
+howto_square_ff_sptr 
+howto_make_square_ff ()
+{
+  return howto_square_ff_sptr (new howto_square_ff ());
+}
+
+/*
+ * Specify constraints on number of input and output streams.
+ * This info is used to construct the input and output signatures
+ * (2nd & 3rd args to gr_block's constructor).  The input and
+ * output signatures are used by the runtime system to
+ * check that a valid number and type of inputs and outputs
+ * are connected to this block.  In this case, we accept
+ * only 1 input and 1 output.
+ */
+static const int MIN_IN = 1;   // mininum number of input streams
+static const int MAX_IN = 1;   // maximum number of input streams
+static const int MIN_OUT = 1;  // minimum number of output streams
+static const int MAX_OUT = 1;  // maximum number of output streams
+
+/*
+ * The private constructor
+ */
+howto_square_ff::howto_square_ff ()
+  : gr_block ("square_ff",
+             gr_make_io_signature (MIN_IN, MAX_IN, sizeof (float)),
+             gr_make_io_signature (MIN_OUT, MAX_OUT, sizeof (float)))
+{
+  // nothing else required in this example
+}
+
+/*
+ * Our virtual destructor.
+ */
+howto_square_ff::~howto_square_ff ()
+{
+  // nothing else required in this example
+}
+
+int 
+howto_square_ff::general_work (int noutput_items,
+                              gr_vector_int &ninput_items,
+                              gr_vector_const_void_star &input_items,
+                              gr_vector_void_star &output_items)
+{
+  const float *in = (const float *) input_items[0];
+  float *out = (float *) output_items[0];
+
+  for (int i = 0; i < noutput_items; i++){
+    out[i] = in[i] * in[i];
+  }
+
+  // Tell runtime system how many input items we consumed on
+  // each input stream.
+
+  consume_each (noutput_items);
+
+  // Tell runtime system how many output items we produced.
+  return noutput_items;
+}
diff --git a/gr-howto-write-a-block/lib/howto_square_ff.h b/gr-howto-write-a-block/lib/howto_square_ff.h
new file mode 100644 (file)
index 0000000..092b936
--- /dev/null
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 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_HOWTO_SQUARE_FF_H
+#define INCLUDED_HOWTO_SQUARE_FF_H
+
+#include <gr_block.h>
+
+class howto_square_ff;
+
+/*
+ * We use boost::shared_ptr's instead of raw pointers for all access
+ * to gr_blocks (and many other data structures).  The shared_ptr gets
+ * us transparent reference counting, which greatly simplifies storage
+ * management issues.  This is especially helpful in our hybrid
+ * C++ / Python system.
+ *
+ * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
+ *
+ * As a convention, the _sptr suffix indicates a boost::shared_ptr
+ */
+typedef boost::shared_ptr<howto_square_ff> howto_square_ff_sptr;
+
+/*!
+ * \brief Return a shared_ptr to a new instance of howto_square_ff.
+ *
+ * To avoid accidental use of raw pointers, howto_square_ff's
+ * constructor is private.  howto_make_square_ff is the public
+ * interface for creating new instances.
+ */
+howto_square_ff_sptr howto_make_square_ff ();
+
+/*!
+ * \brief square a stream of floats.
+ * \ingroup block
+ *
+ * \sa howto_square2_ff for a version that subclasses gr_sync_block.
+ */
+class howto_square_ff : public gr_block
+{
+private:
+  // The friend declaration allows howto_make_square_ff to
+  // access the private constructor.
+
+  friend howto_square_ff_sptr howto_make_square_ff ();
+
+  howto_square_ff ();          // private constructor
+
+ public:
+  ~howto_square_ff (); // public destructor
+
+  // Where all the action really happens
+
+  int general_work (int noutput_items,
+                   gr_vector_int &ninput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_HOWTO_SQUARE_FF_H */
diff --git a/gr-howto-write-a-block/limbo/doc/.gitignore b/gr-howto-write-a-block/limbo/doc/.gitignore
new file mode 100644 (file)
index 0000000..f65ab6c
--- /dev/null
@@ -0,0 +1,18 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/autom4te.cache
+/*.cache
+/howto-write-a-block.html
+/gr_block.h.xml
+/howto_1.i.xml
+/howto_square_ff.cc.xml
+/howto_square_ff.h.xml
+/qa_howto_1.py.xml
+/src_lib_Makefile_1.am.xml
+/src_lib_Makefile_2.am.xml
+/howto_square2_ff.cc.xml
+/howto_square2_ff.h.xml
diff --git a/gr-howto-write-a-block/limbo/doc/Makefile.am b/gr-howto-write-a-block/limbo/doc/Makefile.am
new file mode 100644 (file)
index 0000000..5f58a21
--- /dev/null
@@ -0,0 +1,81 @@
+#
+# Copyright 2004,2005,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 GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+TARGETS = howto-write-a-block.html
+
+# To avoid build problems for folks who don't have xmlto installed, we
+# don't build the docs by default.
+
+# html: $(TARGETS)
+all: $(TARGETS)
+
+
+EXTRA_DIST =                           \
+       README                          \
+       howto-write-a-block.xml         \
+       howto_1.i                       \
+       make_numbered_listing.py        \
+       qa_howto_1.py                   \
+       src_lib_Makefile_1.am           \
+       src_lib_Makefile_2.am           
+
+
+BUILT_XML_FILES =                      \
+       gr_block.h.xml                  \
+       howto_1.i.xml                   \
+       howto_square_ff.cc.xml          \
+       howto_square_ff.h.xml           \
+       howto_square2_ff.cc.xml         \
+       howto_square2_ff.h.xml          \
+       qa_howto_1.py.xml               \
+       src_lib_Makefile_1.am.xml       \
+       src_lib_Makefile_2.am.xml       
+
+
+howto-write-a-block.html : howto-write-a-block.xml $(BUILT_XML_FILES)
+
+
+gr_block.h.xml: $(GNURADIO_CORE_INCLUDEDIR)/gr_block.h make_numbered_listing.py
+       $(PYTHON) ./make_numbered_listing.py $(GNURADIO_CORE_INCLUDEDIR)/gr_block.h
+
+howto_square_ff.cc.xml: $(top_srcdir)/src/lib/howto_square_ff.cc make_numbered_listing.py
+       $(PYTHON) ./make_numbered_listing.py $(top_srcdir)/src/lib/howto_square_ff.cc 
+
+howto_square_ff.h.xml: $(top_srcdir)/src/lib/howto_square_ff.h make_numbered_listing.py
+       $(PYTHON) ./make_numbered_listing.py $(top_srcdir)/src/lib/howto_square_ff.h 
+
+howto_square2_ff.cc.xml: $(top_srcdir)/src/lib/howto_square2_ff.cc make_numbered_listing.py
+       $(PYTHON) ./make_numbered_listing.py $(top_srcdir)/src/lib/howto_square2_ff.cc 
+
+howto_square2_ff.h.xml: $(top_srcdir)/src/lib/howto_square2_ff.h make_numbered_listing.py
+       $(PYTHON) ./make_numbered_listing.py $(top_srcdir)/src/lib/howto_square2_ff.h 
+
+
+# ----------------------------------------------------------------
+
+clean:
+       -${RM} -f $(TARGETS) $(BUILT_XML_FILES)
+
+%.html : %.xml
+       xmlto html-nochunks $<
+
+%.xml : % make_numbered_listing.py
+       $(PYTHON) ./make_numbered_listing.py $<
diff --git a/gr-howto-write-a-block/limbo/doc/README b/gr-howto-write-a-block/limbo/doc/README
new file mode 100644 (file)
index 0000000..ff3b75e
--- /dev/null
@@ -0,0 +1 @@
+The contents of this directory are obsolete.
diff --git a/gr-howto-write-a-block/limbo/doc/howto-write-a-block.xml b/gr-howto-write-a-block/limbo/doc/howto-write-a-block.xml
new file mode 100644 (file)
index 0000000..f8027b4
--- /dev/null
@@ -0,0 +1,959 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+          "docbookx.dtd" [
+  <!ENTITY gnuradio "<application>GNU Radio</application>">
+  <!ENTITY SWIG "<application>SWIG</application>">
+  <!ENTITY gr_block "<classname>gr_block</classname>">
+  <!ENTITY square "<classname>howto_square_ff</classname>">
+
+  <!ENTITY were "we&apos;re">
+  <!ENTITY well "we&apos;ll">
+  <!ENTITY thats "that&apos;s">
+  <!ENTITY its "it&apos;s">
+  <!ENTITY lets "let&apos;s">
+  <!ENTITY youre "you&apos;re">
+
+  <!ENTITY gr_block_listing SYSTEM "gr_block.h.xml">
+  <!ENTITY qa_howto_1_listing SYSTEM "qa_howto_1.py.xml">
+  <!ENTITY howto_square_ff_h_listing SYSTEM "howto_square_ff.h.xml">
+  <!ENTITY howto_square_ff_cc_listing SYSTEM "howto_square_ff.cc.xml">
+  <!ENTITY howto_square2_ff_h_listing SYSTEM "howto_square2_ff.h.xml">
+  <!ENTITY howto_square2_ff_cc_listing SYSTEM "howto_square2_ff.cc.xml">
+  <!ENTITY howto_1_i_listing SYSTEM "howto_1.i.xml">
+  <!ENTITY src_lib_Makefile_1_am_listing SYSTEM "src_lib_Makefile_1.am.xml">
+  <!ENTITY src_lib_Makefile_2_am_listing SYSTEM "src_lib_Makefile_2.am.xml">
+
+]>
+
+<article>
+
+<articleinfo>
+<title>How to Write a Signal Processing Block</title>
+<author>
+  <firstname>Eric</firstname>
+  <surname>Blossom</surname>
+  <affiliation>
+    <address>
+      <email>eb@comsec.com</email>
+    </address>
+  </affiliation>
+</author>
+
+<revhistory>
+  <revision>
+  <revnumber>0.1</revnumber>
+  <date>2005-01-20</date>
+  </revision>
+  <revision>
+  <revnumber>0.2</revnumber>
+  <date>2005-02-02</date>
+  <revremark>Updated for SWIG 1.3.24</revremark>
+  </revision>
+  <revision>
+  <revnumber>0.3</revnumber>
+  <date>2006-07-21</date>
+  <revremark>Clarification of 1:1 fixed rate vs item size</revremark>
+  </revision>
+</revhistory>
+
+<copyright>
+  <year>2004</year>
+  <year>2005</year>
+  <holder>Free Software Foundation, Inc.</holder>
+</copyright>
+
+<abstract><para>This article explains how to write signal
+processing blocks for <application>GNU Radio</application>.
+</para></abstract>
+
+</articleinfo>
+
+<sect1 id="prereqs"><title>Prerequisites</title>
+<para>This article assumes that the reader has basic familiarity with
+GNU Radio and has read and understood 
+<ulink url="http://www.gnu.org/software/gnuradio/doc/exploring-gnuradio.html">
+<citetitle>Exploring GNU Radio</citetitle></ulink>.
+</para>
+
+<para>There is a tarball of files that accompany this article.  It
+includes the examples, DocBook source for the article and all the
+Makefiles etc it takes to make it work.  Grab it at <ulink
+url="ftp://ftp.gnu.org/gnu/gnuradio">
+ftp://ftp.gnu.org/gnu/gnuradio</ulink> or one of the mirrors.  The
+file you want is
+<filename>gr-howto-write-a-block-X.Y.tar.gz</filename>.  Pick the one
+with the highest version number. 
+See <ulink url="http://comsec.com/wiki?CvsAccess">
+http://comsec.com/wiki?CvsAccess</ulink> for CVS Access.
+</para>
+
+
+</sect1>
+
+<sect1 id="intro"><title>Introduction</title>
+<para>&gnuradio; provides a framework for building software radios.
+Waveforms -- signal processing applications -- are built using a
+combination of Python code for high level organization, policy, GUI and
+other non performance-critical functions, while performance critical
+signal processing blocks are written in C++.</para>
+
+<para>From the Python point of view, &gnuradio; provides a data flow
+abstraction.  The fundamental concepts are signal processing
+blocks and the connections between them.  This abstraction is
+implemented by the Python <classname>gr.flow_graph</classname> class.
+Each block has a set of input ports and output ports.  Each port has
+an associated data type.  The most common port types are
+<classname>float</classname> and <classname>gr_complex</classname>
+(equivalent to std::complex&lt;float&gt;), though other types are used,
+including those representing structures, arrays or other types of
+packetized data.</para>  
+
+<para>From the high level point-of-view, infinite streams of data flow
+through the ports.  At the C++ level, streams are dealt with in
+convenient sized pieces, represented as contiguous arrays of the
+underlying type.</para>
+
+</sect1>
+
+<sect1 id="overview"><title>The View from 30,000 Feet</title>
+
+<para>This article will walk through the construction of several
+simple signal processing blocks, and explain the techniques and idioms
+used.  Later sections cover debugging signal processing blocks in the
+mixed Python/C++ environment and performance measurement and
+optimization.</para>
+
+<para>The example blocks will be built in the style of all &gnuradio;
+extensions. That is, they are built outside of the gnuradio-core build
+tree, and are constructed as shared libraries that may be dynamically
+loaded into Python using the "import" mechanism.  &SWIG;, the
+Simplified Wrapper and Interface Generator, is used to generate the
+glue that allows our code to be used from Python.</para>
+
+</sect1>
+
+
+<sect1 id="gr_block"><title></title>
+
+<para>The C++ class &gr_block; is the base of all signal processing
+blocks in &gnuradio;.  Writing a new signal processing block involves
+creating 3 files: The .h and .cc files that define the new class and
+the .i file that tells &SWIG; how to generate the glue that binds the
+class into Python.  The new class must derive from &gr_block; or
+one of it&apos;s subclasses.</para>
+
+<para>Our first examples will derive directly from &gr_block;.  Later
+we will look at some other subclasses that simplify the process for
+common cases.</para>
+
+</sect1><!-- end gr_block sect1 -->
+
+
+
+<!-- ================================================================ -->
+
+<sect1 id="autotools"><title>Autotools, Makefiles, and Directory Layout</title>
+
+<para>Before we dive into the code, &lets; talk a bit about the
+overall build environment and the directory structure that &well;
+be using.</para>
+
+<para>To reduce the amount of Makefile hacking that we have to do, and
+to facilitate portability across a variety of systems, we use the GNU
+<application>autoconf</application>,
+<application>automake</application>, and
+<application>libtool</application> tools.  These are collectively
+referred to as the autotools, and once you get over the initial
+shock, they will become your friends. (The good news is that we
+provide boilerplate that can be used pretty much as-is.)</para>
+
+<variablelist>
+
+<varlistentry><term>automake</term>
+
+<listitem><para>automake and configure work together to generate GNU
+compliant Makefiles from a much higher level description contained in
+the corresponding Makefile.am file.  <filename>Makefile.am</filename>
+specifies the libraries and programs to build and the source files
+that compose each.  Automake reads <filename>Makefile.am</filename>
+and produces <filename>Makefile.in</filename>.  Configure reads
+<filename>Makefile.in</filename> and produces
+<filename>Makefile</filename>.  The resulting Makefile contains a
+zillion rules that do the right right thing to build, check and
+install your code.  It is not uncommon for the the resulting
+<filename>Makefile</filename> to be 5 or 6 times larger than
+<filename>Makefile.am</filename>.</para>
+
+</listitem>
+</varlistentry>
+
+<varlistentry><term>autoconf</term>
+<listitem><para>autoconf reads <filename>configure.ac</filename>
+and produces the <filename>configure</filename> shell
+script.  <filename>configure</filename> automatically tests for
+features of the underlying system and sets a bunch of variables and
+defines that can be used in the Makefiles and your C++ code to
+conditionalize the build.  If features are required but not found,
+configure will output an error message and stop.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry><term>libtool</term>
+<listitem><para>libtool works behind the scenes and provides the magic
+to construct shared libraries on a wide variety of systems.</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+
+<para><xref linkend="dir-layout"/> shows the directory layout and
+common files &well; be using.  After renaming the
+<replaceable>topdir</replaceable> directory, use it in your projects
+too.  We'll talk about particular files as they come up later.</para>
+
+
+<table id="dir-layout"><title>Directory Layout</title>
+<tgroup cols="2">
+
+<thead><row>
+<entry>File/Dir Name</entry>
+<entry>Comment</entry>
+</row>
+</thead>
+
+<tbody>
+
+<row>
+<entry><replaceable>topdir</replaceable>/Makefile.am</entry>
+<entry>Top level Makefile.am</entry>
+</row>
+<row>
+<entry><replaceable>topdir</replaceable>/Makefile.common</entry>
+<entry>Common fragment included in sub-Makefiles</entry>
+</row>
+<row>
+<entry><replaceable>topdir</replaceable>/bootstrap</entry>
+<entry>Runs autoconf, automake, libtool first time through</entry>
+</row>
+<row>
+<entry><replaceable>topdir</replaceable>/config</entry>
+<entry>Directory of m4 macros used by configure.ac</entry>
+</row>
+<row>
+<entry><replaceable>topdir</replaceable>/configure.ac</entry>
+<entry>Input to autoconf</entry>
+</row>
+<row>
+<entry><replaceable>topdir</replaceable>/src</entry>
+</row>
+<row>
+<entry><replaceable>topdir</replaceable>/src/lib</entry>
+<entry>C++ code goes here</entry>
+</row>
+<row>
+<entry><replaceable>topdir</replaceable>/src/lib/Makefile.am</entry>
+</row>
+<row>
+<entry><replaceable>topdir</replaceable>/src/python</entry>
+<entry>Python code goes here</entry>
+</row>
+<row>
+<entry><replaceable>topdir</replaceable>/src/python/Makefile.am</entry>
+</row>
+<row>
+<entry><replaceable>topdir</replaceable>/src/python/run_tests</entry>
+<entry>Script to run tests in the build tree</entry>
+</row>
+
+</tbody>
+</tgroup>
+</table>
+
+</sect1>
+
+<!-- ================================================================ -->
+
+<sect1 id="naming"><title>Naming Conventions</title>
+
+<para>&gnuradio; uses a set of naming conventions to assist in
+comprehending the code base and gluing C++ and Python together.
+Please follow them.</para>
+
+<sect2 id="camel-case"><title><emphasis>Death to CamelCaseNames!</emphasis></title>
+
+<para>We've returned to a kinder, gentler era.  We're now using the
+&quot;STL style&quot; naming convention with a couple of modifications
+since we're not using namespaces.</para>
+
+<para>With the exception of macros and other constant values, all
+identifiers shall be lower case with <literal>words_separated_like_this</literal>.</para>
+
+<para>Macros and constant values (e.g., enumerated values,
+<literal>static const int FOO = 23</literal>) shall be in <literal>UPPER_CASE</literal>.</para>
+
+</sect2>
+
+<sect2 id="global_names"><title>Global Names</title>
+
+<para>All globally visible names (types, functions, variables, consts, etc)
+shall begin with a "package prefix", followed by an underscore.  The bulk of
+the code in GNU Radio belongs to the "gr" package, hence
+names look like <literal>gr_open_file (...)</literal>.</para>
+
+<para>Large coherent bodies of code may use other package prefixes, but
+let's try to keep them to a well thought out list.  See the list
+below.</para>
+
+</sect2>
+
+<sect2 id="package_prefixes"><title>Package Prefixes</title>
+
+<para>These are the current package prefixes:
+
+<variablelist>
+
+<varlistentry><term>gr_</term>
+<listitem><para>Almost everything.</para></listitem>
+</varlistentry>
+
+<varlistentry><term>gri_</term>
+<listitem><para>
+Implementation primitives.  Sometimes we
+have both a gr_<replaceable>foo</replaceable> and a gri_<replaceable>foo</replaceable>.  In that case,
+gr_<replaceable>foo</replaceable> would be derived from gr_block and gri_<replaceable>foo</replaceable>
+would be the low level guts of the function.</para></listitem>
+</varlistentry>
+
+<varlistentry><term>atsc_</term>
+<listitem><para>Code related to the Advanced Television Standards Committee HDTV implementation
+</para></listitem>
+</varlistentry>
+
+<varlistentry><term>usrp_</term>
+<listitem><para>Universal Software Radio Peripheral.</para></listitem>
+</varlistentry>
+
+<varlistentry><term>qa_</term>
+<listitem><para>Quality Assurance (Test code.)</para></listitem>
+</varlistentry>
+
+</variablelist>
+
+</para>
+</sect2>
+
+<sect2 id="class-data-members"><title>Class Data Members (instance variables)</title>
+
+<para>All class data members shall begin with d_<replaceable>foo</replaceable>.</para>
+
+<para>The big win is when you're staring at a block of code it's obvious
+which of the things being assigned to persist outside of the block.
+This also keeps you from having to be creative with parameter names
+for methods and constructors.  You just use the same name as the
+instance variable, without the d_. </para>
+
+<literallayout>
+class gr_wonderfulness {
+  std::string   d_name;
+  double        d_wonderfulness_factor;
+
+public:
+  gr_wonderfulness (std::string name, double wonderfulness_factor)
+    : d_name (name), d_wonderfulness_factor (wonderfulness_factor)
+  {
+    ...
+  }
+  ...
+};
+</literallayout>
+
+</sect2>
+
+<sect2 id="static-data-members"><title>Class Static Data Members (class variables)</title>
+
+<para>
+All class static data members shall begin with s_<replaceable>foo</replaceable>.
+</para>
+
+</sect2>
+
+<sect2 id="file-names"><title>File Names</title>
+
+<para>Each significant class shall be contained in its own file.  The
+declaration of class <classname>gr_foo</classname> shall be in 
+<filename>gr_foo.h</filename> and the definition in
+<filename>gr_foo.cc</filename>.</para>
+</sect2>
+
+
+<sect2><title>Suffixes</title>
+
+<para>By convention, we encode the input and output types of signal
+processing blocks in their name using suffixes.  The suffix is
+typically one or two characters long.  Source and sinks have single
+character suffixes.  Regular blocks that have both inputs and outputs
+have two character suffixes.  The first character indicates the type
+of the input streams, the second indicates the type of the output
+streams.  FIR filter blocks have a three character suffix, indicating
+the type of the inputs, outputs and taps, respectively.</para>
+
+<para>These are the suffix characters and their interpretations:
+<itemizedlist>
+<listitem><para>f - single precision floating point</para></listitem>
+<listitem><para>c - complex&lt;float&gt;</para></listitem>
+<listitem><para>s - short (16-bit integer)</para></listitem>
+<listitem><para>i - integer (32-bit integer)</para></listitem>
+</itemizedlist>
+</para>
+
+<para>In addition, for those cases where the block deals with streams
+of vectors, we use the character 'v' as the first character of the
+suffix.  An example of this usage is
+<classname>gr_fft_vcc</classname>.  The FFT block takes a vector of
+complex numbers on its input and produces a vector of complex
+numbers on its output.</para>
+
+</sect2>
+
+</sect1>
+
+
+
+
+<sect1 id="square"><title>First Block: &square;</title>
+
+<para>For our first example &well; create a block that computes
+the square of its single float input.  This block will accept a single
+float input stream and produce a single float output stream.</para>
+
+<para>Following the naming conventions, &well; use
+<literal>howto</literal> as our package prefix, and the block will
+be called <classname>howto_square_ff</classname>.</para>
+
+<para>We are going to arrange that this block, as well as the others
+that we write in this article, end up in the
+<literal>gnuradio.howto</literal> Python module.  This will allow us
+to access it from Python like this:
+<programlisting>
+from gnuradio import howto
+sqr = howto.square_ff ()
+</programlisting>
+</para>
+
+
+<sect2 id="test_driven"><title>Test Driven Programming</title>
+
+<para>We could just start banging out the C++ code, but being highly
+evolved modern programmers, &were; going to write the test code first.
+After all, we do have a good spec for the behavior: take a single
+stream of floats as the input and produce a single stream of floats as
+the output. The output should be the square of the input.</para>
+
+<para>How hard could this be?  Turns out that this is easy! Check out 
+<xref linkend="qa_howto_1.py"/>.</para>
+
+<example id="qa_howto_1.py">
+<title><filename>qa_howto.py</filename> (first version)</title>
+&qa_howto_1_listing;
+</example>
+
+<para>
+<classname>gr_unittest</classname> is an extension to the standard
+python module <classname>unittest</classname>.
+<classname>gr_unittest</classname> adds support for checking
+approximate equality of tuples of float and complex numbers.  
+Unittest uses Python&apos;s reflection mechanism to find all methods that start with
+<methodname>test_</methodname> and runs them.  Unittest wraps each call
+to <methodname>test_*</methodname> with matching calls to 
+<methodname>setUp</methodname> and <methodname>tearDown</methodname>.
+See the python <ulink url="http://docs.python.org/lib/module-unittest.html">
+unittest</ulink> documentation for details.
+</para>
+
+<para>When we run the test,
+gr_unittest.main is going to invoke
+<methodname>setUp</methodname>,
+<methodname>test_001_square_ff</methodname>, and
+<methodname>tearDown</methodname>.</para>
+<para>
+<methodname>test_001_square_ff</methodname> builds a small graph that
+contains three nodes.  gr.vector_source_f(src_data) will source the
+elements of src_data and then say that &its; finished.  howto.square_ff is the block
+&were; testing.  gr.vector_sink_f gathers the output of
+howto.square_ff.</para>
+
+<para>The <methodname>run</methodname> method runs the graph until all
+the blocks indicate they are finished.  Finally, we check that the
+result of executing square_ff on src_data matches what we expect.
+</para>
+
+</sect2>
+
+<sect2 id="build_vs_install"><title>Build Tree vs. Install Tree</title>
+
+<para>The build tree is everything from <replaceable>topdir</replaceable>
+(the one containing configure.ac) down.  The path to the install tree is
+<filename>
+<replaceable>prefix</replaceable>/lib/python<replaceable>version</replaceable>/site-packages</filename>,
+where <replaceable>prefix</replaceable> is the <literal>--prefix</literal>
+argument to configure (default <filename>/usr/local</filename>) and 
+<replaceable>version</replaceable> is the installed version of
+python. A typical value is 
+<filename>/usr/local/lib/python2.3/site-packages</filename>.</para>
+
+
+<para>We normally set our PYTHONPATH environment variable to point at
+the install tree, and do this in <filename>~/.bash_profile</filename> 
+or <filename>~/.profile</filename>.
+This allows our python apps to access all the standard python
+libraries, plus our locally installed stuff like GNU Radio.</para>
+
+<para>We write our applications such that they access the code and
+libraries in the install tree.  On the other hand, we want our test
+code to run on the build tree, where we can detect problems before
+installation.</para>
+
+</sect2>
+
+<sect2 id="make_check"><title>make check</title>
+
+
+<para>We use <command>make check</command> to run our tests.
+Make check invokes the <command>run_tests</command> shell script which 
+sets up the PYTHONPATH environment variable so that 
+our tests use the build tree versions of our code and libraries.
+It then runs all files
+which have names of the form <filename>qa_*.py</filename> and reports
+the overall success or failure.</para>
+
+<para>There is quite a bit of behind-the-scenes action required to use
+the non-installed versions of our code (look at
+<filename>runtest</filename> for a cheap thrill.)</para>
+
+<para>Finally, running <command>make check</command> in the python
+directory produces this result:
+<literallayout>
+  [eb@bufo python]$ make check
+  make  check-TESTS
+  make[1]: Entering directory `/home/eb/gr-build/gr-howto-write-a-block/src/python'
+  Traceback (most recent call last):
+    File "./qa_howto.py", line 24, in ?
+      import howto
+  ImportError: No module named howto
+  Traceback (most recent call last):
+    File "./qa_howto_1.py", line 24, in ?
+      import howto
+  ImportError: No module named howto
+  FAIL: run_tests
+  ===================
+  1 of 1 tests failed
+  ===================
+  make[1]: *** [check-TESTS] Error 1
+  make[1]: Leaving directory `/home/eb/gr-build/gr-howto-write-a-block/src/python'
+  make: *** [check-am] Error 2
+  [eb@bufo python]$
+</literallayout>
+Excellent!  Our test failed, just as we expected.  The ImportError
+indicates that it can't find the module named
+<classname>howto</classname>.  No surprise, since we haven't written it yet.
+</para>
+
+</sect2>
+
+<sect2><title>The C++ code</title>
+<para>Now that we've got a test case written that successfully fails,
+let's write the C++ code.  As we mentioned earlier, all signal
+processing blocks are derived from <classname>gr_block</classname> or
+one of its subclasses.  Let's take a look at 
+<xref linkend="gr_block.h"/>.</para>
+
+<example id="gr_block.h">
+<title><filename>gr_block.h</filename></title>
+&gr_block_listing;
+</example>
+
+<para>A quick scan of <filename>gr_block.h</filename> reveals that
+since <methodname>general_work</methodname> is pure virtual, we
+definitely need to override that. 
+<methodname>general_work</methodname> is the method that does the
+actual signal processing.  For our squaring example we'll
+need to override <methodname>general_work</methodname> and provide a
+constructor and destructor and a bit of stuff to take advantage of
+the <ulink url="http://www.boost.org">boost</ulink>
+<ulink url="http://www.boost.org/libs/smart_ptr/smart_ptr.htm">
+<classname>shared_ptr</classname>s.</ulink>
+
+</para>
+
+
+<para><xref linkend="howto_square_ff.h"/> 
+and <xref linkend="howto_square_ff.cc"/> are the header and c++
+source.</para>
+
+<example id="howto_square_ff.h">
+<title><filename>howto_square_ff.h</filename></title>
+&howto_square_ff_h_listing;
+</example>
+
+<example id="howto_square_ff.cc">
+<title><filename>howto_square_ff.cc</filename></title>
+&howto_square_ff_cc_listing;
+</example>
+
+<para>Now we need a Makefile.am to get all this to build.  
+<xref linkend="src_lib_Makefile_1"/> 
+is enough to build a shared library from our source file.  We'll be
+adding additional rules to use &SWIG; in just a bit.  If you haven't
+already, this is a good time to browse all the Makefile.am&apos;s in
+the build tree and get an idea for how it all hangs together.</para>
+
+<example id="src_lib_Makefile_1">
+<title><filename>src/lib/Makefile.am</filename> (no &SWIG;)</title>
+&src_lib_Makefile_1_am_listing;
+</example>
+
+</sect2>
+
+
+<!-- ==============================
+
+<sect2 id="io_sig"><title><classname>gr_io_signature</classname></title>
+<para></para>
+</sect2>
+
+<sect2 id="forecast"><title><methodname>forecast</methodname></title>
+<para></para>
+</sect2>
+
+<sect2 id="output_multiple">
+<title><methodname>set_output_multiple</methodname></title>
+<para></para>
+</sect2>
+
+  ============================== -->
+
+
+<sect2 id="swig"><title>The &SWIG; .i file</title> 
+
+<para>Now that we've got something that will compile, we need to write
+the &SWIG; .i file.  This is a pared-down version of the .h file, plus
+a bit of magic that has python work with the boost shared_ptr&apos;s.
+To reduce code bloat, we only declare methods that &well; want to
+access from Python.</para>
+
+<para>We&apos;re going to call the .i file
+<filename>howto.i</filename>, and use it to hold the &SWIG;
+declarations for all classes from <literal>howto</literal> that will
+be accessible from python.  It&apos;s quite small:
+&howto_1_i_listing;
+</para>
+
+</sect2>
+
+<sect2><title>Putting it all together</title>
+<para>
+Now we need to modify <filename>src/lib/Makefile.am</filename>
+to run &SWIG; and to add the glue it generates to the shared library.</para>
+
+<example id="src_lib_Makefile_2">
+<title><filename>src/lib/Makefile.am</filename> (with &SWIG;)</title>
+&src_lib_Makefile_2_am_listing;
+</example>
+
+<para><command>make</command> now builds everything successfully.  We get a
+few warnings, but &thats; OK.</para>
+
+<para>Changing directories back to the python directory we try
+<command>make check</command> again:
+<literallayout>
+  [eb@bufo python]$ make check
+  make  check-TESTS
+  make[1]: Entering directory `/home/eb/gr-build/gr-howto-write-a-block/src/python'
+  .
+  ----------------------------------------------------------------------
+  Ran 1 test in 0.004s
+  
+  OK
+  PASS: run_tests
+  ==================
+  All 1 tests passed
+  ==================
+  make[1]: Leaving directory `/home/eb/gr-build/gr-howto-write-a-block/src/python'
+  [eb@bufo python]$
+</literallayout>
+<emphasis>Victory! Our new block works!</emphasis>
+</para>
+
+</sect2>
+
+</sect1><!-- end First Block: square -->
+
+<sect1 id="additional_methods"><title>Additional gr_block methods</title>
+
+<para>In our <classname>howto_square_ff</classname> example above, we only
+had to override the <methodname>general_work</methodname> method to
+accomplish our goal.  <classname>gr_block</classname> provides a few other
+methods that are sometimes useful.</para>
+
+<sect2 id="forecast"><title>forecast</title>
+
+<para>Looking at <methodname>general_work</methodname> you may
+have wondered how the system knows how much data it needs to
+ensure is valid in each of the input arrays.  The
+<methodname>forecast</methodname> method provides this
+information.</para>
+
+<para>The default implementation of <methodname>forecast</methodname>
+says there is a 1:1 relationship between noutput_items and the
+requirements for each input stream.  The size of the items is defined by
+<classname>gr_io_signature</classname>s in the constructor of
+<classname>gr_block</classname>. The sizes of the input and output items
+can of course differ; this still qualifies as a 1:1 relationship.
+<programlisting>
+  // default implementation:  1:1
+
+  void
+  gr_block::forecast (int noutput_items,
+                      gr_vector_int &amp;ninput_items_required)
+  {
+    unsigned ninputs = ninput_items_required.size ();
+    for (unsigned i = 0; i &lt; ninputs; i++)
+      ninput_items_required[i] = noutput_items;
+  }
+</programlisting>
+</para>
+
+<para>Although the 1:1 implementation worked for howto_square_ff, it
+wouldn&apos;t be appropriate for interpolators, decimators, or blocks
+with a more complicated relationship between noutput_items and the
+input requirements.  That said, by deriving your classes from
+<classname>gr_sync_block</classname>,
+<classname>gr_sync_interpolator</classname> or
+<classname>gr_sync_decimator</classname> instead of
+<classname>gr_block</classname>, you can often avoid
+implementing <methodname>forecast</methodname>.</para>
+
+</sect2>
+
+<sect2 id="set_output_multiple"><title>set_output_multiple</title>
+
+<para>When implementing your <methodname>general_work</methodname>
+routine, &its; occasionally convenient to have the run time system
+ensure that you are only asked to produce a number of output items
+that is a multiple of some particular value.  This might occur if your
+algorithm naturally applies to a fixed sized block of data. 
+Call <methodname>set_output_multiple</methodname> in your constructor
+to specify this requirement. The default output multiple is 1.</para>
+
+</sect2>
+
+</sect1>
+
+
+<sect1 id="common_patterns">
+<title>Subclasses for common patterns</title>
+
+<para><classname>gr_block</classname> allows tremendous flexibility
+with regard to the consumption of input streams and the production of
+output streams.  Adroit use of <methodname>forecast</methodname> and
+<methodname>consume</methodname> allows variable rate blocks to be
+built.  It is possible to construct blocks that consume data at
+different rates on each input, and produce output at a rate that
+is a function of the contents of the input data.</para>
+
+<para>On the other hand, it is very common for signal processing
+blocks to have a fixed relationship between the input rate and the
+output rate.  Many are 1:1, while others have 1:N or N:1
+relationships.</para>
+
+<para>Another common requirement is the need to examine more than one
+input sample to produce a single output sample.  This is orthogonal to
+the relationship between input and output rate.  For example, a
+non-decimating, non-interpolating FIR filter needs to examine N input
+samples for each output sample it produces, where N is the number of
+taps in the filter.  However, it only consumes a single input sample
+to produce a single output.  We call this concept "history", but you
+could also think of it as "look-ahead".</para>
+
+<sect2 id="gr_sync_block"><title><classname>gr_sync_block</classname></title>
+
+<para>
+<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__block.html">
+<classname>gr_sync_block</classname></ulink>
+is derived from
+<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__block.html">
+<classname>gr_block</classname></ulink>
+and implements a 1:1 block with
+optional history.  Given that we know the input to output rate,
+certain simplifications are possible.  From the implementor&apos;s
+point-of-view, the primary change is that we define a
+<methodname>work</methodname> method instead of
+<methodname>general_work</methodname>.  <methodname>work</methodname>
+has a slightly different calling sequence;
+It omits the unnecessary ninput_items parameter, and arranges for
+<methodname>consume_each</methodname> to be called on our
+behalf.</para>
+<programlisting>
+  /*!
+   * \brief Just like gr_block::general_work, only this arranges to
+   *  call consume_each for you.
+   *
+   * The user must override work to define the signal processing code
+   */
+  virtual int work (int noutput_items,
+                    gr_vector_const_void_star &amp;input_items,
+                    gr_vector_void_star &amp;output_items) = 0;
+</programlisting>
+
+<para>This gives us fewer things to worry about, and less code to
+write.  If the block requires history greater than 1, call
+<methodname>set_history</methodname> in the constructor, or any time
+the requirement changes.</para>
+
+<para><classname>gr_sync_block</classname> provides a
+version of <methodname>forecast</methodname> that handles the
+history requirement.</para>
+
+</sect2>
+
+<sect2 id="gr_sync_decimator"><title><classname>gr_sync_decimator</classname></title>
+
+<para>
+<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__decimator.html">
+<classname>gr_sync_decimator</classname></ulink>
+is derived from
+<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__block.html">
+<classname>gr_sync_block</classname></ulink>
+and implements a N:1 block with optional history.  
+</para>
+
+</sect2>
+
+<sect2 id="gr_sync_interpolator"><title><classname>gr_sync_interpolator</classname></title>
+
+<para>
+<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__interpolator.html">
+<classname>gr_sync_interpolator</classname></ulink>
+is derived from
+<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__block.html">
+<classname>gr_sync_block</classname></ulink>
+and implements a 1:N block with optional history.  
+</para>
+
+</sect2>
+
+
+</sect1>
+
+<sect1 id="square2">
+<title>Second Block: <classname>howto_square2_ff</classname></title>
+
+<para>Given that we now know about
+<classname>gr_sync_block</classname>, the way 
+<classname>howto_square_ff</classname> should really be implemented is
+by subclassing <classname>gr_sync_block</classname>.</para>
+
+<para>Here are the revised sources: <xref
+linkend="howto_square2_ff.h"/>, 
+<xref linkend="howto_square2_ff.cc"/>.  
+The accompanying files contain the additional test code.
+</para>
+
+<example id="howto_square2_ff.h">
+<title><filename>howto_square2_ff.h</filename></title>
+&howto_square2_ff_h_listing;
+</example>
+
+<example id="howto_square2_ff.cc">
+<title><filename>howto_square2_ff.cc</filename></title>
+&howto_square2_ff_cc_listing;
+</example>
+
+</sect1>
+
+<sect1 id="where_to"><title>Where to from Here?</title>
+
+<para>At this point, we&apos;ve got a basic overview of how the system
+goes together.  For more insight, I suggest that you look at the code
+of the system.  The doxygen generated <ulink
+url="http://www.gnu.org/software/gnuradio/doc/hierarchy.html"> class
+hierarchy</ulink> is a useful way to find things that might interest
+you.</para>
+
+</sect1>
+
+
+<sect1 id="tips"><title>Miscellaneous Tips</title>
+
+<sect2 id="sources_and_sinks"><title>Sources and Sinks</title>
+
+<para>Sources and sinks are derived from
+<classname>gr_sync_block</classname>.  The only thing different about
+them is that sources have no inputs and sinks have no outputs.  This
+is reflected in the <classname>gr_io_signature</classname>s that are
+passed to the <classname>gr_sync_block</classname> constructor.
+Take a look at <filename>gr_file_source.{h,cc}</filename> and
+<filename>gr_file_sink.{h,cc}</filename> for some very straight-forward examples.
+</para>
+
+</sect2>
+
+<sect2 id="debugging">
+<title>Debugging with <application>gdb</application></title>
+
+<para>If your block isn&apos;t working, and you can&apos;t sort it
+out through python test cases or a few printfs in the code, you may want to
+use <application>gdb</application> to debug it.  The trick of course
+is that all of &gnuradio;, including your new block, is dynamically
+loaded into python for execution.</para>
+
+<para>Try this:  In your python test code, after the relevant imports,
+print out the process id and wait for a keystroke.  In another
+window run gdb and tell it to attach to the python process with the
+given process id.  At this point you can set breakpoints or whatever
+in your code.  Go back to the python window and hit Enter so
+it&apos;ll continue.</para>
+
+<programlisting>
+  #!/usr/bin/env python
+  from gnuradio import gr
+  from gnuradio import my_buggy_module
+
+  # insert this in your test code...
+  import os
+  print 'Blocked waiting for GDB attach (pid = %d)' % (os.getpid(),)
+  raw_input ('Press Enter to continue: ')
+  # remainder of your test code follows...
+</programlisting>
+
+<para>Another SNAFU you might run into is that gdb 6.2 isn&apos;t
+able to set breakpoints in the constructors or destructors generated
+by g++ 3.4.  In this case, insert a call to the nop function
+gri_debugger_hook in the constructor and recompile.  Load the code as
+before and set a break point on gri_debugger_hook.</para>
+
+</sect2>
+
+<sect2 id="oprofile">
+<title>Performance Measurement with <application>oprofile</application></title>
+<para>Oprofile is your friend.  
+See <ulink url="http://oprofile.sourceforge.net">http://oprofile.sourceforge.net</ulink>.
+</para>
+</sect2>
+
+</sect1><!-- end tips -->
+
+<sect1 id="futures"><title>Coming Attractions</title>
+<para></para>
+
+<sect2 id="types"><title>Improved Type System</title>
+<para></para>
+</sect2>
+
+<sect2 id="hierarchy"><title>Hierarchical Blocks</title>
+<para></para>
+</sect2>
+
+</sect1><!-- end Coming Attractions -->
+
+</article>
diff --git a/gr-howto-write-a-block/limbo/doc/howto_1.i b/gr-howto-write-a-block/limbo/doc/howto_1.i
new file mode 100644 (file)
index 0000000..640d089
--- /dev/null
@@ -0,0 +1,29 @@
+/* -*- c++ -*- */
+
+%include "exception.i"
+%import "gnuradio.i"                           // the common stuff
+
+%{
+#include "gnuradio_swig_bug_workaround.h"      // mandatory bug fix
+#include "howto_square_ff.h"
+#include <stdexcept>
+%}
+
+// ----------------------------------------------------------------
+
+/*
+ * First arg is the package prefix.
+ * Second arg is the name of the class minus the prefix.
+ *
+ * This does some behind-the-scenes magic so we can
+ * access howto_square_ff from python as howto.square_ff
+ */
+GR_SWIG_BLOCK_MAGIC(howto,square_ff);
+
+howto_square_ff_sptr howto_make_square_ff ();
+
+class howto_square_ff : public gr_block
+{
+private:
+  howto_square_ff ();
+};
diff --git a/gr-howto-write-a-block/limbo/doc/make_numbered_listing.py b/gr-howto-write-a-block/limbo/doc/make_numbered_listing.py
new file mode 100755 (executable)
index 0000000..889c2d7
--- /dev/null
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+
+import sys
+import os, os.path
+from optparse import OptionParser
+
+def quote_line (line):
+    line = line.replace ('&', '&amp;')
+    line = line.replace ('<', '&lt;')
+    line = line.replace ('>', '&gt;')
+    line = line.replace ("'", '&apos;')
+    line = line.replace ('"', '&quot;')
+    return line
+
+def generate_listing (input_filename, title=None):
+    inf = open (input_filename, "r")
+    output_filename = os.path.basename (input_filename) + '.xml'
+    outf = open (output_filename, "w")
+    outf.write ('<?xml version="1.0" encoding="ISO-8859-1"?>\n')
+    # outf.write ('<example id="%s">\n' % (input_filename,))
+    # if not title:
+    #     title = input_filename
+    # outf.write ('<title>')
+    # outf.write (title)
+    # outf.write ('</title>\n')
+    outf.write ('<programlisting>\n');
+
+    lineno = 0
+    for line in inf:
+        line = line.expandtabs (8)
+        line = quote_line (line)
+        lineno = lineno + 1
+        outf.write ('%3d  %s' % (lineno, line))
+
+    outf.write ('</programlisting>\n')
+    # outf.write ('</example>\n')
+
+
+def main ():
+    for file in sys.argv[1:]:
+        generate_listing (file)
+
+if __name__ == '__main__':
+    main ()
+    
diff --git a/gr-howto-write-a-block/limbo/doc/qa_howto_1.py b/gr-howto-write-a-block/limbo/doc/qa_howto_1.py
new file mode 100755 (executable)
index 0000000..3173110
--- /dev/null
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gr_unittest
+import howto
+
+class qa_howto (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.tb = gr.top_block ()
+
+    def tearDown (self):
+        self.tb = None
+
+    def test_001_square_ff (self):
+        src_data = (-3, 4, -5.5, 2, 3)
+        expected_result = (9, 16, 30.25, 4, 9)
+        src = gr.vector_source_f (src_data)
+        sqr = howto.square_ff ()
+        dst = gr.vector_sink_f ()
+        self.tb.connect (src, sqr)
+        self.tb.connect (sqr, dst)
+        self.tb.run ()
+        result_data = dst.data ()
+        self.assertFloatTuplesAlmostEqual (expected_result, result_data, 6)
+        
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gr-howto-write-a-block/limbo/doc/src_lib_Makefile_1.am b/gr-howto-write-a-block/limbo/doc/src_lib_Makefile_1.am
new file mode 100644 (file)
index 0000000..e97d70d
--- /dev/null
@@ -0,0 +1,25 @@
+include $(top_srcdir)/Makefile.common
+
+# Install this stuff so that it ends up as the gnuradio.howto module
+# This usually ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
+
+ourpythondir = $(grpythondir)
+ourlibdir    = $(grpyexecdir)
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES)
+
+ourlib_LTLIBRARIES = _howto.la
+
+# These are the source files that go into the shared library
+_howto_la_SOURCES =                    \
+       howto_square_ff.cc              
+
+# magic flags
+_howto_la_LDFLAGS = -module -avoid-version
+
+# These headers get installed in ${prefix}/include/gnuradio
+grinclude_HEADERS =                    \
+       howto_square_ff.h               
+
+MOSTLYCLEANFILES = $(BUILT_SOURCES) *.pyc
diff --git a/gr-howto-write-a-block/limbo/doc/src_lib_Makefile_2.am b/gr-howto-write-a-block/limbo/doc/src_lib_Makefile_2.am
new file mode 100644 (file)
index 0000000..dca236e
--- /dev/null
@@ -0,0 +1,86 @@
+#
+# Copyright 2004,2008 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
+
+# Install this stuff so that it ends up as the gnuradio.howto module
+# This usually ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
+
+ourpythondir = $(grpythondir)
+ourlibdir    = $(grpyexecdir)
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES)
+
+SWIGCPPPYTHONARGS = -noruntime -c++ -python $(PYTHON_CPPFLAGS) \
+       -I$(swigincludedir) -I$(grincludedir) $(WITH_SWIG_INCLUDES)
+
+ALL_IFILES =                           \
+       $(LOCAL_IFILES)                 \
+       $(NON_LOCAL_IFILES)             
+
+NON_LOCAL_IFILES =                     \
+       $(GNURADIO_CORE_INCLUDEDIR)/swig/gnuradio.i
+
+
+LOCAL_IFILES =                                 \
+       howto.i                         
+
+# These files are built by SWIG.  The first is the C++ glue.
+# The second is the python wrapper that loads the _howto shared library
+# and knows how to call our extensions.
+
+BUILT_SOURCES =                        \
+       howto.cc                        \
+       howto.py                                
+
+# This gets howto.py installed in the right place
+ourpython_PYTHON =                     \
+       howto.py
+
+ourlib_LTLIBRARIES = _howto.la
+
+# These are the source files that go into the shared library
+_howto_la_SOURCES =                    \
+       howto.cc                        \
+       howto_square_ff.cc              
+
+# magic flags
+_howto_la_LDFLAGS = -module -avoid-version
+
+# link the library against some comon swig runtime code and the 
+# c++ standard library
+_howto_la_LIBADD =                     \
+       -lgrswigrunpy                   \
+       -lstdc++                        
+
+howto.cc howto.py: howto.i $(ALL_IFILES)
+       $(SWIG) $(SWIGCPPPYTHONARGS) -module howto -o howto.cc $<
+
+# These headers get installed in ${prefix}/include/gnuradio
+grinclude_HEADERS =                    \
+       howto_square_ff.h               
+
+# These swig headers get installed in ${prefix}/include/gnuradio/swig
+swiginclude_HEADERS =                  \
+       $(LOCAL_IFILES)
+
+MOSTLYCLEANFILES = $(BUILT_SOURCES) *.pyc
diff --git a/gr-howto-write-a-block/python/.gitignore b/gr-howto-write-a-block/python/.gitignore
new file mode 100644 (file)
index 0000000..bf03975
--- /dev/null
@@ -0,0 +1,9 @@
+/Makefile
+/Makefile.in
+/.deps
+/.libs
+/*.la
+/*.lo
+/*.pyc
+/*.pyo
+/run_tests
diff --git a/gr-howto-write-a-block/python/Makefile.am b/gr-howto-write-a-block/python/Makefile.am
new file mode 100644 (file)
index 0000000..79f4401
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# Copyright 2004 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
+
+EXTRA_DIST = run_tests.in
+
+
+TESTS =                                \
+       run_tests
+
+
+noinst_PYTHON =                        \
+       qa_howto.py                     
diff --git a/gr-howto-write-a-block/python/qa_howto.py b/gr-howto-write-a-block/python/qa_howto.py
new file mode 100755 (executable)
index 0000000..0abe0e2
--- /dev/null
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,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 GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import gr, gr_unittest
+import howto
+
+class qa_howto (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.tb = gr.top_block ()
+
+    def tearDown (self):
+        self.tb = None
+
+    def test_001_square_ff (self):
+        src_data = (-3, 4, -5.5, 2, 3)
+        expected_result = (9, 16, 30.25, 4, 9)
+        src = gr.vector_source_f (src_data)
+        sqr = howto.square_ff ()
+        dst = gr.vector_sink_f ()
+        self.tb.connect (src, sqr)
+        self.tb.connect (sqr, dst)
+        self.tb.run ()
+        result_data = dst.data ()
+        self.assertFloatTuplesAlmostEqual (expected_result, result_data, 6)
+
+    def test_002_square2_ff (self):
+        src_data = (-3, 4, -5.5, 2, 3)
+        expected_result = (9, 16, 30.25, 4, 9)
+        src = gr.vector_source_f (src_data)
+        sqr = howto.square2_ff ()
+        dst = gr.vector_sink_f ()
+        self.tb.connect (src, sqr)
+        self.tb.connect (sqr, dst)
+        self.tb.run ()
+        result_data = dst.data ()
+        self.assertFloatTuplesAlmostEqual (expected_result, result_data, 6)
+        
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gr-howto-write-a-block/python/run_tests.in b/gr-howto-write-a-block/python/run_tests.in
new file mode 100644 (file)
index 0000000..5b50509
--- /dev/null
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+# All this strange PYTHONPATH manipulation is required to run our
+# tests using our just built shared library and swig-generated python
+# code prior to installation.
+
+# build tree == src tree unless you're doing a VPATH build.  
+# If you don't know what a VPATH build is, you're not doing one.  Relax...
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+
+# Where to look in the build tree for our shared library
+libbld=@abs_top_builddir@/lib
+# Where to look in the build tree for swig generated python code
+libswig=@abs_top_builddir@/swig
+# Where to look in the src tree for hand written python code
+py=@abs_top_srcdir@/python
+
+# Where to look for installed GNU Radio python modules
+# FIXME this is wrong on a distcheck.  We really need to ask gnuradio-core
+# where it put its python files.
+installed_pythondir=@pythondir@
+installed_pyexecdir=@pyexecdir@
+
+PYTHONPATH="$libbld:$libbld/.libs:$libswig:$libswig/.libs:$py:$installed_pythondir:$installed_pyexecdir:$PYTHONPATH"
+echo $PYTHONPATH
+
+export PYTHONPATH
+
+#
+# This is the simple part...
+# Run everything that matches qa_*.py and return the final result.
+#
+
+ok=yes
+for file in @srcdir@/qa_*.py
+do
+  if ! $file
+  then
+    ok=no
+  fi  
+done
+
+if [ $ok = yes ]
+then
+  exit 0
+else
+  exit 1
+fi
diff --git a/gr-howto-write-a-block/src/.gitignore b/gr-howto-write-a-block/src/.gitignore
deleted file mode 100644 (file)
index bb3f277..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-/Makefile
-/Makefile.in
-/.la
-/.lo
-/.deps
-/.libs
-/*.la
-/*.lo
-/howto.cc
-/howto.py
diff --git a/gr-howto-write-a-block/src/Makefile.am b/gr-howto-write-a-block/src/Makefile.am
deleted file mode 100644 (file)
index 4c8650d..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Copyright 2004,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.
-# 
-
-SUBDIRS = lib
-
-if PYTHON
-SUBDIRS += python
-endif
diff --git a/gr-howto-write-a-block/src/lib/.gitignore b/gr-howto-write-a-block/src/lib/.gitignore
deleted file mode 100644 (file)
index d957a68..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-/Makefile
-/Makefile.in
-/.la
-/.lo
-/.deps
-/.libs
-/*.la
-/*.lo
-/*.pyc
-/howto.cc
-/howto.py
diff --git a/gr-howto-write-a-block/src/lib/Makefile.am b/gr-howto-write-a-block/src/lib/Makefile.am
deleted file mode 100644 (file)
index fa6b439..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-#
-# Copyright 2004,2005,2006,2008,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.
-# 
-
-include $(top_srcdir)/Makefile.common
-
-###################################
-# howto C++ library
-
-# C/C++ headers get installed in ${prefix}/include/gnuradio
-grinclude_HEADERS =            \
-       howto_square_ff.h       \
-       howto_square2_ff.h
-
-lib_LTLIBRARIES = libgnuradio-howto.la
-
-libgnuradio_howto_la_SOURCES =         \
-       howto_square_ff.cc      \
-       howto_square2_ff.cc
-
-libgnuradio_howto_la_LIBADD =  \
-       $(GNURADIO_CORE_LA)
-
-libgnuradio_howto_la_LDFLAGS = \
-       $(NO_UNDEFINED)
-
-if PYTHON
-###################################
-# SWIG Python interface and library
-
-TOP_SWIG_IFILES =              \
-       howto.i
-
-# Install so that they end up available as:
-#   import gnuradio.howto
-# This ends up at:
-#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
-howto_pythondir_category =     \
-       gnuradio
-
-howto_la_swig_libadd =         \
-       libgnuradio-howto.la
-
-include $(top_srcdir)/Makefile.swig
-
-# add some of the variables generated inside the Makefile.swig.gen
-BUILT_SOURCES = $(swig_built_sources)
-
-# Do not distribute the output of SWIG
-no_dist_files = $(swig_built_sources)
-endif
diff --git a/gr-howto-write-a-block/src/lib/Makefile.swig.gen b/gr-howto-write-a-block/src/lib/Makefile.swig.gen
deleted file mode 100644 (file)
index f76cc63..0000000
+++ /dev/null
@@ -1,259 +0,0 @@
-# -*- 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 howto.i
-
-## Default install locations for these files:
-##
-## Default location for the Python directory is:
-##  ${prefix}/lib/python${python_version}/site-packages/[category]/howto
-## Default location for the Python exec directory is:
-##  ${exec_prefix}/lib/python${python_version}/site-packages/[category]/howto
-##
-## 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.
-
-howto_pythondir_category ?= gnuradio/howto
-howto_pylibdir_category ?= $(howto_pythondir_category)
-howto_pythondir = $(pythondir)/$(howto_pythondir_category)
-howto_pylibdir = $(pyexecdir)/$(howto_pylibdir_category)
-
-## SWIG headers are always installed into the same directory.
-
-howto_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 >
-
-## Stamps used to ensure parallel make does the right thing.  These
-## are removed by "make clean", but otherwise unused except during the
-## parallel built.  These will not be included in a tarball, because
-## the SWIG-generated files will be removed from the distribution.
-
-STAMPS += $(DEPDIR)/howto-generate-*
-
-## Other cleaned files: dependency files generated by SWIG or this Makefile
-
-MOSTLYCLEANFILES += $(DEPDIR)/*.S*
-
-## Add the .py and .cc files to the list of SWIG built sources.  The
-## .h file is sometimes built, but not always ... so that one has to
-## be added manually by the including Makefile.am .
-
-swig_built_sources += howto.py howto.cc
-
-## Various SWIG variables.  These can be overloaded in the including
-## Makefile.am by setting the variable value there, then including
-## Makefile.swig .
-
-howto_swiginclude_HEADERS =            \
-       howto.i                 \
-       $(howto_swiginclude_headers)
-
-howto_pylib_LTLIBRARIES =              \
-       _howto.la
-
-_howto_la_SOURCES =                    \
-       howto.cc                        \
-       $(howto_la_swig_sources)
-
-_howto_la_LIBADD =                     \
-       $(STD_SWIG_LA_LIB_ADD)          \
-       $(howto_la_swig_libadd)
-
-_howto_la_LDFLAGS =                    \
-       $(STD_SWIG_LA_LD_FLAGS)         \
-       $(howto_la_swig_ldflags)
-
-_howto_la_CXXFLAGS =                   \
-       $(STD_SWIG_CXX_FLAGS)           \
-       $(howto_la_swig_cxxflags)
-
-howto_python_PYTHON =                  \
-       howto.py                        \
-       $(howto_python)
-
-## Entry rule for running SWIG
-
-howto.h howto.py howto.cc: howto.i
-## This rule will get called only when MAKE decides that one of the
-## targets needs to be created or re-created, because:
-##
-## * The .i file is newer than any or all of the generated files;
-##
-## * Any or all of the .cc, .h, or .py files does not exist and is
-##   needed (in the case this file is not needed, the rule for it is
-##   ignored); or
-##
-## * Some SWIG-based dependecy of the .cc file isn't met and hence the
-##   .cc file needs be be regenerated.  Explanation: Because MAKE
-##   knows how to handle dependencies for .cc files (regardless of
-##   their name or extension), then the .cc file is used as a target
-##   instead of the .i file -- but with the dependencies of the .i
-##   file.  It is this last reason why the line:
-##
-##             if test -f $@; then :; else
-##
-##   cannot be used in this case: If a .i file dependecy is not met,
-##   then the .cc file needs to be rebuilt.  But if the stamp is newer
-##   than the .cc file, and the .cc file exists, then in the original
-##   version (with the 'test' above) the internal MAKE call will not
-##   be issued and hence the .cc file will not be rebuilt.
-##
-## Once execution gets to here, it should always proceed no matter the
-## state of a stamp (as discussed in link above).  The
-## $(DEPDIR)/howto-generate stuff is used to allow for parallel
-## builds to "do the right thing".  The stamp has no relationship with
-## either the target files or dependency file; it is used solely for
-## the protection of multiple builds during a given call to MAKE.
-##
-## Catch signals SIGHUP (1), SIGINT (2), SIGPIPE (13), and SIGTERM
-## (15).  At a caught signal, the quoted command will be issued before
-## exiting.  In this case, remove any stamp, whether temporary of not.
-## The trap is valid until the process exits; the process includes all
-## commands appended via "\"s.
-##
-       trap 'rm -rf $(DEPDIR)/howto-generate-*' 1 2 13 15; \
-##
-## Create a temporary directory, which acts as a lock.  The first
-## process to create the directory will succeed and issue the MAKE
-## command to do the actual work, while all subsequent processes will
-## fail -- leading them to wait for the first process to finish.
-##
-       if mkdir $(DEPDIR)/howto-generate-lock 2>/dev/null; then \
-##
-## This code is being executed by the first process to succeed in
-## creating the directory lock.
-##
-## Remove the stamp associated with this filename.
-##
-               rm -f $(DEPDIR)/howto-generate-stamp; \
-##
-## Tell MAKE to run the rule for creating this stamp.
-##
-               $(MAKE) $(AM_MAKEFLAGS) $(DEPDIR)/howto-generate-stamp WHAT=$<; \
-##
-## Now that the .cc, .h, and .py files have been (re)created from the
-## .i file, future checking of this rule during the same MAKE
-## execution will come back that the rule doesn't need to be executed
-## because none of the conditions mentioned at the start of this rule
-## will be positive.  Remove the the directory lock, which frees up
-## any waiting process(es) to continue.
-##
-               rmdir $(DEPDIR)/howto-generate-lock; \
-       else \
-##
-## This code is being executed by any follower processes while the
-## directory lock is in place.
-##
-## Wait until the first process is done, testing once per second.
-##
-               while test -d $(DEPDIR)/howto-generate-lock; do \
-                       sleep 1; \
-               done; \
-##
-## Succeed if and only if the first process succeeded; exit this
-## process returning the status of the generated stamp.
-##
-               test -f $(DEPDIR)/howto-generate-stamp; \
-               exit $$?; \
-       fi;
-
-$(DEPDIR)/howto-generate-stamp:
-## This rule will be called only by the first process issuing the
-## above rule to succeed in creating the lock directory, after
-## removing the actual stamp file in order to guarantee that MAKE will
-## execute this rule.
-##
-## Call SWIG to generate the various output files; special
-## post-processing on 'mingw32' host OS for the dependency file.
-##
-       if $(SWIG) $(STD_SWIG_PYTHON_ARGS) $(howto_swig_args) \
-               -MD -MF $(DEPDIR)/howto.Std \
-               -module howto -o howto.cc $(WHAT); then \
-           if test $(host_os) = mingw32; then \
-               $(RM) $(DEPDIR)/howto.Sd; \
-               $(SED) 's,\\\\,/,g' < $(DEPDIR)/howto.Std \
-                       > $(DEPDIR)/howto.Sd; \
-               $(RM) $(DEPDIR)/howto.Std; \
-               $(MV) $(DEPDIR)/howto.Sd $(DEPDIR)/howto.Std; \
-           fi; \
-       else \
-           $(RM) $(DEPDIR)/howto.S*; exit 1; \
-       fi;
-##
-## Mess with the SWIG output .Std dependency file, to create a
-## dependecy file valid for the input .i file: Basically, simulate the
-## dependency file created for libraries by GNU's libtool for C++,
-## where all of the dependencies for the target are first listed, then
-## each individual dependency is listed as a target with no further
-## dependencies.
-##
-## (1) remove the current dependency file
-##
-       $(RM) $(DEPDIR)/howto.d
-##
-## (2) Copy the whole SWIG file:
-##
-       cp $(DEPDIR)/howto.Std $(DEPDIR)/howto.d
-##
-## (3) all a carriage return to the end of the dependency file.
-##
-       echo "" >> $(DEPDIR)/howto.d
-##
-## (4) from the SWIG file, remove the first line (the target); remove
-##     trailing " \" and " " from each line.  Append ":" to each line,
-##     followed by 2 carriage returns, then append this to the end of
-##     the dependency file.
-##
-       $(SED) -e '1d;s, \\,,g;s, ,,g' < $(DEPDIR)/howto.Std | \
-               awk '{ printf "%s:\n\n", $$0 }' >> $(DEPDIR)/howto.d
-##
-## (5) remove the SWIG-generated file
-##
-       $(RM) $(DEPDIR)/howto.Std
-##
-## Create the stamp for this filename generation, to signal success in
-## executing this rule; allows other threads waiting on this process
-## to continue.
-##
-       touch $(DEPDIR)/howto-generate-stamp
-
-# KLUDGE: Force runtime include of a SWIG dependency file.  This is
-# not guaranteed to be portable, but will probably work.  If it works,
-# we have accurate dependencies for our swig stuff, which is good.
-
-@am__include@ @am__quote@./$(DEPDIR)/howto.d@am__quote@
-
diff --git a/gr-howto-write-a-block/src/lib/howto.i b/gr-howto-write-a-block/src/lib/howto.i
deleted file mode 100644 (file)
index c3dae9d..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* -*- c++ -*- */
-
-%include "gnuradio.i"                  // the common stuff
-
-%{
-#include "howto_square_ff.h"
-#include "howto_square2_ff.h"
-%}
-
-// ----------------------------------------------------------------
-
-/*
- * First arg is the package prefix.
- * Second arg is the name of the class minus the prefix.
- *
- * This does some behind-the-scenes magic so we can
- * access howto_square_ff from python as howto.square_ff
- */
-GR_SWIG_BLOCK_MAGIC(howto,square_ff);
-
-howto_square_ff_sptr howto_make_square_ff ();
-
-class howto_square_ff : public gr_block
-{
-private:
-  howto_square_ff ();
-};
-
-// ----------------------------------------------------------------
-
-GR_SWIG_BLOCK_MAGIC(howto,square2_ff);
-
-howto_square2_ff_sptr howto_make_square2_ff ();
-
-class howto_square2_ff : public gr_sync_block
-{
-private:
-  howto_square2_ff ();
-};
diff --git a/gr-howto-write-a-block/src/lib/howto_square2_ff.cc b/gr-howto-write-a-block/src/lib/howto_square2_ff.cc
deleted file mode 100644 (file)
index e86db93..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004 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.
- */
-
-/*
- * config.h is generated by configure.  It contains the results
- * of probing for features, options etc.  It should be the first
- * file included in your .cc file.
- */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <howto_square2_ff.h>
-#include <gr_io_signature.h>
-
-/*
- * Create a new instance of howto_square2_ff and return
- * a boost shared_ptr.  This is effectively the public constructor.
- */
-howto_square2_ff_sptr 
-howto_make_square2_ff ()
-{
-  return howto_square2_ff_sptr (new howto_square2_ff ());
-}
-
-/*
- * Specify constraints on number of input and output streams.
- * This info is used to construct the input and output signatures
- * (2nd & 3rd args to gr_block's constructor).  The input and
- * output signatures are used by the runtime system to
- * check that a valid number and type of inputs and outputs
- * are connected to this block.  In this case, we accept
- * only 1 input and 1 output.
- */
-static const int MIN_IN = 1;   // mininum number of input streams
-static const int MAX_IN = 1;   // maximum number of input streams
-static const int MIN_OUT = 1;  // minimum number of output streams
-static const int MAX_OUT = 1;  // maximum number of output streams
-
-/*
- * The private constructor
- */
-howto_square2_ff::howto_square2_ff ()
-  : gr_sync_block ("square2_ff",
-                  gr_make_io_signature (MIN_IN, MAX_IN, sizeof (float)),
-                  gr_make_io_signature (MIN_OUT, MAX_OUT, sizeof (float)))
-{
-  // nothing else required in this example
-}
-
-/*
- * Our virtual destructor.
- */
-howto_square2_ff::~howto_square2_ff ()
-{
-  // nothing else required in this example
-}
-
-int 
-howto_square2_ff::work (int noutput_items,
-                       gr_vector_const_void_star &input_items,
-                       gr_vector_void_star &output_items)
-{
-  const float *in = (const float *) input_items[0];
-  float *out = (float *) output_items[0];
-
-  for (int i = 0; i < noutput_items; i++){
-    out[i] = in[i] * in[i];
-  }
-
-  // Tell runtime system how many output items we produced.
-  return noutput_items;
-}
diff --git a/gr-howto-write-a-block/src/lib/howto_square2_ff.h b/gr-howto-write-a-block/src/lib/howto_square2_ff.h
deleted file mode 100644 (file)
index 536b04f..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004 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_HOWTO_SQUARE2_FF_H
-#define INCLUDED_HOWTO_SQUARE2_FF_H
-
-#include <gr_sync_block.h>
-
-class howto_square2_ff;
-
-/*
- * We use boost::shared_ptr's instead of raw pointers for all access
- * to gr_blocks (and many other data structures).  The shared_ptr gets
- * us transparent reference counting, which greatly simplifies storage
- * management issues.  This is especially helpful in our hybrid
- * C++ / Python system.
- *
- * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
- *
- * As a convention, the _sptr suffix indicates a boost::shared_ptr
- */
-typedef boost::shared_ptr<howto_square2_ff> howto_square2_ff_sptr;
-
-/*!
- * \brief Return a shared_ptr to a new instance of howto_square2_ff.
- *
- * To avoid accidental use of raw pointers, howto_square2_ff's
- * constructor is private.  howto_make_square2_ff is the public
- * interface for creating new instances.
- */
-howto_square2_ff_sptr howto_make_square2_ff ();
-
-/*!
- * \brief square2 a stream of floats.
- * \ingroup block
- *
- * This uses the preferred technique: subclassing gr_sync_block.
- */
-class howto_square2_ff : public gr_sync_block
-{
-private:
-  // The friend declaration allows howto_make_square2_ff to
-  // access the private constructor.
-
-  friend howto_square2_ff_sptr howto_make_square2_ff ();
-
-  howto_square2_ff ();         // private constructor
-
- public:
-  ~howto_square2_ff ();        // public destructor
-
-  // Where all the action really happens
-
-  int work (int noutput_items,
-           gr_vector_const_void_star &input_items,
-           gr_vector_void_star &output_items);
-};
-
-#endif /* INCLUDED_HOWTO_SQUARE2_FF_H */
diff --git a/gr-howto-write-a-block/src/lib/howto_square_ff.cc b/gr-howto-write-a-block/src/lib/howto_square_ff.cc
deleted file mode 100644 (file)
index 5ab45d1..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004 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.
- */
-
-/*
- * config.h is generated by configure.  It contains the results
- * of probing for features, options etc.  It should be the first
- * file included in your .cc file.
- */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <howto_square_ff.h>
-#include <gr_io_signature.h>
-
-/*
- * Create a new instance of howto_square_ff and return
- * a boost shared_ptr.  This is effectively the public constructor.
- */
-howto_square_ff_sptr 
-howto_make_square_ff ()
-{
-  return howto_square_ff_sptr (new howto_square_ff ());
-}
-
-/*
- * Specify constraints on number of input and output streams.
- * This info is used to construct the input and output signatures
- * (2nd & 3rd args to gr_block's constructor).  The input and
- * output signatures are used by the runtime system to
- * check that a valid number and type of inputs and outputs
- * are connected to this block.  In this case, we accept
- * only 1 input and 1 output.
- */
-static const int MIN_IN = 1;   // mininum number of input streams
-static const int MAX_IN = 1;   // maximum number of input streams
-static const int MIN_OUT = 1;  // minimum number of output streams
-static const int MAX_OUT = 1;  // maximum number of output streams
-
-/*
- * The private constructor
- */
-howto_square_ff::howto_square_ff ()
-  : gr_block ("square_ff",
-             gr_make_io_signature (MIN_IN, MAX_IN, sizeof (float)),
-             gr_make_io_signature (MIN_OUT, MAX_OUT, sizeof (float)))
-{
-  // nothing else required in this example
-}
-
-/*
- * Our virtual destructor.
- */
-howto_square_ff::~howto_square_ff ()
-{
-  // nothing else required in this example
-}
-
-int 
-howto_square_ff::general_work (int noutput_items,
-                              gr_vector_int &ninput_items,
-                              gr_vector_const_void_star &input_items,
-                              gr_vector_void_star &output_items)
-{
-  const float *in = (const float *) input_items[0];
-  float *out = (float *) output_items[0];
-
-  for (int i = 0; i < noutput_items; i++){
-    out[i] = in[i] * in[i];
-  }
-
-  // Tell runtime system how many input items we consumed on
-  // each input stream.
-
-  consume_each (noutput_items);
-
-  // Tell runtime system how many output items we produced.
-  return noutput_items;
-}
diff --git a/gr-howto-write-a-block/src/lib/howto_square_ff.h b/gr-howto-write-a-block/src/lib/howto_square_ff.h
deleted file mode 100644 (file)
index 092b936..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004 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_HOWTO_SQUARE_FF_H
-#define INCLUDED_HOWTO_SQUARE_FF_H
-
-#include <gr_block.h>
-
-class howto_square_ff;
-
-/*
- * We use boost::shared_ptr's instead of raw pointers for all access
- * to gr_blocks (and many other data structures).  The shared_ptr gets
- * us transparent reference counting, which greatly simplifies storage
- * management issues.  This is especially helpful in our hybrid
- * C++ / Python system.
- *
- * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
- *
- * As a convention, the _sptr suffix indicates a boost::shared_ptr
- */
-typedef boost::shared_ptr<howto_square_ff> howto_square_ff_sptr;
-
-/*!
- * \brief Return a shared_ptr to a new instance of howto_square_ff.
- *
- * To avoid accidental use of raw pointers, howto_square_ff's
- * constructor is private.  howto_make_square_ff is the public
- * interface for creating new instances.
- */
-howto_square_ff_sptr howto_make_square_ff ();
-
-/*!
- * \brief square a stream of floats.
- * \ingroup block
- *
- * \sa howto_square2_ff for a version that subclasses gr_sync_block.
- */
-class howto_square_ff : public gr_block
-{
-private:
-  // The friend declaration allows howto_make_square_ff to
-  // access the private constructor.
-
-  friend howto_square_ff_sptr howto_make_square_ff ();
-
-  howto_square_ff ();          // private constructor
-
- public:
-  ~howto_square_ff (); // public destructor
-
-  // Where all the action really happens
-
-  int general_work (int noutput_items,
-                   gr_vector_int &ninput_items,
-                   gr_vector_const_void_star &input_items,
-                   gr_vector_void_star &output_items);
-};
-
-#endif /* INCLUDED_HOWTO_SQUARE_FF_H */
diff --git a/gr-howto-write-a-block/src/python/.gitignore b/gr-howto-write-a-block/src/python/.gitignore
deleted file mode 100644 (file)
index bf03975..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-/Makefile
-/Makefile.in
-/.deps
-/.libs
-/*.la
-/*.lo
-/*.pyc
-/*.pyo
-/run_tests
diff --git a/gr-howto-write-a-block/src/python/Makefile.am b/gr-howto-write-a-block/src/python/Makefile.am
deleted file mode 100644 (file)
index 79f4401..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# Copyright 2004 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
-
-EXTRA_DIST = run_tests.in
-
-
-TESTS =                                \
-       run_tests
-
-
-noinst_PYTHON =                        \
-       qa_howto.py                     
diff --git a/gr-howto-write-a-block/src/python/qa_howto.py b/gr-howto-write-a-block/src/python/qa_howto.py
deleted file mode 100755 (executable)
index 0abe0e2..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2004,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 GNU Radio; see the file COPYING.  If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-# 
-
-from gnuradio import gr, gr_unittest
-import howto
-
-class qa_howto (gr_unittest.TestCase):
-
-    def setUp (self):
-        self.tb = gr.top_block ()
-
-    def tearDown (self):
-        self.tb = None
-
-    def test_001_square_ff (self):
-        src_data = (-3, 4, -5.5, 2, 3)
-        expected_result = (9, 16, 30.25, 4, 9)
-        src = gr.vector_source_f (src_data)
-        sqr = howto.square_ff ()
-        dst = gr.vector_sink_f ()
-        self.tb.connect (src, sqr)
-        self.tb.connect (sqr, dst)
-        self.tb.run ()
-        result_data = dst.data ()
-        self.assertFloatTuplesAlmostEqual (expected_result, result_data, 6)
-
-    def test_002_square2_ff (self):
-        src_data = (-3, 4, -5.5, 2, 3)
-        expected_result = (9, 16, 30.25, 4, 9)
-        src = gr.vector_source_f (src_data)
-        sqr = howto.square2_ff ()
-        dst = gr.vector_sink_f ()
-        self.tb.connect (src, sqr)
-        self.tb.connect (sqr, dst)
-        self.tb.run ()
-        result_data = dst.data ()
-        self.assertFloatTuplesAlmostEqual (expected_result, result_data, 6)
-        
-if __name__ == '__main__':
-    gr_unittest.main ()
diff --git a/gr-howto-write-a-block/src/python/run_tests.in b/gr-howto-write-a-block/src/python/run_tests.in
deleted file mode 100644 (file)
index 6e4b83e..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/bin/sh
-
-# All this strange PYTHONPATH manipulation is required to run our
-# tests using our just built shared library and swig-generated python
-# code prior to installation.
-
-# build tree == src tree unless you're doing a VPATH build.  
-# If you don't know what a VPATH build is, you're not doing one.  Relax...
-
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-
-# Where to look in the build tree for our shared library
-libbld=@abs_top_builddir@/src/lib
-# Where to look in the src tree for swig generated python code
-libsrc=@abs_top_srcdir@/src/lib
-# Where to look in the src tree for hand written python code
-py=@abs_top_srcdir@/src/python
-
-# Where to look for installed GNU Radio python modules
-# FIXME this is wrong on a distcheck.  We really need to ask gnuradio-core
-# where it put its python files.
-installed_pythondir=@pythondir@
-installed_pyexecdir=@pyexecdir@
-
-PYTHONPATH="$libbld:$libbld/.libs:$libsrc:$py:$installed_pythondir:$installed_pyexecdir:$PYTHONPATH"
-#PYTHONPATH="$libbld:$libbld/.libs:$libsrc:$py:$installed_pythondir:$installed_pyexecdir"
-
-export PYTHONPATH
-
-#
-# This is the simple part...
-# Run everything that matches qa_*.py and return the final result.
-#
-
-ok=yes
-for file in @srcdir@/qa_*.py
-do
-  if ! $file
-  then
-    ok=no
-  fi  
-done
-
-if [ $ok = yes ]
-then
-  exit 0
-else
-  exit 1
-fi
diff --git a/gr-howto-write-a-block/swig/.gitignore b/gr-howto-write-a-block/swig/.gitignore
new file mode 100644 (file)
index 0000000..9165273
--- /dev/null
@@ -0,0 +1,6 @@
+/.deps
+/.libs
+/Makefile.in
+/Makefile
+/howto.cc
+/howto.py
diff --git a/gr-howto-write-a-block/swig/Makefile.am b/gr-howto-write-a-block/swig/Makefile.am
new file mode 100644 (file)
index 0000000..8c94f50
--- /dev/null
@@ -0,0 +1,56 @@
+#
+# Copyright 2004,2005,2006,2008,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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+AM_CPPFLAGS += -I$(top_srcdir)/lib
+
+if PYTHON
+###################################
+# SWIG Python interface and library
+
+TOP_SWIG_IFILES =              \
+       howto.i
+
+# Install so that they end up available as:
+#   import gnuradio.howto
+# This ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
+howto_pythondir_category =     \
+       gnuradio
+
+howto_la_swig_libadd =         \
+       $(top_builddir)/lib/libgnuradio-howto.la
+
+include $(top_srcdir)/Makefile.swig
+
+# add some of the variables generated inside the Makefile.swig.gen
+BUILT_SOURCES = $(swig_built_sources)
+
+# Do not distribute the output of SWIG
+no_dist_files = $(swig_built_sources)
+
+# additional SWIG files to be installed
+howto_swiginclude_headers =    \
+       howto_square_ff.i \
+       howto_square2_ff.i
+
+endif
diff --git a/gr-howto-write-a-block/swig/Makefile.swig.gen b/gr-howto-write-a-block/swig/Makefile.swig.gen
new file mode 100644 (file)
index 0000000..f76cc63
--- /dev/null
@@ -0,0 +1,259 @@
+# -*- 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 howto.i
+
+## Default install locations for these files:
+##
+## Default location for the Python directory is:
+##  ${prefix}/lib/python${python_version}/site-packages/[category]/howto
+## Default location for the Python exec directory is:
+##  ${exec_prefix}/lib/python${python_version}/site-packages/[category]/howto
+##
+## 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.
+
+howto_pythondir_category ?= gnuradio/howto
+howto_pylibdir_category ?= $(howto_pythondir_category)
+howto_pythondir = $(pythondir)/$(howto_pythondir_category)
+howto_pylibdir = $(pyexecdir)/$(howto_pylibdir_category)
+
+## SWIG headers are always installed into the same directory.
+
+howto_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 >
+
+## Stamps used to ensure parallel make does the right thing.  These
+## are removed by "make clean", but otherwise unused except during the
+## parallel built.  These will not be included in a tarball, because
+## the SWIG-generated files will be removed from the distribution.
+
+STAMPS += $(DEPDIR)/howto-generate-*
+
+## Other cleaned files: dependency files generated by SWIG or this Makefile
+
+MOSTLYCLEANFILES += $(DEPDIR)/*.S*
+
+## Add the .py and .cc files to the list of SWIG built sources.  The
+## .h file is sometimes built, but not always ... so that one has to
+## be added manually by the including Makefile.am .
+
+swig_built_sources += howto.py howto.cc
+
+## Various SWIG variables.  These can be overloaded in the including
+## Makefile.am by setting the variable value there, then including
+## Makefile.swig .
+
+howto_swiginclude_HEADERS =            \
+       howto.i                 \
+       $(howto_swiginclude_headers)
+
+howto_pylib_LTLIBRARIES =              \
+       _howto.la
+
+_howto_la_SOURCES =                    \
+       howto.cc                        \
+       $(howto_la_swig_sources)
+
+_howto_la_LIBADD =                     \
+       $(STD_SWIG_LA_LIB_ADD)          \
+       $(howto_la_swig_libadd)
+
+_howto_la_LDFLAGS =                    \
+       $(STD_SWIG_LA_LD_FLAGS)         \
+       $(howto_la_swig_ldflags)
+
+_howto_la_CXXFLAGS =                   \
+       $(STD_SWIG_CXX_FLAGS)           \
+       $(howto_la_swig_cxxflags)
+
+howto_python_PYTHON =                  \
+       howto.py                        \
+       $(howto_python)
+
+## Entry rule for running SWIG
+
+howto.h howto.py howto.cc: howto.i
+## This rule will get called only when MAKE decides that one of the
+## targets needs to be created or re-created, because:
+##
+## * The .i file is newer than any or all of the generated files;
+##
+## * Any or all of the .cc, .h, or .py files does not exist and is
+##   needed (in the case this file is not needed, the rule for it is
+##   ignored); or
+##
+## * Some SWIG-based dependecy of the .cc file isn't met and hence the
+##   .cc file needs be be regenerated.  Explanation: Because MAKE
+##   knows how to handle dependencies for .cc files (regardless of
+##   their name or extension), then the .cc file is used as a target
+##   instead of the .i file -- but with the dependencies of the .i
+##   file.  It is this last reason why the line:
+##
+##             if test -f $@; then :; else
+##
+##   cannot be used in this case: If a .i file dependecy is not met,
+##   then the .cc file needs to be rebuilt.  But if the stamp is newer
+##   than the .cc file, and the .cc file exists, then in the original
+##   version (with the 'test' above) the internal MAKE call will not
+##   be issued and hence the .cc file will not be rebuilt.
+##
+## Once execution gets to here, it should always proceed no matter the
+## state of a stamp (as discussed in link above).  The
+## $(DEPDIR)/howto-generate stuff is used to allow for parallel
+## builds to "do the right thing".  The stamp has no relationship with
+## either the target files or dependency file; it is used solely for
+## the protection of multiple builds during a given call to MAKE.
+##
+## Catch signals SIGHUP (1), SIGINT (2), SIGPIPE (13), and SIGTERM
+## (15).  At a caught signal, the quoted command will be issued before
+## exiting.  In this case, remove any stamp, whether temporary of not.
+## The trap is valid until the process exits; the process includes all
+## commands appended via "\"s.
+##
+       trap 'rm -rf $(DEPDIR)/howto-generate-*' 1 2 13 15; \
+##
+## Create a temporary directory, which acts as a lock.  The first
+## process to create the directory will succeed and issue the MAKE
+## command to do the actual work, while all subsequent processes will
+## fail -- leading them to wait for the first process to finish.
+##
+       if mkdir $(DEPDIR)/howto-generate-lock 2>/dev/null; then \
+##
+## This code is being executed by the first process to succeed in
+## creating the directory lock.
+##
+## Remove the stamp associated with this filename.
+##
+               rm -f $(DEPDIR)/howto-generate-stamp; \
+##
+## Tell MAKE to run the rule for creating this stamp.
+##
+               $(MAKE) $(AM_MAKEFLAGS) $(DEPDIR)/howto-generate-stamp WHAT=$<; \
+##
+## Now that the .cc, .h, and .py files have been (re)created from the
+## .i file, future checking of this rule during the same MAKE
+## execution will come back that the rule doesn't need to be executed
+## because none of the conditions mentioned at the start of this rule
+## will be positive.  Remove the the directory lock, which frees up
+## any waiting process(es) to continue.
+##
+               rmdir $(DEPDIR)/howto-generate-lock; \
+       else \
+##
+## This code is being executed by any follower processes while the
+## directory lock is in place.
+##
+## Wait until the first process is done, testing once per second.
+##
+               while test -d $(DEPDIR)/howto-generate-lock; do \
+                       sleep 1; \
+               done; \
+##
+## Succeed if and only if the first process succeeded; exit this
+## process returning the status of the generated stamp.
+##
+               test -f $(DEPDIR)/howto-generate-stamp; \
+               exit $$?; \
+       fi;
+
+$(DEPDIR)/howto-generate-stamp:
+## This rule will be called only by the first process issuing the
+## above rule to succeed in creating the lock directory, after
+## removing the actual stamp file in order to guarantee that MAKE will
+## execute this rule.
+##
+## Call SWIG to generate the various output files; special
+## post-processing on 'mingw32' host OS for the dependency file.
+##
+       if $(SWIG) $(STD_SWIG_PYTHON_ARGS) $(howto_swig_args) \
+               -MD -MF $(DEPDIR)/howto.Std \
+               -module howto -o howto.cc $(WHAT); then \
+           if test $(host_os) = mingw32; then \
+               $(RM) $(DEPDIR)/howto.Sd; \
+               $(SED) 's,\\\\,/,g' < $(DEPDIR)/howto.Std \
+                       > $(DEPDIR)/howto.Sd; \
+               $(RM) $(DEPDIR)/howto.Std; \
+               $(MV) $(DEPDIR)/howto.Sd $(DEPDIR)/howto.Std; \
+           fi; \
+       else \
+           $(RM) $(DEPDIR)/howto.S*; exit 1; \
+       fi;
+##
+## Mess with the SWIG output .Std dependency file, to create a
+## dependecy file valid for the input .i file: Basically, simulate the
+## dependency file created for libraries by GNU's libtool for C++,
+## where all of the dependencies for the target are first listed, then
+## each individual dependency is listed as a target with no further
+## dependencies.
+##
+## (1) remove the current dependency file
+##
+       $(RM) $(DEPDIR)/howto.d
+##
+## (2) Copy the whole SWIG file:
+##
+       cp $(DEPDIR)/howto.Std $(DEPDIR)/howto.d
+##
+## (3) all a carriage return to the end of the dependency file.
+##
+       echo "" >> $(DEPDIR)/howto.d
+##
+## (4) from the SWIG file, remove the first line (the target); remove
+##     trailing " \" and " " from each line.  Append ":" to each line,
+##     followed by 2 carriage returns, then append this to the end of
+##     the dependency file.
+##
+       $(SED) -e '1d;s, \\,,g;s, ,,g' < $(DEPDIR)/howto.Std | \
+               awk '{ printf "%s:\n\n", $$0 }' >> $(DEPDIR)/howto.d
+##
+## (5) remove the SWIG-generated file
+##
+       $(RM) $(DEPDIR)/howto.Std
+##
+## Create the stamp for this filename generation, to signal success in
+## executing this rule; allows other threads waiting on this process
+## to continue.
+##
+       touch $(DEPDIR)/howto-generate-stamp
+
+# KLUDGE: Force runtime include of a SWIG dependency file.  This is
+# not guaranteed to be portable, but will probably work.  If it works,
+# we have accurate dependencies for our swig stuff, which is good.
+
+@am__include@ @am__quote@./$(DEPDIR)/howto.d@am__quote@
+
diff --git a/gr-howto-write-a-block/swig/howto.i b/gr-howto-write-a-block/swig/howto.i
new file mode 100644 (file)
index 0000000..8dc5020
--- /dev/null
@@ -0,0 +1,11 @@
+/* -*- c++ -*- */
+
+%include "gnuradio.i"                  // the common stuff
+
+%{
+#include "howto_square_ff.h"
+#include "howto_square2_ff.h"
+%}
+
+%include "howto_square_ff.i"
+%include "howto_square2_ff.i"
diff --git a/gr-howto-write-a-block/swig/howto_square2_ff.i b/gr-howto-write-a-block/swig/howto_square2_ff.i
new file mode 100644 (file)
index 0000000..683a93d
--- /dev/null
@@ -0,0 +1,9 @@
+GR_SWIG_BLOCK_MAGIC(howto,square2_ff);
+
+howto_square2_ff_sptr howto_make_square2_ff ();
+
+class howto_square2_ff : public gr_sync_block
+{
+private:
+  howto_square2_ff ();
+};
diff --git a/gr-howto-write-a-block/swig/howto_square_ff.i b/gr-howto-write-a-block/swig/howto_square_ff.i
new file mode 100644 (file)
index 0000000..f8ae769
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * First arg is the package prefix.
+ * Second arg is the name of the class minus the prefix.
+ *
+ * This does some behind-the-scenes magic so we can
+ * access howto_square_ff from python as howto.square_ff
+ */
+GR_SWIG_BLOCK_MAGIC(howto,square_ff);
+
+howto_square_ff_sptr howto_make_square_ff ();
+
+class howto_square_ff : public gr_block
+{
+private:
+  howto_square_ff ();
+};
diff --git a/gr-howto-write-a-block/version.sh b/gr-howto-write-a-block/version.sh
new file mode 100644 (file)
index 0000000..b2cad87
--- /dev/null
@@ -0,0 +1,4 @@
+MAJOR_VERSION=3
+API_COMPAT=3
+MINOR_VERSION=git
+MAINT_VERSION=