# # 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(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