From a62f90d8cc96b9dea9289ad6e420d1c0b16f6c36 Mon Sep 17 00:00:00 2001
From: Martin Braun <martin.braun@kit.edu>
Date: Thu, 24 Jan 2013 19:33:03 +0100
Subject: utils: added modtool

---
 gr-utils/src/python/modtool/modtool_info.py | 137 ++++++++++++++++++++++++++++
 1 file changed, 137 insertions(+)
 create mode 100644 gr-utils/src/python/modtool/modtool_info.py

(limited to 'gr-utils/src/python/modtool/modtool_info.py')

diff --git a/gr-utils/src/python/modtool/modtool_info.py b/gr-utils/src/python/modtool/modtool_info.py
new file mode 100644
index 0000000000..80fa278321
--- /dev/null
+++ b/gr-utils/src/python/modtool/modtool_info.py
@@ -0,0 +1,137 @@
+""" Returns information about a module """
+
+import os
+from optparse import OptionGroup
+
+from modtool_base import ModTool
+from util_functions import get_modname
+
+### Info module ##############################################################
+class ModToolInfo(ModTool):
+    """ Return information about a given module """
+    name = 'info'
+    aliases = ('getinfo', 'inf')
+    def __init__(self):
+        ModTool.__init__(self)
+
+    def setup_parser(self):
+        " Initialise the option parser for 'gr_modtool.py info' "
+        parser = ModTool.setup_parser(self)
+        parser.usage = '%prog info [options]. \n Call %prog without any options to run it interactively.'
+        ogroup = OptionGroup(parser, "Info options")
+        ogroup.add_option("--python-readable", action="store_true", default=None,
+                help="Return the output in a format that's easier to read for Python scripts.")
+        ogroup.add_option("--suggested-dirs", default=None, type="string",
+                help="Suggest typical include dirs if nothing better can be detected.")
+        parser.add_option_group(ogroup)
+        return parser
+
+    def setup(self):
+        # Won't call parent's setup(), because that's too chatty
+        (self.options, self.args) = self.parser.parse_args()
+
+    def run(self):
+        """ Go, go, go! """
+        mod_info = {}
+        mod_info['base_dir'] = self._get_base_dir(self.options.directory)
+        if mod_info['base_dir'] is None:
+            if self.options.python_readable:
+                print '{}'
+            else:
+                print "No module found."
+            exit(1)
+        os.chdir(mod_info['base_dir'])
+        mod_info['modname'] = get_modname()
+        if mod_info['modname'] is None:
+            if self.options.python_readable:
+                print '{}'
+            else:
+                print "No module found."
+            exit(1)
+        if self._info['version'] == '36' and os.path.isdir(os.path.join('include', mod_info['modname'])):
+            self._info['version'] = '37'
+        mod_info['version'] = self._info['version']
+        if 'is_component' in self._info.keys():
+            mod_info['is_component'] = True
+        mod_info['incdirs'] = []
+        mod_incl_dir = os.path.join(mod_info['base_dir'], 'include')
+        if os.path.isdir(os.path.join(mod_incl_dir, mod_info['modname'])):
+            mod_info['incdirs'].append(os.path.join(mod_incl_dir, mod_info['modname']))
+        else:
+            mod_info['incdirs'].append(mod_incl_dir)
+        build_dir = self._get_build_dir(mod_info)
+        if build_dir is not None:
+            mod_info['build_dir'] = build_dir
+            mod_info['incdirs'] += self._get_include_dirs(mod_info)
+        if self.options.python_readable:
+            print str(mod_info)
+        else:
+            self._pretty_print(mod_info)
+
+    def _get_base_dir(self, start_dir):
+        """ Figure out the base dir (where the top-level cmake file is) """
+        base_dir = os.path.abspath(start_dir)
+        if self._check_directory(base_dir):
+            return base_dir
+        else:
+            (up_dir, this_dir) = os.path.split(base_dir)
+            if os.path.split(up_dir)[1] == 'include':
+                up_dir = os.path.split(up_dir)[0]
+            if self._check_directory(up_dir):
+                return up_dir
+        return None
+
+    def _get_build_dir(self, mod_info):
+        """ Figure out the build dir (i.e. where you run 'cmake'). This checks
+        for a file called CMakeCache.txt, which is created when running cmake.
+        If that hasn't happened, the build dir cannot be detected, unless it's
+        called 'build', which is then assumed to be the build dir. """
+        base_build_dir = mod_info['base_dir']
+        if 'is_component' in mod_info.keys():
+            (base_build_dir, rest_dir) = os.path.split(base_build_dir)
+        has_build_dir = os.path.isdir(os.path.join(base_build_dir , 'build'))
+        if (has_build_dir and os.path.isfile(os.path.join(base_build_dir, 'CMakeCache.txt'))):
+            return os.path.join(base_build_dir, 'build')
+        else:
+            for (dirpath, dirnames, filenames) in os.walk(base_build_dir):
+                if 'CMakeCache.txt' in filenames:
+                    return dirpath
+        if has_build_dir:
+            return os.path.join(base_build_dir, 'build')
+        return None
+
+    def _get_include_dirs(self, mod_info):
+        """ Figure out include dirs for the make process. """
+        inc_dirs = []
+        path_or_internal = {True: 'INTERNAL',
+                            False: 'PATH'}['is_component' in mod_info.keys()]
+        try:
+            cmakecache_fid = open(os.path.join(mod_info['build_dir'], 'CMakeCache.txt'))
+            for line in cmakecache_fid:
+                if line.find('GNURADIO_CORE_INCLUDE_DIRS:%s' % path_or_internal) != -1:
+                    inc_dirs += line.replace('GNURADIO_CORE_INCLUDE_DIRS:%s=' % path_or_internal, '').strip().split(';')
+                if line.find('GRUEL_INCLUDE_DIRS:%s' % path_or_internal) != -1:
+                    inc_dirs += line.replace('GRUEL_INCLUDE_DIRS:%s=' % path_or_internal, '').strip().split(';')
+        except IOError:
+            pass
+        if len(inc_dirs) == 0 and self.options.suggested_dirs is not None:
+            inc_dirs = [os.path.normpath(path) for path in self.options.suggested_dirs.split(':') if os.path.isdir(path)]
+        return inc_dirs
+
+    def _pretty_print(self, mod_info):
+        """ Output the module info in human-readable format """
+        index_names = {'base_dir': 'Base directory',
+                       'modname':  'Module name',
+                       'is_component':  'Is GR component',
+                       'build_dir': 'Build directory',
+                       'incdirs': 'Include directories'}
+        for key in mod_info.keys():
+            if key == 'version':
+                print "        API version: %s" % {
+                        '36': 'pre-3.7',
+                        '37': 'post-3.7',
+                        'autofoo': 'Autotools (pre-3.5)'
+                        }[mod_info['version']]
+            else:
+                print '%19s: %s' % (index_names[key], mod_info[key])
+
-- 
cgit v1.2.3


