From a62f90d8cc96b9dea9289ad6e420d1c0b16f6c36 Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Thu, 24 Jan 2013 19:33:03 +0100 Subject: utils: added modtool --- gr-utils/src/python/modtool/modtool_base.py | 139 ++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 gr-utils/src/python/modtool/modtool_base.py (limited to 'gr-utils/src/python/modtool/modtool_base.py') 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..edb0f14ee --- /dev/null +++ b/gr-utils/src/python/modtool/modtool_base.py @@ -0,0 +1,139 @@ +""" 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 + +### ModTool base class ####################################################### +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(usage=Templates['usage'], add_help_option=False) + 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.") + 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.") + ogroup.add_option("-N", "--block-name", type="string", default=None, + help="Name of the block, minus the module name prefix.") + 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.") + 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) + print "Operating in directory " + self._dir + 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() + + 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 + -- cgit From 9ef0f125355a4541c691f18d05ad7ca7b6f7125e Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Sun, 27 Jan 2013 16:57:04 +0100 Subject: modtool: added copyleft headers --- gr-utils/src/python/modtool/modtool_base.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'gr-utils/src/python/modtool/modtool_base.py') diff --git a/gr-utils/src/python/modtool/modtool_base.py b/gr-utils/src/python/modtool/modtool_base.py index edb0f14ee..d824910e9 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): -- cgit From 2d695b3c4c86b5c206f95dcc1d71f97d808d98b8 Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Mon, 28 Jan 2013 15:26:05 +0100 Subject: modtool: cleanup, bugfixes --- gr-utils/src/python/modtool/modtool_base.py | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'gr-utils/src/python/modtool/modtool_base.py') diff --git a/gr-utils/src/python/modtool/modtool_base.py b/gr-utils/src/python/modtool/modtool_base.py index d824910e9..3f8f2bc3c 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] \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 + -- cgit