summaryrefslogtreecommitdiff
path: root/gr-utils/src/python/modtool/modtool_base.py
diff options
context:
space:
mode:
Diffstat (limited to 'gr-utils/src/python/modtool/modtool_base.py')
-rw-r--r--gr-utils/src/python/modtool/modtool_base.py176
1 files changed, 176 insertions, 0 deletions
diff --git a/gr-utils/src/python/modtool/modtool_base.py b/gr-utils/src/python/modtool/modtool_base.py
new file mode 100644
index 000000000..3f8f2bc3c
--- /dev/null
+++ b/gr-utils/src/python/modtool/modtool_base.py
@@ -0,0 +1,176 @@
+#
+# 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
+import re
+import sys
+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):
+ self._subdirs = ['lib', 'include', 'python', 'swig', 'grc'] # List subdirs where stuff happens
+ self._has_subdirs = {}
+ self._skip_subdirs = {}
+ self._info = {}
+ self._file = {}
+ for subdir in self._subdirs:
+ self._has_subdirs[subdir] = False
+ self._skip_subdirs[subdir] = False
+ self.parser = self.setup_parser()
+ self.args = None
+ self.options = None
+ self._dir = None
+
+ def setup_parser(self):
+ """ Init the option parser. If derived classes need to add options,
+ override this and call the parent function. """
+ 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. Defaults to the cwd.")
+ ogroup.add_option("-n", "--module-name", type="string", default=None,
+ 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, 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,
+ help="Don't do anything in the swig/ subdirectory.")
+ ogroup.add_option("--skip-python", action="store_true", default=False,
+ 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
+
+ def setup(self):
+ """ Initialise all internal variables, such as the module name etc. """
+ (options, self.args) = self.parser.parse_args()
+ self._dir = options.directory
+ if not self._check_directory(self._dir):
+ print "No GNU Radio module found in the given directory. Quitting."
+ sys.exit(1)
+ if options.module_name is not None:
+ self._info['modname'] = options.module_name
+ else:
+ self._info['modname'] = get_modname()
+ if self._info['modname'] is None:
+ print "No GNU Radio module found in the given directory. Quitting."
+ sys.exit(1)
+ print "GNU Radio module name identified: " + self._info['modname']
+ if self._info['version'] == '36' and os.path.isdir(os.path.join('include', self._info['modname'])):
+ self._info['version'] = '37'
+ if options.skip_lib or not self._has_subdirs['lib']:
+ self._skip_subdirs['lib'] = True
+ if options.skip_python or not self._has_subdirs['python']:
+ self._skip_subdirs['python'] = True
+ if options.skip_swig or self._get_mainswigfile() is None or not self._has_subdirs['swig']:
+ self._skip_subdirs['swig'] = True
+ if options.skip_grc or not self._has_subdirs['grc']:
+ self._skip_subdirs['grc'] = True
+ 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 """
+ if not self._skip_subdirs['swig']:
+ self._file['swig'] = os.path.join('swig', self._get_mainswigfile())
+ self._file['qalib'] = os.path.join('lib', 'qa_%s.cc' % self._info['modname'])
+ self._file['pyinit'] = os.path.join('python', '__init__.py')
+ self._file['cmlib'] = os.path.join('lib', 'CMakeLists.txt')
+ self._file['cmgrc'] = os.path.join('grc', 'CMakeLists.txt')
+ self._file['cmpython'] = os.path.join('python', 'CMakeLists.txt')
+ if self._info['version'] in ('37', 'component'):
+ self._info['includedir'] = os.path.join('include', self._info['modname'])
+ else:
+ self._info['includedir'] = 'include'
+ self._file['cminclude'] = os.path.join(self._info['includedir'], 'CMakeLists.txt')
+ self._file['cmswig'] = os.path.join('swig', 'CMakeLists.txt')
+
+ def _check_directory(self, directory):
+ """ Guesses if dir is a valid GNU Radio module directory by looking for
+ CMakeLists.txt and at least one of the subdirs lib/, python/ and swig/.
+ Changes the directory, if valid. """
+ has_makefile = False
+ try:
+ files = os.listdir(directory)
+ os.chdir(directory)
+ except OSError:
+ print "Can't read or chdir to directory %s." % directory
+ return False
+ for f in files:
+ if os.path.isfile(f) and f == 'CMakeLists.txt':
+ if re.search('find_package\(GnuradioCore\)', open(f).read()) is not None:
+ self._info['version'] = '36' # Might be 37, check that later
+ has_makefile = True
+ elif re.search('GR_REGISTER_COMPONENT', open(f).read()) is not None:
+ self._info['version'] = '36' # Might be 37, check that later
+ self._info['is_component'] = True
+ has_makefile = True
+ # TODO search for autofoo
+ elif os.path.isdir(f):
+ if (f in self._has_subdirs.keys()):
+ self._has_subdirs[f] = True
+ else:
+ self._skip_subdirs[f] = True
+ return bool(has_makefile and (self._has_subdirs.values()))
+
+ def _get_mainswigfile(self):
+ """ Find out which name the main SWIG file has. In particular, is it
+ a MODNAME.i or a MODNAME_swig.i? Returns None if none is found. """
+ modname = self._info['modname']
+ swig_files = (modname + '.i',
+ modname + '_swig.i')
+ for fname in swig_files:
+ if os.path.isfile(os.path.join(self._dir, 'swig', fname)):
+ return fname
+ return None
+
+ def run(self):
+ """ 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
+