From 9ef0f125355a4541c691f18d05ad7ca7b6f7125e Mon Sep 17 00:00:00 2001
From: Martin Braun <martin.braun@kit.edu>
Date: Sun, 27 Jan 2013 16:57:04 +0100
Subject: modtool: added copyleft headers

---
 gr-utils/src/python/modtool/__init__.py          |  2 +-
 gr-utils/src/python/modtool/cmakefile_editor.py  | 21 ++++++++++-
 gr-utils/src/python/modtool/code_generator.py    | 21 ++++++++++-
 gr-utils/src/python/modtool/grc_xml_generator.py | 21 ++++++++++-
 gr-utils/src/python/modtool/modtool_add.py       | 21 ++++++++++-
 gr-utils/src/python/modtool/modtool_base.py      | 21 ++++++++++-
 gr-utils/src/python/modtool/modtool_disable.py   | 21 ++++++++++-
 gr-utils/src/python/modtool/modtool_help.py      | 44 ++++++++++++------------
 gr-utils/src/python/modtool/modtool_info.py      | 21 ++++++++++-
 gr-utils/src/python/modtool/modtool_makexml.py   | 21 ++++++++++-
 gr-utils/src/python/modtool/modtool_newmod.py    | 23 +++++++++++--
 gr-utils/src/python/modtool/modtool_rm.py        | 21 ++++++++++-
 gr-utils/src/python/modtool/parser_cc_block.py   | 21 ++++++++++-
 gr-utils/src/python/modtool/templates.py         | 22 ++++++++++--
 gr-utils/src/python/modtool/util_functions.py    | 21 ++++++++++-
 15 files changed, 284 insertions(+), 38 deletions(-)

(limited to 'gr-utils/src/python/modtool/modtool_info.py')

diff --git a/gr-utils/src/python/modtool/__init__.py b/gr-utils/src/python/modtool/__init__.py
index a107472540..7935e4b482 100644
--- a/gr-utils/src/python/modtool/__init__.py
+++ b/gr-utils/src/python/modtool/__init__.py
@@ -1,5 +1,5 @@
 #
-# Copyright 2012 Free Software Foundation, Inc.
+# Copyright 2013 Free Software Foundation, Inc.
 #
 # This file is part of GNU Radio
 #
diff --git a/gr-utils/src/python/modtool/cmakefile_editor.py b/gr-utils/src/python/modtool/cmakefile_editor.py
index b182757076..ed5b714253 100644
--- a/gr-utils/src/python/modtool/cmakefile_editor.py
+++ b/gr-utils/src/python/modtool/cmakefile_editor.py
@@ -1,8 +1,27 @@
+#
+# Copyright 2013 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.
+#
 """ Edit CMakeLists.txt files """
 
 import re
 
-### CMakeFile.txt editor class ###############################################
 class CMakeFileEditor(object):
     """A tool for editing CMakeLists.txt files. """
     def __init__(self, filename, separator='\n    ', indent='    '):
diff --git a/gr-utils/src/python/modtool/code_generator.py b/gr-utils/src/python/modtool/code_generator.py
index b727f611e5..525b3d1e9a 100644
--- a/gr-utils/src/python/modtool/code_generator.py
+++ b/gr-utils/src/python/modtool/code_generator.py
@@ -1,3 +1,23 @@
+#
+# Copyright 2013 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.
+#
 """ A code generator (needed by ModToolAdd) """
 
 from templates import Templates
@@ -7,7 +27,6 @@ from util_functions import str_to_python_comment
 from util_functions import strip_default_values
 from util_functions import strip_arg_types
 
-### Code generator class #####################################################
 class GRMTemplate(Cheetah.Template.Template):
     """ An extended template class """
     def __init__(self, src, searchList):
