diff options
author | Jiří Pinkava <j-pi@seznam.cz> | 2016-06-26 13:04:41 +0200 |
---|---|---|
committer | Jiří Pinkava <j-pi@seznam.cz> | 2016-06-30 01:38:45 +0200 |
commit | 9f62aa85ee15b6a7dd7283d834abc192c437ea13 (patch) | |
tree | 834fe66c09cd774a85adb5e35550ffa0bf0f4943 /gr-utils | |
parent | 5ff65f3804f7e7e19c29365ff73d645f241bd95a (diff) |
modtool: replace OptionParser by ArgumentParser
Diffstat (limited to 'gr-utils')
-rw-r--r-- | gr-utils/python/modtool/CMakeLists.txt | 1 | ||||
-rw-r--r-- | gr-utils/python/modtool/__init__.py | 3 | ||||
-rw-r--r-- | gr-utils/python/modtool/modtool_add.py | 44 | ||||
-rw-r--r-- | gr-utils/python/modtool/modtool_base.py | 78 | ||||
-rw-r--r-- | gr-utils/python/modtool/modtool_disable.py | 19 | ||||
-rw-r--r-- | gr-utils/python/modtool/modtool_help.py | 68 | ||||
-rw-r--r-- | gr-utils/python/modtool/modtool_info.py | 20 | ||||
-rw-r--r-- | gr-utils/python/modtool/modtool_makexml.py | 25 | ||||
-rw-r--r-- | gr-utils/python/modtool/modtool_newmod.py | 24 | ||||
-rw-r--r-- | gr-utils/python/modtool/modtool_rename.py | 39 | ||||
-rw-r--r-- | gr-utils/python/modtool/modtool_rm.py | 19 | ||||
-rw-r--r-- | gr-utils/python/modtool/templates.py | 6 | ||||
-rw-r--r-- | gr-utils/python/modtool/util_functions.py | 9 | ||||
-rwxr-xr-x | gr-utils/python/utils/gr_modtool | 28 |
14 files changed, 151 insertions, 232 deletions
diff --git a/gr-utils/python/modtool/CMakeLists.txt b/gr-utils/python/modtool/CMakeLists.txt index 9ee38d61e6..697a84ddd1 100644 --- a/gr-utils/python/modtool/CMakeLists.txt +++ b/gr-utils/python/modtool/CMakeLists.txt @@ -27,7 +27,6 @@ GR_PYTHON_INSTALL(FILES modtool_add.py modtool_base.py modtool_disable.py - modtool_help.py modtool_info.py modtool_makexml.py modtool_newmod.py diff --git a/gr-utils/python/modtool/__init__.py b/gr-utils/python/modtool/__init__.py index 1bc841ecf5..897ff97fce 100644 --- a/gr-utils/python/modtool/__init__.py +++ b/gr-utils/python/modtool/__init__.py @@ -21,7 +21,7 @@ from cmakefile_editor import CMakeFileEditor from grc_xml_generator import GRCXMLGenerator -from modtool_base import ModTool, ModToolException, get_class_dict +from modtool_base import ModTool, ModToolException, get_modtool_modules from modtool_add import ModToolAdd from modtool_disable import ModToolDisable from modtool_info import ModToolInfo @@ -31,6 +31,5 @@ from modtool_rm import ModToolRemove from modtool_rename import ModToolRename from templates import Templates # 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/python/modtool/modtool_add.py b/gr-utils/python/modtool/modtool_add.py index 416c0943b7..b7d33c6113 100644 --- a/gr-utils/python/modtool/modtool_add.py +++ b/gr-utils/python/modtool/modtool_add.py @@ -22,7 +22,6 @@ import os import re -from optparse import OptionGroup from util_functions import append_re_line_sequence, ask_yes_no from cmakefile_editor import CMakeFileEditor @@ -33,7 +32,7 @@ from code_generator import render_template class ModToolAdd(ModTool): """ Add block to the out-of-tree module. """ name = 'add' - aliases = ('insert',) + description = 'Add new block into module.' _block_types = ('sink', 'source', 'sync', 'decimator', 'interpolator', 'general', 'tagged_stream', 'hier', 'noblock') @@ -44,30 +43,29 @@ class ModToolAdd(ModTool): self._skip_cmakefiles = False self._license_file = None - def setup_parser(self): - parser = ModTool.setup_parser(self) - 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)) - ogroup.add_option("--license-file", type="string", default=None, + @staticmethod + def setup_parser(parser): + parser.add_argument("-t", "--block-type", choices=ModToolAdd._block_types, + help="One of %s." % ', '.join(ModToolAdd._block_types)) + parser.add_argument("--license-file", help="File containing the license header for every source code file.") - ogroup.add_option("--copyright", type="string", default=None, + parser.add_argument("--copyright", help="Name of the copyright holder (you or your company) MUST be a quoted string.") - ogroup.add_option("--argument-list", type="string", default=None, + parser.add_argument("--argument-list", help="The argument list for the constructor and make functions.") - ogroup.add_option("--add-python-qa", action="store_true", default=None, + parser.add_argument("--add-python-qa", action="store_true", default=None, help="If given, Python QA code is automatically added if possible.") - ogroup.add_option("--add-cpp-qa", action="store_true", default=None, + parser.add_argument("--add-cpp-qa", action="store_true", default=None, help="If given, C++ QA code is automatically added if possible.") - ogroup.add_option("--skip-cmakefiles", action="store_true", default=False, + parser.add_argument("--skip-cmakefiles", action="store_true", help="If given, only source files are written, but CMakeLists.txt files are left unchanged.") - ogroup.add_option("-l", "--lang", type="choice", choices=('cpp', 'c++', 'python'), - default=None, help="Language (cpp or python)") - parser.add_option_group(ogroup) + parser.add_argument("-l", "--lang", choices=('cpp', 'c++', 'python'), + help="Programing language") + ModTool.setup_parser_block(parser) return parser - def setup(self, options, args): - ModTool.setup(self, options, args) + def setup(self, options): + ModTool.setup(self, options) self._info['blocktype'] = options.block_type if self._info['blocktype'] is None: @@ -80,7 +78,7 @@ class ModToolAdd(ModTool): # Allow user to specify language interactively if not set self._info['lang'] = options.lang if self._info['lang'] is None: - while self._info['lang'] not in ['cpp', 'python']: + while self._info['lang'] not in ['c++', 'cpp', 'python']: self._info['lang'] = raw_input("Language (python/cpp): ") if self._info['lang'] == 'c++': self._info['lang'] = 'cpp' @@ -92,10 +90,7 @@ class ModToolAdd(ModTool): raise ModToolException('Missing or skipping relevant subdir.') if self._info['blockname'] is None: - if len(args) >= 2: - self._info['blockname'] = args[1] - else: - self._info['blockname'] = raw_input("Enter name of block/code (without module name prefix): ") + self._info['blockname'] = raw_input("Enter name of block/code (without module name prefix): ") if not re.match('[a-zA-Z0-9_]+', self._info['blockname']): raise ModToolException('Invalid block name.') print "Block/code identifier: " + self._info['blockname'] @@ -152,8 +147,9 @@ class ModToolAdd(ModTool): open(path_to_file, 'w').write(render_template(tpl, **self._info)) self.scm.add_files((path_to_file,)) - def run(self): + def run(self, options): """ Go, go, go. """ + self.setup(options) has_swig = ( self._info['lang'] == 'cpp' and not self._skip_subdirs['swig'] diff --git a/gr-utils/python/modtool/modtool_base.py b/gr-utils/python/modtool/modtool_base.py index a58b7abcb1..990e63af14 100644 --- a/gr-utils/python/modtool/modtool_base.py +++ b/gr-utils/python/modtool/modtool_base.py @@ -22,7 +22,7 @@ import os import re -from optparse import OptionParser, OptionGroup +from argparse import ArgumentParser, RawDescriptionHelpFormatter from gnuradio import gr from util_functions import get_modname @@ -35,6 +35,8 @@ class ModToolException(BaseException): class ModTool(object): """ Base class for all modtool command classes. """ name = 'base' + description = None + def __init__(self): self._subdirs = ['lib', 'include', 'python', 'swig', 'grc'] # List subdirs where stuff happens self._has_subdirs = {} @@ -44,45 +46,49 @@ class ModTool(object): for subdir in self._subdirs: self._has_subdirs[subdir] = False self._skip_subdirs[subdir] = False - self.parser = self.setup_parser() 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=".", + @staticmethod + def setup_parser(parser): + """Override in child class.""" + pass + + @staticmethod + def setup_parser_block(parser): + """Setup options specific for block manipulating modules.""" + parser.add_argument("blockname", nargs="?", metavar="BLOCK_NAME", + help="Name of the block/module") + + @staticmethod + def get_parser(): + """Init the option parser.""" + parser = ArgumentParser( + description='Manipulate with GNU Radio modules source code tree. ' + \ + 'Call it withou options to run specified command interactively', + formatter_class=RawDescriptionHelpFormatter) + parser.add_argument("-d", "--directory", 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, + parser.add_argument("--skip-lib", action="store_true", help="Don't do anything in the lib/ subdirectory.") - ogroup.add_option("--skip-swig", action="store_true", default=False, + parser.add_argument("--skip-swig", action="store_true", help="Don't do anything in the swig/ subdirectory.") - ogroup.add_option("--skip-python", action="store_true", default=False, + parser.add_argument("--skip-python", action="store_true", help="Don't do anything in the python/ subdirectory.") - ogroup.add_option("--skip-grc", action="store_true", default=False, + parser.add_argument("--skip-grc", action="store_true", help="Don't do anything in the grc/ subdirectory.") - ogroup.add_option("--scm-mode", type="choice", choices=('yes', 'no', 'auto'), + parser.add_argument("--scm-mode", choices=('yes', 'no', 'auto'), default=gr.prefs().get_string('modtool', 'scm_mode', 'no'), - help="Use source control management (yes, no or auto).") - ogroup.add_option("-y", "--yes", action="store_true", default=False, + help="Use source control management [ yes | no | auto ]).") + parser.add_argument("-y", "--yes", action="store_true", 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, options, args): + def setup(self, options): """ Initialise all internal variables, such as the module name etc. """ self._dir = options.directory if not self._check_directory(self._dir): raise ModToolException('No GNU Radio module found in the given directory.') - if options.module_name is not None: + if hasattr(options, 'module_name') and options.module_name is not None: self._info['modname'] = options.module_name else: self._info['modname'] = get_modname() @@ -102,7 +108,7 @@ class ModTool(object): 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._info['blockname'] = options.blockname self._setup_files() self._info['yes'] = options.yes self.options = options @@ -181,21 +187,19 @@ class ModTool(object): return fname return None - def run(self): + def run(self, options): """ Override this. """ - pass + raise NotImplementedError('Module implementation missing') -def get_class_dict(the_globals): - " Return a dictionary of the available commands in the form command->class " - classdict = {} - for g in the_globals: +def get_modtool_modules(all_objects): + """Return list with all modtool modules.""" + modules = [] + for o in all_objects: try: - if issubclass(g, ModTool): - classdict[g.name] = g - for a in g.aliases: - classdict[a] = g + if issubclass(o, ModTool) and o != ModTool: + modules.append(o) except (TypeError, AttributeError): pass - return classdict + return modules diff --git a/gr-utils/python/modtool/modtool_disable.py b/gr-utils/python/modtool/modtool_disable.py index 4ae2242f99..1772a740f3 100644 --- a/gr-utils/python/modtool/modtool_disable.py +++ b/gr-utils/python/modtool/modtool_disable.py @@ -31,24 +31,26 @@ from cmakefile_editor import CMakeFileEditor class ModToolDisable(ModTool): """ Disable block (comments out CMake entries for files) """ name = 'disable' - aliases = ('dis',) + description = 'Disable selected block in module.' def __init__(self): ModTool.__init__(self) - def setup(self, options, args): - ModTool.setup(self, options, args) + @staticmethod + def setup_parser(parser): + ModTool.setup_parser_block(parser) - if options.block_name is not None: - self._info['pattern'] = options.block_name - elif len(args) >= 2: - self._info['pattern'] = args[1] + def setup(self, options): + ModTool.setup(self, options) + + if options.blockname is not None: + self._info['pattern'] = options.blockname else: self._info['pattern'] = raw_input('Which blocks do you want to disable? (Regex): ') if len(self._info['pattern']) == 0: self._info['pattern'] = '.' - def run(self): + def run(self, options): """ Go, go, go! """ def _handle_py_qa(cmake, fname): """ Do stuff for py qa """ @@ -115,6 +117,7 @@ class ModToolDisable(ModTool): open(self._file['swig'], 'w').write(swigfile) self.scm.mark_file_updated(self._file['swig']) return False + self.setup(options) # List of special rules: 0: subdir, 1: filename re match, 2: callback special_treatments = ( ('python', 'qa.+py$', _handle_py_qa), diff --git a/gr-utils/python/modtool/modtool_help.py b/gr-utils/python/modtool/modtool_help.py deleted file mode 100644 index b894e272e8..0000000000 --- a/gr-utils/python/modtool/modtool_help.py +++ /dev/null @@ -1,68 +0,0 @@ -# -# 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 gnuradio.modtool import * -from util_functions import get_command_from_argv -from templates import Templates - - -def print_class_descriptions(): - """ Go through all ModTool* classes and print their name, - alias and description. """ - desclist = [] - for gvar in globals().values(): - try: - if issubclass(gvar, ModTool) and not issubclass(gvar, ModToolHelp): - desclist.append((gvar.name, ','.join(gvar.aliases), gvar.__doc__)) - except (TypeError, AttributeError): - pass - print 'Name Aliases Description' - print '=====================================================================' - for description in desclist: - print '%-8s %-12s %s' % description - - -class ModToolHelp(ModTool): - """ Show some help. """ - name = 'help' - aliases = ('h', '?') - - def __init__(self): - ModTool.__init__(self) - - def setup(self, options, args): - pass - - def run(self): - cmd_dict = get_class_dict(globals().values()) - cmds = cmd_dict.keys() - cmds.remove(self.name) - for a in self.aliases: - cmds.remove(a) - help_requested_for = get_command_from_argv(cmds) - if help_requested_for is None: - print 'Usage:' + Templates['usage'] - print '\nList of possible commands:\n' - print_class_descriptions() - return - cmd_dict[help_requested_for]().setup_parser().print_help() - diff --git a/gr-utils/python/modtool/modtool_info.py b/gr-utils/python/modtool/modtool_info.py index 5596a7db83..317948239e 100644 --- a/gr-utils/python/modtool/modtool_info.py +++ b/gr-utils/python/modtool/modtool_info.py @@ -21,7 +21,6 @@ """ Returns information about a module """ import os -from optparse import OptionGroup from modtool_base import ModTool, ModToolException from util_functions import get_modname @@ -30,7 +29,7 @@ from util_functions import get_modname class ModToolInfo(ModTool): """ Return information about a given module """ name = 'info' - aliases = ('getinfo', 'inf') + description = 'Return informations about module.' def __init__(self): ModTool.__init__(self) @@ -38,26 +37,25 @@ class ModToolInfo(ModTool): self._python_readable = False self._suggested_dirs = None - def setup_parser(self): + @staticmethod + def setup_parser(parser): """ 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") - ogroup.add_option("--python-readable", action="store_true", default=None, + #args_group = parser.add_argument_group(title="Info options") + parser.add_argument("--python-readable", action="store_true", help="Return the output in a format that's easier to read for Python scripts.") - ogroup.add_option("--suggested-dirs", default=None, type="string", + parser.add_argument("--suggested-dirs", help="Suggest typical include dirs if nothing better can be detected.") - parser.add_option_group(ogroup) return parser - def setup(self, options, args): + def setup(self, options): # Won't call parent's setup(), because that's too chatty self._directory = options.directory self._python_readable = options.python_readable self._suggested_dirs = options.suggested_dirs - def run(self): + def run(self, options): """ Go, go, go! """ + self.setup(options) mod_info = dict() mod_info['base_dir'] = self._get_base_dir(self._directory) if mod_info['base_dir'] is None: diff --git a/gr-utils/python/modtool/modtool_makexml.py b/gr-utils/python/modtool/modtool_makexml.py index 575d7eb873..5f53749163 100644 --- a/gr-utils/python/modtool/modtool_makexml.py +++ b/gr-utils/python/modtool/modtool_makexml.py @@ -34,35 +34,34 @@ from util_functions import ask_yes_no class ModToolMakeXML(ModTool): """ Make XML file for GRC block bindings """ name = 'makexml' - aliases = ('mx',) + description = 'Generate XML files for GRC block bindings.' def __init__(self): ModTool.__init__(self) - def setup_parser(self): + @staticmethod + def setup_parser(parser): """ Initialise the option parser for 'gr_modtool makexml' """ - parser = ModTool.setup_parser(self) - parser.usage = """%prog info [options]. \n Call %prog without any options to run it interactively. + parser.usage = """%s Note: This does not work on Python blocks! - """ - return parser + """ % parser.usage + ModTool.setup_parser_block(parser) - def setup(self, options, args): - ModTool.setup(self, options, args) + def setup(self, options): + ModTool.setup(self, options) - if options.block_name is not None: - self._info['pattern'] = options.block_name - elif len(args) >= 2: - self._info['pattern'] = args[1] + if options.blockname is not None: + self._info['pattern'] = options.blockname else: self._info['pattern'] = raw_input('Which blocks do you want to parse? (Regex): ') if len(self._info['pattern']) == 0: self._info['pattern'] = '.' - def run(self): + def run(self, options): """ Go, go, go! """ print "Warning: This is an experimental feature. Don't expect any magic." + self.setup(options) # 1) Go through lib/ if not self._skip_subdirs['lib']: if self._info['version'] == '37': diff --git a/gr-utils/python/modtool/modtool_newmod.py b/gr-utils/python/modtool/modtool_newmod.py index 3e05ecbf48..4382d9be7d 100644 --- a/gr-utils/python/modtool/modtool_newmod.py +++ b/gr-utils/python/modtool/modtool_newmod.py @@ -23,7 +23,6 @@ import shutil import os import re -from optparse import OptionGroup from gnuradio import gr from modtool_base import ModTool, ModToolException from scm import SCMRepoFactory @@ -31,26 +30,24 @@ from scm import SCMRepoFactory class ModToolNewModule(ModTool): """ Create a new out-of-tree module """ name = 'newmod' - aliases = ('nm', 'create') + description = 'Create new empty module, use add to add blocks.' def __init__(self): ModTool.__init__(self) - def setup_parser(self): + @staticmethod + def setup_parser(parser): " Initialise the option parser for 'gr_modtool newmod' " - parser = ModTool.setup_parser(self) - parser.usage = '%prog nm [options]. \n Call %prog without any options to run it interactively.' - ogroup = OptionGroup(parser, "New out-of-tree module options") - ogroup.add_option("--srcdir", type="string", + parser.add_argument("--srcdir", help="Source directory for the module template.") - parser.add_option_group(ogroup) - return parser + parser.add_argument("module_name", metavar='MODULE-NAME', nargs='?', + help="Override the current module's name (normally is autodetected).") - def setup(self, options, args): + def setup(self, options): # Don't call ModTool.setup(), that assumes an existing module. self._info['modname'] = options.module_name if self._info['modname'] is None: - if len(args) >= 2: - self._info['modname'] = args[1] + if options.module_name: + self._info['modname'] = options.module_name else: self._info['modname'] = raw_input('Name of the new module: ') if not re.match('[a-zA-Z0-9_]+$', self._info['modname']): @@ -72,12 +69,13 @@ class ModToolNewModule(ModTool): self.options = options self._setup_scm(mode='new') - def run(self): + def run(self, options): """ * Copy the example dir recursively * Open all files, rename howto and HOWTO to the module name * Rename files and directories that contain the word howto """ + self.setup(options) print "Creating out-of-tree module in %s..." % self._dir, try: shutil.copytree(self._srcdir, self._dir) diff --git a/gr-utils/python/modtool/modtool_rename.py b/gr-utils/python/modtool/modtool_rename.py index 86bafc56a5..f0ff412a89 100644 --- a/gr-utils/python/modtool/modtool_rename.py +++ b/gr-utils/python/modtool/modtool_rename.py @@ -22,7 +22,6 @@ import os import re -from optparse import OptionGroup from util_functions import append_re_line_sequence, ask_yes_no from cmakefile_editor import CMakeFileEditor @@ -32,7 +31,7 @@ from templates import Templates class ModToolRename(ModTool): """ Rename a block in the out-of-tree module. """ name = 'rename' - aliases = ('mv',) + description = 'Rename block inside module.' def __init__(self): ModTool.__init__(self) @@ -41,47 +40,43 @@ class ModToolRename(ModTool): self._skip_cmakefiles = False self._license_file = None - def setup_parser(self): - parser = ModTool.setup_parser(self) - ogroup = OptionGroup(parser, "Rename module options") - ogroup.add_option("-o", "--old-name", type="string", default=None, help="Current name of the block to rename.") - ogroup.add_option("-u", "--new-name", type="string", default=None, help="New name of the block.") - parser.add_option_group(ogroup) + @staticmethod + def setup_parser(parser): + #parser = parser.add_argument_group(title="Rename module options") + ModTool.setup_parser_block(parser) + parser.add_argument("new_name", nargs="?", metavar='NEW-BLOCK-NAME', + help="New name of the block.") return parser - def setup(self, options, args): - ModTool.setup(self, options, args) + def setup(self, options): + ModTool.setup(self, options) if ((self._skip_subdirs['lib'] and self._info['lang'] == 'cpp') or (self._skip_subdirs['python'] and self._info['lang'] == 'python')): raise ModToolException('Missing or skipping relevant subdir.') # first make sure the old block name is provided - self._info['oldname'] = options.old_name + self._info['oldname'] = options.blockname if self._info['oldname'] is None: - if len(args) >= 2: - self._info['oldname'] = args[1] - else: - self._info['oldname'] = raw_input("Enter name of block/code to rename (without module name prefix): ") + self._info['oldname'] = raw_input("Enter name of block/code to rename (without module name prefix): ") if not re.match('[a-zA-Z0-9_]+', self._info['oldname']): raise ModToolException('Invalid block name.') print "Block/code to rename identifier: " + self._info['oldname'] self._info['fulloldname'] = self._info['modname'] + '_' + self._info['oldname'] # now get the new block name - self._info['newname'] = options.new_name - if self._info['newname'] is None: - if len(args) >= 2: - self._info['newname'] = args[2] - else: - self._info['newname'] = raw_input("Enter name of block/code (without module name prefix): ") + if options.new_name is None: + self._info['newname'] = raw_input("Enter name of block/code (without module name prefix): ") + else: + self._info['newname'] = options.new_name[0] if not re.match('[a-zA-Z0-9_]+', self._info['newname']): raise ModToolException('Invalid block name.') print "Block/code identifier: " + self._info['newname'] self._info['fullnewname'] = self._info['modname'] + '_' + self._info['newname'] - def run(self): + def run(self, options): """ Go, go, go. """ + self.setup(options) module = self._info['modname'] oldname = self._info['oldname'] newname = self._info['newname'] diff --git a/gr-utils/python/modtool/modtool_rm.py b/gr-utils/python/modtool/modtool_rm.py index 47128dbc87..eef743dd61 100644 --- a/gr-utils/python/modtool/modtool_rm.py +++ b/gr-utils/python/modtool/modtool_rm.py @@ -33,24 +33,26 @@ from cmakefile_editor import CMakeFileEditor class ModToolRemove(ModTool): """ Remove block (delete files and remove Makefile entries) """ name = 'remove' - aliases = ('rm', 'del') + description = 'Remove block from module.' def __init__(self): ModTool.__init__(self) - def setup(self, options, args): - ModTool.setup(self, options, args) + @staticmethod + def setup_parser(parser): + ModTool.setup_parser_block(parser) - if options.block_name is not None: - self._info['pattern'] = options.block_name - elif len(args) >= 2: - self._info['pattern'] = args[1] + def setup(self, options): + ModTool.setup(self, options) + + if options.blockname is not None: + self._info['pattern'] = options.blockname else: self._info['pattern'] = raw_input('Which blocks do you want to delete? (Regex): ') if len(self._info['pattern']) == 0: self._info['pattern'] = '.' - def run(self): + def run(self, options): """ Go, go, go! """ def _remove_cc_test_case(filename=None, ed=None): """ Special function that removes the occurrences of a qa*.cc file @@ -96,6 +98,7 @@ class ModToolRemove(ModTool): (self._info['modname'], pyblockname, self._info['modname'], filename) return regexp # Go, go, go! + self.setup(options) if not self._skip_subdirs['lib']: self._run_subdir('lib', ('*.cc', '*.h'), ('add_library', 'list'), cmakeedit_func=_remove_cc_test_case) diff --git a/gr-utils/python/modtool/templates.py b/gr-utils/python/modtool/templates.py index a9c117ac91..3829f7a644 100644 --- a/gr-utils/python/modtool/templates.py +++ b/gr-utils/python/modtool/templates.py @@ -567,12 +567,6 @@ Templates['grc_xml'] = '''<?xml version="1.0"?> </block> ''' -# Usage -Templates['usage'] = ''' -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 == '36': % if blocktype != 'noblock': diff --git a/gr-utils/python/modtool/util_functions.py b/gr-utils/python/modtool/util_functions.py index 47799ac461..de7f3d29b6 100644 --- a/gr-utils/python/modtool/util_functions.py +++ b/gr-utils/python/modtool/util_functions.py @@ -25,15 +25,6 @@ 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 - optparse throws an error.""" - for arg in sys.argv: - if arg[0] != "-" and arg in possible_cmds: - return arg - return None - def append_re_line_sequence(filename, linepattern, newline): """ Detects the re 'linepattern' in the file. After its last occurrence, paste 'newline'. If the pattern does not exist, append the new line diff --git a/gr-utils/python/utils/gr_modtool b/gr-utils/python/utils/gr_modtool index e714cf48e5..d9016840be 100755 --- a/gr-utils/python/utils/gr_modtool +++ b/gr-utils/python/utils/gr_modtool @@ -24,19 +24,27 @@ from gnuradio.modtool import * +def setup_parser(): + modules = get_modtool_modules(globals().values()) + parser = ModTool.get_parser() + subparsers = parser.add_subparsers(title="Commands") + epilog = [] + for module in modules: + subparser = subparsers.add_parser(module.name, + description=module.description) + module.setup_parser(subparser) + subparser.set_defaults(module=module) + epilog.append(" {:<22}{}".format(module.name, module.description)) + parser.epilog = '\n'.join(epilog) + return parser + def main(): """ Here we go. Parse command, choose class and run. """ - cmd_dict = get_class_dict(globals().values()) - command = get_command_from_argv(cmd_dict.keys()) - if command is None: - print 'Usage:' + Templates['usage'] - exit(2) - modtool = cmd_dict[command]() - try: - (options, args) = modtool.parser.parse_args() - modtool.setup(options, args) - modtool.run() + parser = setup_parser() + args = parser.parse_args() + try: + args.module().run(args) except ModToolException as err: print >> sys.stderr, err exit(1) |