diff --git a/gr-utils/src/python/modtool/grc_xml_generator.py b/gr-utils/src/python/modtool/grc_xml_generator.py
index 2fa61863f2..7ccd443196 100644
--- a/gr-utils/src/python/modtool/grc_xml_generator.py
+++ b/gr-utils/src/python/modtool/grc_xml_generator.py
@@ -1,7 +1,26 @@
+#
+# Copyright 2013 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
 import xml.etree.ElementTree as ET
 from util_functions import is_number, xml_indent
 
-### GRC XML Generator ########################################################
 try:
     import lxml.etree
     LXML_IMPORTED = True
diff --git a/gr-utils/src/python/modtool/modtool_add.py b/gr-utils/src/python/modtool/modtool_add.py
index 581f3b0aaf..a6c84bea85 100644
--- a/gr-utils/src/python/modtool/modtool_add.py
+++ b/gr-utils/src/python/modtool/modtool_add.py
@@ -1,3 +1,23 @@
+#
+# Copyright 2013 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
 """ Module to add new blocks """
 
 import os
@@ -12,7 +32,6 @@ from templates import Templates
 from code_generator import get_template
 import Cheetah.Template
 
-### Add new block module #####################################################
 class ModToolAdd(ModTool):
     """ Add block to the out-of-tree module. """
     name = 'add'
diff --git a/gr-utils/src/python/modtool/modtool_base.py b/gr-utils/src/python/modtool/modtool_base.py
index edb0f14eed..d824910e95 100644
--- a/gr-utils/src/python/modtool/modtool_base.py
+++ b/gr-utils/src/python/modtool/modtool_base.py
@@ -1,3 +1,23 @@
+#
+# Copyright 2013 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.
+#
 """ Base class for the modules """
 
 import os
@@ -8,7 +28,6 @@ from optparse import OptionParser, OptionGroup
 from util_functions import get_modname
 from templates import Templates
 
-### ModTool base class #######################################################
 class ModTool(object):
     """ Base class for all modtool command classes. """
     def __init__(self):
diff --git a/gr-utils/src/python/modtool/modtool_disable.py b/gr-utils/src/python/modtool/modtool_disable.py
index 67f15ad537..b0fb132451 100644
--- a/gr-utils/src/python/modtool/modtool_disable.py
+++ b/gr-utils/src/python/modtool/modtool_disable.py
@@ -1,3 +1,23 @@
+#
+# Copyright 2013 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.
+#
 """ Disable blocks module """
 
 import os
@@ -8,7 +28,6 @@ from optparse import OptionGroup
 from modtool_base import ModTool
 from cmakefile_editor import CMakeFileEditor
 
-### Disable module ###########################################################
 class ModToolDisable(ModTool):
     """ Disable block (comments out CMake entries for files) """
     name = 'disable'
diff --git a/gr-utils/src/python/modtool/modtool_help.py b/gr-utils/src/python/modtool/modtool_help.py
index a1dd3c4660..79474a9631 100644
--- a/gr-utils/src/python/modtool/modtool_help.py
+++ b/gr-utils/src/python/modtool/modtool_help.py
@@ -1,30 +1,30 @@
+#
+# Copyright 2013 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
 """ The help module """
 
-from modtool_base import ModTool
-from modtool_info import ModToolInfo
-from modtool_add import ModToolAdd
-from modtool_rm import ModToolRemove
-from modtool_newmod import ModToolNewModule
-from modtool_disable import ModToolDisable
-from modtool_makexml import ModToolMakeXML
-from util_functions import get_command_from_argv
+from gnuradio.modtool import *
+from util_functions import get_command_from_argv, get_class_dict
 from templates import Templates
 
-def get_class_dict():
-    " Return a dictionary of the available commands in the form command->class "
-    classdict = {}
-    for g in globals().values():
-        try:
-            if issubclass(g, ModTool):
-                classdict[g.name] = g
-                for a in g.aliases:
-                    classdict[a] = g
-        except (TypeError, AttributeError):
-            pass
-    return classdict
-
 
-### Help module ##############################################################
 def print_class_descriptions():
     ''' Go through all ModTool* classes and print their name,
         alias and description. '''
diff --git a/gr-utils/src/python/modtool/modtool_info.py b/gr-utils/src/python/modtool/modtool_info.py
index 80fa278321..e774db9114 100644
--- a/gr-utils/src/python/modtool/modtool_info.py
+++ b/gr-utils/src/python/modtool/modtool_info.py
@@ -1,3 +1,23 @@
+#
+# Copyright 2013 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.
+#
 """ Returns information about a module """
 
 import os
@@ -6,7 +26,6 @@ from optparse import OptionGroup
 from modtool_base import ModTool
 from util_functions import get_modname
 
-### Info module ##############################################################
 class ModToolInfo(ModTool):
     """ Return information about a given module """
     name = 'info'
diff --git a/gr-utils/src/python/modtool/modtool_makexml.py b/gr-utils/src/python/modtool/modtool_makexml.py
index 5a1a24f1bb..acf3e459c0 100644
--- a/gr-utils/src/python/modtool/modtool_makexml.py
+++ b/gr-utils/src/python/modtool/modtool_makexml.py
@@ -1,3 +1,23 @@
+#
+# Copyright 2013 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.
+#
 """ Automatically create XML bindings for GRC from block code """
 
 import sys
@@ -11,7 +31,6 @@ from parser_cc_block import ParserCCBlock
 from grc_xml_generator import GRCXMLGenerator
 from cmakefile_editor import CMakeFileEditor
 
-### Remove module ###########################################################
 class ModToolMakeXML(ModTool):
     """ Make XML file for GRC block bindings """
     name = 'makexml'
diff --git a/gr-utils/src/python/modtool/modtool_newmod.py b/gr-utils/src/python/modtool/modtool_newmod.py
index 0c69cb69e8..7a5f635dde 100644
--- a/gr-utils/src/python/modtool/modtool_newmod.py
+++ b/gr-utils/src/python/modtool/modtool_newmod.py
@@ -1,3 +1,23 @@
+#
+# Copyright 2013 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.
+#
 """ Create a whole new out-of-tree module """
 
 import shutil
@@ -6,7 +26,6 @@ import re
 from optparse import OptionGroup
 from modtool_base import ModTool
 
-### New out-of-tree-mod module ###############################################
 class ModToolNewModule(ModTool):
     """ Create a new out-of-tree module """
     name = 'newmod'
@@ -36,7 +55,6 @@ class ModToolNewModule(ModTool):
         self._dir = options.directory
         if self._dir == '.':
             self._dir = './gr-%s' % self._info['modname']
-        print 'Module directory is "%s".' % self._dir
         try:
             os.stat(self._dir)
         except OSError:
@@ -56,6 +74,7 @@ class ModToolNewModule(ModTool):
             shutil.copytree('/home/braun/.usrlocal/share/gnuradio/modtool/gr-newmod', self._dir)
             os.chdir(self._dir)
         except OSError:
+            print 'FAILED'
             print 'Could not create directory %s. Quitting.' % self._dir
             exit(2)
         for root, dirs, files in os.walk('.'):
diff --git a/gr-utils/src/python/modtool/modtool_rm.py b/gr-utils/src/python/modtool/modtool_rm.py
index 16bfeb34ce..bdbd802f33 100644
--- a/gr-utils/src/python/modtool/modtool_rm.py
+++ b/gr-utils/src/python/modtool/modtool_rm.py
@@ -1,3 +1,23 @@
+#
+# Copyright 2013 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.
+#
 """ Remove blocks module """
 
 import os
@@ -10,7 +30,6 @@ from util_functions import remove_pattern_from_file
 from modtool_base import ModTool
 from cmakefile_editor import CMakeFileEditor
 
-### Remove module ###########################################################
 class ModToolRemove(ModTool):
     """ Remove block (delete files and remove Makefile entries) """
     name = 'remove'
diff --git a/gr-utils/src/python/modtool/parser_cc_block.py b/gr-utils/src/python/modtool/parser_cc_block.py
index 447fe113dd..d11353cc7a 100644
--- a/gr-utils/src/python/modtool/parser_cc_block.py
+++ b/gr-utils/src/python/modtool/parser_cc_block.py
@@ -1,8 +1,27 @@
+#
+# Copyright 2013 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.
+#
 ''' A parser for blocks written in C++ '''
 import re
 import sys
 
-### Parser for CC blocks ####################################################
 def dummy_translator(the_type, default_v=None):
     """ Doesn't really translate. """
     return the_type
diff --git a/gr-utils/src/python/modtool/templates.py b/gr-utils/src/python/modtool/templates.py
index f41049c5ae..91d8370b98 100644
--- a/gr-utils/src/python/modtool/templates.py
+++ b/gr-utils/src/python/modtool/templates.py
@@ -1,10 +1,28 @@
+#
+# Copyright 2013 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.
+#
 ''' All the templates for skeleton files (needed by ModToolAdd) '''
 
 from datetime import datetime
 
-### Templates ################################################################
 Templates = {}
-Templates36 = {}
 
 # Default licence
 Templates['defaultlicense'] = '''
diff --git a/gr-utils/src/python/modtool/util_functions.py b/gr-utils/src/python/modtool/util_functions.py
index 029ae04bfa..33d8ad3339 100644
--- a/gr-utils/src/python/modtool/util_functions.py
+++ b/gr-utils/src/python/modtool/util_functions.py
@@ -1,9 +1,28 @@
+#
+# Copyright 2013 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.
+#
 """ Utility functions for gr_modtool.py """
 
 import re
 import sys
 
-### Utility functions ########################################################
 def get_command_from_argv(possible_cmds):
     """ Read the requested command from argv. This can't be done with optparse,
     since the option parser isn't defined before the command is known, and
-- 
cgit v1.2.3


From 2d695b3c4c86b5c206f95dcc1d71f97d808d98b8 Mon Sep 17 00:00:00 2001
From: Martin Braun <martin.braun@kit.edu>
Date: Mon, 28 Jan 2013 15:26:05 +0100
Subject: modtool: cleanup, bugfixes

---
 gr-utils/src/python/gr_modtool                  | 20 +-----------------
 gr-utils/src/python/modtool/__init__.py         |  5 +++--
 gr-utils/src/python/modtool/cmakefile_editor.py |  2 +-
 gr-utils/src/python/modtool/modtool_add.py      |  1 -
 gr-utils/src/python/modtool/modtool_base.py     | 28 ++++++++++++++++++++-----
 gr-utils/src/python/modtool/modtool_disable.py  | 19 ++---------------
 gr-utils/src/python/modtool/modtool_help.py     |  4 ++--
 gr-utils/src/python/modtool/modtool_info.py     |  2 +-
 gr-utils/src/python/modtool/modtool_makexml.py  | 26 +++++++----------------
 gr-utils/src/python/modtool/modtool_newmod.py   |  2 +-
 gr-utils/src/python/modtool/modtool_rm.py       | 19 ++---------------
 gr-utils/src/python/modtool/parser_cc_block.py  |  5 +++--
 gr-utils/src/python/modtool/templates.py        |  6 +++---
 gr-utils/src/python/modtool/util_functions.py   | 19 ++++-------------
 14 files changed, 53 insertions(+), 105 deletions(-)

(limited to 'gr-utils/src/python/modtool/modtool_info.py')

diff --git a/gr-utils/src/python/gr_modtool b/gr-utils/src/python/gr_modtool
index bc41d56f55..8c5c710aff 100755
--- a/gr-utils/src/python/gr_modtool
+++ b/gr-utils/src/python/gr_modtool
@@ -24,24 +24,9 @@
 import sys
 from gnuradio.modtool import *
 
-def get_class_dict():
-    " Return a dictionary of the available commands in the form command->class "
-    classdict = {}
-    for g in globals().values():
-        try:
-            if issubclass(g, ModTool):
-                classdict[g.name] = g
-                for a in g.aliases:
-                    classdict[a] = g
-        except (TypeError, AttributeError):
-            pass
-    return classdict
-
-
-### Main code ################################################################
 def main():
     """ Here we go. Parse command, choose class and run. """
-    cmd_dict = get_class_dict()
+    cmd_dict = get_class_dict(globals().values())
     command = get_command_from_argv(cmd_dict.keys())
     if command is None:
         print 'Usage:' + templates.Templates['usage']
@@ -51,9 +36,6 @@ def main():
     modtool.run()
 
 if __name__ == '__main__':
-    if not ((sys.version_info[0] > 2) or
-            (sys.version_info[0] == 2 and sys.version_info[1] >= 7)):
-        print "Using Python < 2.7 is not recommended for gr_modtool."
     try:
         main()
     except KeyboardInterrupt:
diff --git a/gr-utils/src/python/modtool/__init__.py b/gr-utils/src/python/modtool/__init__.py
index 7935e4b482..a242722ab4 100644
--- a/gr-utils/src/python/modtool/__init__.py
+++ b/gr-utils/src/python/modtool/__init__.py
@@ -22,13 +22,14 @@
 from cmakefile_editor import CMakeFileEditor
 from code_generator import GRMTemplate
 from grc_xml_generator import GRCXMLGenerator
+from modtool_base import ModTool, get_class_dict
 from modtool_add import ModToolAdd
-from modtool_base import ModTool
 from modtool_disable import ModToolDisable
-from modtool_help import ModToolHelp
 from modtool_info import ModToolInfo
 from modtool_makexml import ModToolMakeXML
 from modtool_newmod import ModToolNewModule
 from modtool_rm import ModToolRemove
+# Leave this at the end
+from modtool_help import ModToolHelp
 from parser_cc_block import ParserCCBlock
 from util_functions import *
diff --git a/gr-utils/src/python/modtool/cmakefile_editor.py b/gr-utils/src/python/modtool/cmakefile_editor.py
index 92121dda3b..3d90b8d163 100644
--- a/gr-utils/src/python/modtool/cmakefile_editor.py
+++ b/gr-utils/src/python/modtool/cmakefile_editor.py
@@ -49,7 +49,7 @@ class CMakeFileEditor(object):
         """Remove an entry from the current buffer."""
         regexp = '%s\s*\([^()]*%s[^()]*\)[^\n]*\n' % (entry, value_pattern)
         regexp = re.compile(regexp, re.MULTILINE)
-        (self.cfile, nsubs) = re.sub(regexp, '', self.cfile, count=1)
+        (self.cfile, nsubs) = re.subn(regexp, '', self.cfile, count=1)
         return nsubs
 
     def write(self):
diff --git a/gr-utils/src/python/modtool/modtool_add.py b/gr-utils/src/python/modtool/modtool_add.py
index 32cfe04408..7ca375b6f9 100644
--- a/gr-utils/src/python/modtool/modtool_add.py
+++ b/gr-utils/src/python/modtool/modtool_add.py
@@ -45,7 +45,6 @@ class ModToolAdd(ModTool):
 
     def setup_parser(self):
         parser = ModTool.setup_parser(self)
-        parser.usage = '%prog add [options]. \n Call %prog without any options to run it interactively.'
         ogroup = OptionGroup(parser, "Add module options")
         ogroup.add_option("-t", "--block-type", type="choice",
                 choices=self._block_types, default=None, help="One of %s." % ', '.join(self._block_types))
diff --git a/gr-utils/src/python/modtool/modtool_base.py b/gr-utils/src/python/modtool/modtool_base.py
index d824910e95..3f8f2bc3c7 100644
--- a/gr-utils/src/python/modtool/modtool_base.py
+++ b/gr-utils/src/python/modtool/modtool_base.py
@@ -28,6 +28,7 @@ from optparse import OptionParser, OptionGroup
 from util_functions import get_modname
 from templates import Templates
 
+
 class ModTool(object):
     """ Base class for all modtool command classes. """
     def __init__(self):
@@ -47,15 +48,17 @@ class ModTool(object):
     def setup_parser(self):
         """ Init the option parser. If derived classes need to add options,
         override this and call the parent function. """
-        parser = OptionParser(usage=Templates['usage'], add_help_option=False)
+        parser = OptionParser(add_help_option=False)
+        parser.usage = '%prog ' + self.name + ' [options] <PATTERN> \n' + \
+                       ' Call "%prog ' + self.name + '" without any options to run it interactively.'
         ogroup = OptionGroup(parser, "General options")
         ogroup.add_option("-h", "--help", action="help", help="Displays this help message.")
         ogroup.add_option("-d", "--directory", type="string", default=".",
-                help="Base directory of the module.")
+                help="Base directory of the module. Defaults to the cwd.")
         ogroup.add_option("-n", "--module-name", type="string", default=None,
-                help="Name of the GNU Radio module. If possible, this gets detected from CMakeLists.txt.")
+                help="Use this to override the current module's name (is normally autodetected).")
         ogroup.add_option("-N", "--block-name", type="string", default=None,
-                help="Name of the block, minus the module name prefix.")
+                help="Name of the block, where applicable.")
         ogroup.add_option("--skip-lib", action="store_true", default=False,
                 help="Don't do anything in the lib/ subdirectory.")
         ogroup.add_option("--skip-swig", action="store_true", default=False,
@@ -64,6 +67,8 @@ class ModTool(object):
                 help="Don't do anything in the python/ subdirectory.")
         ogroup.add_option("--skip-grc", action="store_true", default=False,
                 help="Don't do anything in the grc/ subdirectory.")
+        ogroup.add_option("-y", "--yes", action="store_true", default=False,
+                help="Answer all questions with 'yes'. This can overwrite and delete your files, so be careful.")
         parser.add_option_group(ogroup)
         return parser
 
@@ -74,7 +79,6 @@ class ModTool(object):
         if not self._check_directory(self._dir):
             print "No GNU Radio module found in the given directory. Quitting."
             sys.exit(1)
-        print "Operating in directory " + self._dir
         if options.module_name is not None:
             self._info['modname'] = options.module_name
         else:
@@ -96,6 +100,7 @@ class ModTool(object):
         self._info['blockname'] = options.block_name
         self.options = options
         self._setup_files()
+        self._info['yes'] = options.yes
 
     def _setup_files(self):
         """ Initialise the self._file[] dictionary """
@@ -156,3 +161,16 @@ class ModTool(object):
         """ Override this. """
         pass
 
+def get_class_dict(the_globals):
+    " Return a dictionary of the available commands in the form command->class "
+    classdict = {}
+    for g in the_globals:
+        try:
+            if issubclass(g, ModTool):
+                classdict[g.name] = g
+                for a in g.aliases:
+                    classdict[a] = g
+        except (TypeError, AttributeError):
+            pass
+    return classdict
+
diff --git a/gr-utils/src/python/modtool/modtool_disable.py b/gr-utils/src/python/modtool/modtool_disable.py
index b0fb132451..36725e5578 100644
--- a/gr-utils/src/python/modtool/modtool_disable.py
+++ b/gr-utils/src/python/modtool/modtool_disable.py
@@ -35,24 +35,10 @@ class ModToolDisable(ModTool):
     def __init__(self):
         ModTool.__init__(self)
 
-    def setup_parser(self):
-        " Initialise the option parser for 'gr_modtool.py rm' "
-        parser = ModTool.setup_parser(self)
-        parser.usage = '%prog disable [options]. \n Call %prog without any options to run it interactively.'
-        ogroup = OptionGroup(parser, "Disable module options")
-        ogroup.add_option("-p", "--pattern", type="string", default=None,
-                help="Filter possible choices for blocks to be disabled.")
-        ogroup.add_option("-y", "--yes", action="store_true", default=False,
-                help="Answer all questions with 'yes'.")
-        parser.add_option_group(ogroup)
-        return parser
-
     def setup(self):
         ModTool.setup(self)
         options = self.options
-        if options.pattern is not None:
-            self._info['pattern'] = options.pattern
-        elif options.block_name is not None:
+        if options.block_name is not None:
             self._info['pattern'] = options.block_name
         elif len(self.args) >= 2:
             self._info['pattern'] = self.args[1]
@@ -60,7 +46,6 @@ class ModToolDisable(ModTool):
             self._info['pattern'] = raw_input('Which blocks do you want to disable? (Regex): ')
         if len(self._info['pattern']) == 0:
             self._info['pattern'] = '.'
-        self._info['yes'] = options.yes
 
     def run(self):
         """ Go, go, go! """
@@ -123,7 +108,7 @@ class ModToolDisable(ModTool):
             swigfile = re.sub('(GR_SWIG_BLOCK_MAGIC2?.+'+blockname+'.+;)', r'//\1', swigfile)
             open(self._file['swig'], 'w').write(swigfile)
             return False
-        # List of special rules: 0: subdir, 1: filename re match, 2: function
+        # List of special rules: 0: subdir, 1: filename re match, 2: callback
         special_treatments = (
                 ('python', 'qa.+py$', _handle_py_qa),
                 ('python', '^(?!qa).+py$', _handle_py_mod),
diff --git a/gr-utils/src/python/modtool/modtool_help.py b/gr-utils/src/python/modtool/modtool_help.py
index 79474a9631..76d9fd28bd 100644
--- a/gr-utils/src/python/modtool/modtool_help.py
+++ b/gr-utils/src/python/modtool/modtool_help.py
@@ -21,7 +21,7 @@
 """ The help module """
 
 from gnuradio.modtool import *
-from util_functions import get_command_from_argv, get_class_dict
+from util_functions import get_command_from_argv
 from templates import Templates
 
 
@@ -51,7 +51,7 @@ class ModToolHelp(ModTool):
         pass
 
     def run(self):
-        cmd_dict = get_class_dict()
+        cmd_dict = get_class_dict(globals().values())
         cmds = cmd_dict.keys()
         cmds.remove(self.name)
         for a in self.aliases:
diff --git a/gr-utils/src/python/modtool/modtool_info.py b/gr-utils/src/python/modtool/modtool_info.py
index e774db9114..680bd41b99 100644
--- a/gr-utils/src/python/modtool/modtool_info.py
+++ b/gr-utils/src/python/modtool/modtool_info.py
@@ -34,7 +34,7 @@ class ModToolInfo(ModTool):
         ModTool.__init__(self)
 
     def setup_parser(self):
-        " Initialise the option parser for 'gr_modtool.py info' "
+        " Initialise the option parser for 'gr_modtool info' "
         parser = ModTool.setup_parser(self)
         parser.usage = '%prog info [options]. \n Call %prog without any options to run it interactively.'
         ogroup = OptionGroup(parser, "Info options")
diff --git a/gr-utils/src/python/modtool/modtool_makexml.py b/gr-utils/src/python/modtool/modtool_makexml.py
index 104a0fdbde..777cc09e1f 100644
--- a/gr-utils/src/python/modtool/modtool_makexml.py
+++ b/gr-utils/src/python/modtool/modtool_makexml.py
@@ -30,6 +30,7 @@ from modtool_base import ModTool
 from parser_cc_block import ParserCCBlock
 from grc_xml_generator import GRCXMLGenerator
 from cmakefile_editor import CMakeFileEditor
+from util_functions import ask_yes_no
 
 class ModToolMakeXML(ModTool):
     """ Make XML file for GRC block bindings """
@@ -38,24 +39,10 @@ class ModToolMakeXML(ModTool):
     def __init__(self):
         ModTool.__init__(self)
 
-    def setup_parser(self):
-        " Initialise the option parser for 'gr_modtool.py makexml' "
-        parser = ModTool.setup_parser(self)
-        parser.usage = '%prog makexml [options]. \n Call %prog without any options to run it interactively.'
-        ogroup = OptionGroup(parser, "Make XML module options")
-        ogroup.add_option("-p", "--pattern", type="string", default=None,
-                help="Filter possible choices for blocks to be parsed.")
-        ogroup.add_option("-y", "--yes", action="store_true", default=False,
-                help="Answer all questions with 'yes'. This can overwrite existing files!")
-        parser.add_option_group(ogroup)
-        return parser
-
     def setup(self):
         ModTool.setup(self)
         options = self.options
-        if options.pattern is not None:
-            self._info['pattern'] = options.pattern
-        elif options.block_name is not None:
+        if options.block_name is not None:
             self._info['pattern'] = options.block_name
         elif len(self.args) >= 2:
             self._info['pattern'] = self.args[1]
@@ -63,7 +50,6 @@ class ModToolMakeXML(ModTool):
             self._info['pattern'] = raw_input('Which blocks do you want to parse? (Regex): ')
         if len(self._info['pattern']) == 0:
             self._info['pattern'] = '.'
-        self._info['yes'] = options.yes
 
     def run(self):
         """ Go, go, go! """
@@ -109,8 +95,11 @@ class ModToolMakeXML(ModTool):
                                'default': '2',
                                'in_constructor': False})
         if os.path.isfile(os.path.join('grc', fname_xml)):
-            # TODO add an option to keep
-            print "Warning: Overwriting existing GRC file."
+            if not self._info['yes']:
+                if not ask_yes_no('Overwrite existing GRC file?', False):
+                    return
+            else:
+                print "Warning: Overwriting existing GRC file."
         grc_generator = GRCXMLGenerator(
                 modname=self._info['modname'],
                 blockname=blockname,
@@ -167,4 +156,3 @@ class ModToolMakeXML(ModTool):
             sys.exit(1)
         return (parser.read_params(), parser.read_io_signature(), blockname)
 
-
diff --git a/gr-utils/src/python/modtool/modtool_newmod.py b/gr-utils/src/python/modtool/modtool_newmod.py
index 5e14493c3c..102d83d8df 100644
--- a/gr-utils/src/python/modtool/modtool_newmod.py
+++ b/gr-utils/src/python/modtool/modtool_newmod.py
@@ -35,7 +35,7 @@ class ModToolNewModule(ModTool):
         ModTool.__init__(self)
 
     def setup_parser(self):
-        " Initialise the option parser for 'gr_modtool.py newmod' "
+        " Initialise the option parser for 'gr_modtool newmod' "
         parser = ModTool.setup_parser(self)
         parser.usage = '%prog rm [options]. \n Call %prog without any options to run it interactively.'
         ogroup = OptionGroup(parser, "New out-of-tree module options")
diff --git a/gr-utils/src/python/modtool/modtool_rm.py b/gr-utils/src/python/modtool/modtool_rm.py
index 02ce8ef3f2..32dfee4806 100644
--- a/gr-utils/src/python/modtool/modtool_rm.py
+++ b/gr-utils/src/python/modtool/modtool_rm.py
@@ -37,24 +37,10 @@ class ModToolRemove(ModTool):
     def __init__(self):
         ModTool.__init__(self)
 
-    def setup_parser(self):
-        " Initialise the option parser for 'gr_modtool.py rm' "
-        parser = ModTool.setup_parser(self)
-        parser.usage = '%prog rm [options]. \n Call %prog without any options to run it interactively.'
-        ogroup = OptionGroup(parser, "Remove module options")
-        ogroup.add_option("-p", "--pattern", type="string", default=None,
-                help="Filter possible choices for blocks to be deleted.")
-        ogroup.add_option("-y", "--yes", action="store_true", default=False,
-                help="Answer all questions with 'yes'.")
-        parser.add_option_group(ogroup)
-        return parser
-
     def setup(self):
         ModTool.setup(self)
         options = self.options
-        if options.pattern is not None:
-            self._info['pattern'] = options.pattern
-        elif options.block_name is not None:
+        if options.block_name is not None:
             self._info['pattern'] = options.block_name
         elif len(self.args) >= 2:
             self._info['pattern'] = self.args[1]
@@ -62,7 +48,6 @@ class ModToolRemove(ModTool):
             self._info['pattern'] = raw_input('Which blocks do you want to delete? (Regex): ')
         if len(self._info['pattern']) == 0:
             self._info['pattern'] = '.'
-        self._info['yes'] = options.yes
 
     def run(self):
         """ Go, go, go! """
@@ -108,7 +93,7 @@ class ModToolRemove(ModTool):
             return regexp
         # Go, go, go!
         if not self._skip_subdirs['lib']:
-            self._run_subdir('lib', ('*.cc', '*.h'), ('add_library',),
+            self._run_subdir('lib', ('*.cc', '*.h'), ('add_library', 'list'),
                              cmakeedit_func=_remove_cc_test_case)
         if not self._skip_subdirs['include']:
             incl_files_deleted = self._run_subdir(self._info['includedir'], ('*.h',), ('install',))
diff --git a/gr-utils/src/python/modtool/parser_cc_block.py b/gr-utils/src/python/modtool/parser_cc_block.py
index d11353cc7a..0d1d75f29a 100644
--- a/gr-utils/src/python/modtool/parser_cc_block.py
+++ b/gr-utils/src/python/modtool/parser_cc_block.py
@@ -121,12 +121,13 @@ class ParserCCBlock(object):
                 if not in_string:
                     if c[i] == ')':
                         if parens_count == 0:
-                            if read_state == 'type':
+                            if read_state == 'type' and len(this_type):
                                 raise ValueError(
                                         'Found closing parentheses before finishing last argument (this is how far I got: %s)'
                                         % str(param_list)
                                 )
-                            param_list.append((this_type, this_name, this_defv))
+                            if len(this_type):
+                                param_list.append((this_type, this_name, this_defv))
                             end_of_list = True
                             break
                         else:
diff --git a/gr-utils/src/python/modtool/templates.py b/gr-utils/src/python/modtool/templates.py
index 91d8370b98..8777357112 100644
--- a/gr-utils/src/python/modtool/templates.py
+++ b/gr-utils/src/python/modtool/templates.py
@@ -490,9 +490,9 @@ Templates['grc_xml'] = '''<?xml version="1.0"?>
 
 # Usage
 Templates['usage'] = '''
-gr_modtool.py <command> [options] -- Run <command> with the given options.
-gr_modtool.py help -- Show a list of commands.
-gr_modtool.py help <command> -- Shows the help for a given command. '''
+gr_modtool <command> [options] -- Run <command> with the given options.
+gr_modtool help -- Show a list of commands.
+gr_modtool help <command> -- Shows the help for a given command. '''
 
 # SWIG string
 Templates['swig_block_magic'] = """#if $version == '37'
diff --git a/gr-utils/src/python/modtool/util_functions.py b/gr-utils/src/python/modtool/util_functions.py
index 33d8ad3339..4ca294ac31 100644
--- a/gr-utils/src/python/modtool/util_functions.py
+++ b/gr-utils/src/python/modtool/util_functions.py
@@ -18,11 +18,13 @@
 # the Free Software Foundation, Inc., 51 Franklin Street,
 # Boston, MA 02110-1301, USA.
 #
-""" Utility functions for gr_modtool.py """
+""" Utility functions for gr_modtool """
 
 import re
 import sys
 
+# None of these must depend on other modtool stuff!
+
 def get_command_from_argv(possible_cmds):
     """ Read the requested command from argv. This can't be done with optparse,
     since the option parser isn't defined before the command is known, and
@@ -38,7 +40,7 @@ def get_command_from_argv(possible_cmds):
     return None
 
 def append_re_line_sequence(filename, linepattern, newline):
-    """Detects the re 'linepattern' in the file. After its last occurrence,
+    """ Detects the re 'linepattern' in the file. After its last occurrence,
     paste 'newline'. If the pattern does not exist, append the new line
     to the file. Then, write. """
     oldfile = open(filename, 'r').read()
@@ -99,19 +101,6 @@ def get_modname():
     except AttributeError:
         return None
 
-def get_class_dict():
-    " Return a dictionary of the available commands in the form command->class "
-    classdict = {}
-    for g in globals().values():
-        try:
-            if issubclass(g, ModTool):
-                classdict[g.name] = g
-                for a in g.aliases:
-                    classdict[a] = g
-        except (TypeError, AttributeError):
-            pass
-    return classdict
-
 def is_number(s):
     " Return True if the string s contains a number. "
     try:
-- 
cgit v1.2.3