diff options
Diffstat (limited to 'gr-utils/python')
37 files changed, 608 insertions, 925 deletions
diff --git a/gr-utils/python/modtool/CMakeLists.txt b/gr-utils/python/modtool/CMakeLists.txt index 9ee38d61e6..5fc5b0287f 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 @@ -38,13 +37,11 @@ GR_PYTHON_INSTALL(FILES templates.py util_functions.py DESTINATION ${GR_PYTHON_DIR}/gnuradio/modtool - COMPONENT "utils" ) set(GR_PKG_MODTOOL_DATA_DIR ${GR_PKG_DATA_DIR}/modtool) install(DIRECTORY gr-newmod DESTINATION ${GR_PKG_MODTOOL_DATA_DIR} - COMPONENT "utils" ) @@ -61,6 +58,5 @@ configure_file( install( FILES ${CMAKE_CURRENT_BINARY_DIR}/modtool.conf DESTINATION ${GR_PREFSDIR} - COMPONENT "utils" ) diff --git a/gr-utils/python/modtool/__init__.py b/gr-utils/python/modtool/__init__.py index 0319b91326..897ff97fce 100644 --- a/gr-utils/python/modtool/__init__.py +++ b/gr-utils/python/modtool/__init__.py @@ -1,5 +1,5 @@ # -# Copyright 2013 Free Software Foundation, Inc. +# Copyright 2013-2014 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -20,9 +20,8 @@ # from cmakefile_editor import CMakeFileEditor -from code_generator import GRMTemplate 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 @@ -32,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/code_generator.py b/gr-utils/python/modtool/code_generator.py index 99f91761af..326b2d5986 100644 --- a/gr-utils/python/modtool/code_generator.py +++ b/gr-utils/python/modtool/code_generator.py @@ -1,5 +1,5 @@ # -# Copyright 2013 Free Software Foundation, Inc. +# Copyright 2013-2014 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -20,39 +20,41 @@ # """ A code generator (needed by ModToolAdd) """ +from mako.template import Template from templates import Templates -import Cheetah.Template from util_functions import str_to_fancyc_comment from util_functions import str_to_python_comment from util_functions import strip_default_values from util_functions import strip_arg_types from util_functions import strip_arg_types_grc -class GRMTemplate(Cheetah.Template.Template): - """ An extended template class """ - def __init__(self, src, searchList): - self.grtypelist = { - 'sync': 'sync_block', - 'sink': 'sync_block', - 'source': 'sync_block', - 'decimator': 'sync_decimator', - 'interpolator': 'sync_interpolator', - 'general': 'block', - 'tagged_stream': 'tagged_stream_block', - 'hier': 'hier_block2', - 'noblock': ''} - searchList['str_to_fancyc_comment'] = str_to_fancyc_comment - searchList['str_to_python_comment'] = str_to_python_comment - searchList['strip_default_values'] = strip_default_values - searchList['strip_arg_types'] = strip_arg_types - searchList['strip_arg_types_grc'] = strip_arg_types_grc - Cheetah.Template.Template.__init__(self, src, searchList=searchList) - self.grblocktype = self.grtypelist[searchList['blocktype']] - if searchList['is_component']: - self.include_dir_prefix = "gnuradio/" + searchList['modname'] - else: - self.include_dir_prefix = searchList['modname'] +GRTYPELIST = { + 'sync': 'sync_block', + 'sink': 'sync_block', + 'source': 'sync_block', + 'decimator': 'sync_decimator', + 'interpolator': 'sync_interpolator', + 'general': 'block', + 'tagged_stream': 'tagged_stream_block', + 'hier': 'hier_block2', + 'noblock': '' +} + +def render_template(tpl_id, **kwargs): + """ Return the parsed and rendered template given by tpl_id """ + # Choose template + tpl = Template(Templates[tpl_id]) + # Set up all variables + kwargs['str_to_fancyc_comment'] = str_to_fancyc_comment + kwargs['str_to_python_comment'] = str_to_python_comment + kwargs['strip_default_values'] = strip_default_values + kwargs['strip_arg_types'] = strip_arg_types + kwargs['strip_arg_types_grc'] = strip_arg_types_grc + kwargs['grblocktype'] = GRTYPELIST[kwargs['blocktype']] + if kwargs['is_component']: + kwargs['include_dir_prefix'] = "gnuradio/" + kwargs['modname'] + else: + kwargs['include_dir_prefix'] = kwargs['modname'] + # Render and return + return tpl.render(**kwargs) -def get_template(tpl_id, **kwargs): - """ Return the template given by tpl_id, parsed through Cheetah """ - return str(GRMTemplate(Templates[tpl_id], searchList=kwargs)) diff --git a/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrMiscUtils.cmake b/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrMiscUtils.cmake index 5bad57c51e..319581c05e 100644 --- a/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrMiscUtils.cmake +++ b/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrMiscUtils.cmake @@ -135,18 +135,14 @@ endfunction(GR_LIBTOOL) # Also handle gnuradio custom naming conventions w/ extras mode. ######################################################################## function(GR_LIBRARY_FOO target) - #parse the arguments for component names - include(CMakeParseArgumentsCopy) - CMAKE_PARSE_ARGUMENTS(GR_LIBRARY "" "RUNTIME_COMPONENT;DEVEL_COMPONENT" "" ${ARGN}) - #set additional target properties set_target_properties(${target} PROPERTIES SOVERSION ${LIBVER}) #install the generated files like so... install(TARGETS ${target} - LIBRARY DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT} # .so/.dylib file - ARCHIVE DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_DEVEL_COMPONENT} # .lib file - RUNTIME DESTINATION ${GR_RUNTIME_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT} # .dll file + LIBRARY DESTINATION ${GR_LIBRARY_DIR} # .so/.dylib file + ARCHIVE DESTINATION ${GR_LIBRARY_DIR} # .lib file + RUNTIME DESTINATION ${GR_RUNTIME_DIR} # .dll file ) #extras mode enabled automatically on linux @@ -178,7 +174,7 @@ function(GR_LIBRARY_FOO target) FILES ${CMAKE_CURRENT_BINARY_DIR}/lib${target}.so ${CMAKE_CURRENT_BINARY_DIR}/lib${target}-${LIBVER}.so.0 - DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT} + DESTINATION ${GR_LIBRARY_DIR} ) endif(LIBRARY_EXTRAS) @@ -216,49 +212,6 @@ function(GR_GEN_TARGET_DEPS name var) endfunction(GR_GEN_TARGET_DEPS) ######################################################################## -# Control use of gr_logger -# Usage: -# GR_LOGGING() -# -# Will set ENABLE_GR_LOG to 1 by default. -# Can manually set with -DENABLE_GR_LOG=0|1 -######################################################################## -function(GR_LOGGING) - find_package(Log4cpp) - - OPTION(ENABLE_GR_LOG "Use gr_logger" ON) - if(ENABLE_GR_LOG) - # If gr_logger is enabled, make it usable - add_definitions( -DENABLE_GR_LOG ) - - # also test LOG4CPP; if we have it, use this version of the logger - # otherwise, default to the stdout/stderr model. - if(LOG4CPP_FOUND) - SET(HAVE_LOG4CPP True CACHE INTERNAL "" FORCE) - add_definitions( -DHAVE_LOG4CPP ) - else(not LOG4CPP_FOUND) - SET(HAVE_LOG4CPP False CACHE INTERNAL "" FORCE) - SET(LOG4CPP_INCLUDE_DIRS "" CACHE INTERNAL "" FORCE) - SET(LOG4CPP_LIBRARY_DIRS "" CACHE INTERNAL "" FORCE) - SET(LOG4CPP_LIBRARIES "" CACHE INTERNAL "" FORCE) - endif(LOG4CPP_FOUND) - - SET(ENABLE_GR_LOG ${ENABLE_GR_LOG} CACHE INTERNAL "" FORCE) - - else(ENABLE_GR_LOG) - SET(HAVE_LOG4CPP False CACHE INTERNAL "" FORCE) - SET(LOG4CPP_INCLUDE_DIRS "" CACHE INTERNAL "" FORCE) - SET(LOG4CPP_LIBRARY_DIRS "" CACHE INTERNAL "" FORCE) - SET(LOG4CPP_LIBRARIES "" CACHE INTERNAL "" FORCE) - endif(ENABLE_GR_LOG) - - message(STATUS "ENABLE_GR_LOG set to ${ENABLE_GR_LOG}.") - message(STATUS "HAVE_LOG4CPP set to ${HAVE_LOG4CPP}.") - message(STATUS "LOG4CPP_LIBRARIES set to ${LOG4CPP_LIBRARIES}.") - -endfunction(GR_LOGGING) - -######################################################################## # Run GRCC to compile .grc files into .py files. # # Usage: GRCC(filename, directory) diff --git a/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrPython.cmake b/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrPython.cmake index 06e061e212..0bfa92db8d 100644 --- a/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrPython.cmake +++ b/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrPython.cmake @@ -130,7 +130,7 @@ endfunction(GR_UNIQUE_TARGET) ######################################################################## function(GR_PYTHON_INSTALL) include(CMakeParseArgumentsCopy) - CMAKE_PARSE_ARGUMENTS(GR_PYTHON_INSTALL "" "DESTINATION;COMPONENT" "FILES;PROGRAMS" ${ARGN}) + CMAKE_PARSE_ARGUMENTS(GR_PYTHON_INSTALL "" "DESTINATION" "FILES;PROGRAMS" ${ARGN}) #################################################################### if(GR_PYTHON_INSTALL_FILES) @@ -182,7 +182,6 @@ function(GR_PYTHON_INSTALL) set(python_install_gen_targets ${pycfiles} ${pyofiles}) install(FILES ${python_install_gen_targets} DESTINATION ${GR_PYTHON_INSTALL_DESTINATION} - COMPONENT ${GR_PYTHON_INSTALL_COMPONENT} ) #################################################################### @@ -219,7 +218,6 @@ function(GR_PYTHON_INSTALL) install(PROGRAMS ${pyexefile} RENAME ${pyfile_name} DESTINATION ${GR_PYTHON_INSTALL_DESTINATION} - COMPONENT ${GR_PYTHON_INSTALL_COMPONENT} ) endforeach(pyfile) diff --git a/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrSwig.cmake b/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrSwig.cmake index 33f37d2731..58699a7be0 100644 --- a/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrSwig.cmake +++ b/gr-utils/python/modtool/gr-newmod/cmake/Modules/GrSwig.cmake @@ -188,24 +188,21 @@ endmacro(GR_SWIG_MAKE) # GR_SWIG_INSTALL( # TARGETS target target target... # [DESTINATION destination] -# [COMPONENT component] # ) ######################################################################## macro(GR_SWIG_INSTALL) include(CMakeParseArgumentsCopy) - CMAKE_PARSE_ARGUMENTS(GR_SWIG_INSTALL "" "DESTINATION;COMPONENT" "TARGETS" ${ARGN}) + CMAKE_PARSE_ARGUMENTS(GR_SWIG_INSTALL "" "DESTINATION" "TARGETS" ${ARGN}) foreach(name ${GR_SWIG_INSTALL_TARGETS}) install(TARGETS ${SWIG_MODULE_${name}_REAL_NAME} DESTINATION ${GR_SWIG_INSTALL_DESTINATION} - COMPONENT ${GR_SWIG_INSTALL_COMPONENT} ) include(GrPython) GR_PYTHON_INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${name}.py DESTINATION ${GR_SWIG_INSTALL_DESTINATION} - COMPONENT ${GR_SWIG_INSTALL_COMPONENT} ) GR_LIBTOOL( diff --git a/gr-utils/python/modtool/gr-newmod/lib/CMakeLists.txt b/gr-utils/python/modtool/gr-newmod/lib/CMakeLists.txt index 10a15b7dd9..24ffa41fc1 100644 --- a/gr-utils/python/modtool/gr-newmod/lib/CMakeLists.txt +++ b/gr-utils/python/modtool/gr-newmod/lib/CMakeLists.txt @@ -48,7 +48,7 @@ endif(APPLE) # Install built library files ######################################################################## include(GrMiscUtils) -GR_LIBRARY_FOO(gnuradio-howto RUNTIME_COMPONENT "howto_runtime" DEVEL_COMPONENT "howto_devel") +GR_LIBRARY_FOO(gnuradio-howto) ######################################################################## # Build and register unit test @@ -79,4 +79,3 @@ GR_ADD_TEST(test_howto test-howto) ######################################################################## message(STATUS "Using install prefix: ${CMAKE_INSTALL_PREFIX}") message(STATUS "Building for version: ${VERSION} / ${LIBVER}") - diff --git a/gr-utils/python/modtool/modtool_add.py b/gr-utils/python/modtool/modtool_add.py index b60474740c..b7d33c6113 100644 --- a/gr-utils/python/modtool/modtool_add.py +++ b/gr-utils/python/modtool/modtool_add.py @@ -1,5 +1,5 @@ # -# Copyright 2013 Free Software Foundation, Inc. +# Copyright 2013-2014 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,20 +22,17 @@ import os import re -from optparse import OptionGroup from util_functions import append_re_line_sequence, ask_yes_no from cmakefile_editor import CMakeFileEditor from modtool_base import ModTool, ModToolException from templates import Templates -from code_generator import get_template -import Cheetah.Template - +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') @@ -46,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: @@ -82,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' @@ -94,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'] @@ -145,17 +138,18 @@ class ModToolAdd(ModTool): elif self._info['is_component']: return Templates['grlicense'] else: - return get_template('defaultlicense', **self._info) + return Templates['defaultlicense'].format(**self._info) def _write_tpl(self, tpl, path, fname): """ Shorthand for writing a substituted template to a file""" path_to_file = os.path.join(path, fname) print "Adding file '%s'..." % path_to_file - open(path_to_file, 'w').write(get_template(tpl, **self._info)) + 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'] @@ -204,26 +198,6 @@ class ModToolAdd(ModTool): self.scm.mark_files_updated((self._file['qalib'],)) except IOError: print "Can't add C++ QA files." - def _add_qa36(): - " Add C++ QA files for pre-3.7 API (not autotools) " - fname_qa_cc = 'qa_%s.cc' % self._info['fullblockname'] - self._write_tpl('qa_cpp36', 'lib', fname_qa_cc) - if not self._skip_cmakefiles: - open(self._file['cmlib'], 'a').write( - str( - Cheetah.Template.Template( - Templates['qa_cmakeentry36'], - searchList={'basename': os.path.splitext(fname_qa_cc)[0], - 'upperbasename': os.path.splitext(fname_qa_cc)[0].upper(), - 'filename': fname_qa_cc, - 'modname': self._info['modname'] - } - ) - ) - ) - ed = CMakeFileEditor(self._file['cmlib']) - ed.remove_double_newlines() - ed.write() fname_cc = None fname_h = None if self._info['version'] == '37': @@ -244,7 +218,7 @@ class ModToolAdd(ModTool): if self._info['version'] == '37': _add_qa() elif self._info['version'] == '36': - _add_qa36() + print "Warning: C++ QA files not supported for 3.6-style OOTs." elif self._info['version'] == 'autofoo': print "Warning: C++ QA files not supported for autotools." if not self._skip_cmakefiles: @@ -269,7 +243,7 @@ class ModToolAdd(ModTool): mod_block_sep = '/' if self._info['version'] == '36': mod_block_sep = '_' - swig_block_magic_str = get_template('swig_block_magic', **self._info) + swig_block_magic_str = render_template('swig_block_magic', **self._info) open(self._file['swig'], 'a').write(swig_block_magic_str) include_str = '#include "%s%s%s.h"' % ( {True: 'gnuradio/' + self._info['modname'], False: self._info['modname']}[self._info['is_component']], 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 4d3f5cb17e..f0ff412a89 100644 --- a/gr-utils/python/modtool/modtool_rename.py +++ b/gr-utils/python/modtool/modtool_rename.py @@ -22,20 +22,16 @@ import os import re -from optparse import OptionGroup from util_functions import append_re_line_sequence, ask_yes_no from cmakefile_editor import CMakeFileEditor from modtool_base import ModTool, ModToolException from templates import Templates -from code_generator import get_template -import Cheetah.Template - 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) @@ -44,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 2804224892..3829f7a644 100644 --- a/gr-utils/python/modtool/templates.py +++ b/gr-utils/python/modtool/templates.py @@ -1,5 +1,5 @@ # -# Copyright 2013 Free Software Foundation, Inc. +# Copyright 2013-2014 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -45,7 +45,7 @@ Boston, MA 02110-1301, USA. ''' % datetime.now().year Templates['grlicense'] = ''' -Copyright %d Free Software Foundation, Inc. +Copyright {0} Free Software Foundation, Inc. This file is part of GNU Radio @@ -63,15 +63,15 @@ 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. -''' % datetime.now().year +'''.format(datetime.now().year) # Header file of a sync/decimator/interpolator block Templates['block_impl_h'] = '''/* -*- c++ -*- */ -${str_to_fancyc_comment($license)} -\#ifndef INCLUDED_${modname.upper()}_${blockname.upper()}_IMPL_H -\#define INCLUDED_${modname.upper()}_${blockname.upper()}_IMPL_H +${str_to_fancyc_comment(license)} +#ifndef INCLUDED_${modname.upper()}_${blockname.upper()}_IMPL_H +#define INCLUDED_${modname.upper()}_${blockname.upper()}_IMPL_H -\#include <${include_dir_prefix}/${blockname}.h> +#include <${include_dir_prefix}/${blockname}.h> namespace gr { namespace ${modname} { @@ -81,112 +81,118 @@ namespace gr { private: // Nothing to declare in this block. -#if $blocktype == 'tagged_stream' +% if blocktype == 'tagged_stream': protected: int calculate_output_stream_length(const gr_vector_int &ninput_items); -#end if +% endif public: - ${blockname}_impl(${strip_default_values($arglist)}); + ${blockname}_impl(${strip_default_values(arglist)}); ~${blockname}_impl(); // Where all the action really happens -#if $blocktype == 'general' +% if blocktype == 'general': void forecast (int noutput_items, gr_vector_int &ninput_items_required); int general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); -#else if $blocktype == 'tagged_stream' - int work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -#else if $blocktype == 'hier' -#silent pass -#else - int work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -#end if + +% elif blocktype == 'tagged_stream': + int work( + int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items + ); +% elif blocktype == 'hier': +% else: + int work( + int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items + ); +% endif }; } // namespace ${modname} } // namespace gr -\#endif /* INCLUDED_${modname.upper()}_${blockname.upper()}_IMPL_H */ +#endif /* INCLUDED_${modname.upper()}_${blockname.upper()}_IMPL_H */ ''' # C++ file of a GR block Templates['block_impl_cpp'] = '''/* -*- c++ -*- */ -${str_to_fancyc_comment($license)} -\#ifdef HAVE_CONFIG_H -\#include "config.h" -\#endif - -\#include <gnuradio/io_signature.h> -#if $blocktype == 'noblock' -\#include <${include_dir_prefix}/${blockname}.h> -#else -\#include "${blockname}_impl.h" -#end if +${str_to_fancyc_comment(license)} +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gnuradio/io_signature.h> +% if blocktype == 'noblock': +#include <${include_dir_prefix}/${blockname}.h> +% else: +#include "${blockname}_impl.h" +% endif namespace gr { namespace ${modname} { -#if $blocktype == 'noblock' - $blockname::${blockname}(${strip_default_values($arglist)}) +% if blocktype == 'noblock': + ${blockname}::${blockname}(${strip_default_values(arglist)}) { } - $blockname::~${blockname}() + ${blockname}::~${blockname}() { } -#else +% else: ${blockname}::sptr - ${blockname}::make(${strip_default_values($arglist)}) + ${blockname}::make(${strip_default_values(arglist)}) { return gnuradio::get_initial_sptr - (new ${blockname}_impl(${strip_arg_types($arglist)})); + (new ${blockname}_impl(${strip_arg_types(arglist)})); } -#if $blocktype == 'decimator' -#set $decimation = ', <+decimation+>' -#else if $blocktype == 'interpolator' -#set $decimation = ', <+interpolation+>' -#else if $blocktype == 'tagged_stream' -#set $decimation = ', <+len_tag_key+>' -#else -#set $decimation = '' -#end if -#if $blocktype == 'source' -#set $inputsig = '0, 0, 0' -#else -#set $inputsig = '<+MIN_IN+>, <+MAX_IN+>, sizeof(<+ITYPE+>)' -#end if -#if $blocktype == 'sink' -#set $outputsig = '0, 0, 0' -#else -#set $outputsig = '<+MIN_OUT+>, <+MAX_OUT+>, sizeof(<+OTYPE+>)' -#end if +<% + if blocktype == 'decimator': + decimation = ', <+decimation+>' + elif blocktype == 'interpolator': + decimation = ', <+interpolation+>' + elif blocktype == 'tagged_stream': + decimation = ', <+len_tag_key+>' + else: + decimation = '' + endif + if blocktype == 'source': + inputsig = '0, 0, 0' + else: + inputsig = '<+MIN_IN+>, <+MAX_IN+>, sizeof(<+ITYPE+>)' + endif + if blocktype == 'sink': + outputsig = '0, 0, 0' + else: + outputsig = '<+MIN_OUT+>, <+MAX_OUT+>, sizeof(<+OTYPE+>)' + endif +%> /* * The private constructor */ - ${blockname}_impl::${blockname}_impl(${strip_default_values($arglist)}) + ${blockname}_impl::${blockname}_impl(${strip_default_values(arglist)}) : gr::${grblocktype}("${blockname}", - gr::io_signature::make($inputsig), - gr::io_signature::make($outputsig)$decimation) -#if $blocktype == 'hier' + gr::io_signature::make(${inputsig}), + gr::io_signature::make(${outputsig})${decimation}) + % if blocktype == 'hier': { connect(self(), 0, d_firstblock, 0); // connect other blocks connect(d_lastblock, 0, self(), 0); } -#else + % else: {} -#end if + % endif /* * Our virtual destructor. @@ -195,7 +201,7 @@ namespace gr { { } -#if $blocktype == 'general' + % if blocktype == 'general': void ${blockname}_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required) { @@ -219,7 +225,7 @@ namespace gr { // Tell runtime system how many output items we produced. return noutput_items; } -#else if $blocktype == 'tagged_stream' + % elif blocktype == 'tagged_stream': int ${blockname}_impl::calculate_output_stream_length(const gr_vector_int &ninput_items) { @@ -241,32 +247,27 @@ namespace gr { // Tell runtime system how many output items we produced. return noutput_items; } -#else if $blocktype == 'hier' -#silent pass -#else + % elif blocktype == 'hier': + % else: int ${blockname}_impl::work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { -#if $blocktype == 'source' -#silent pass -#else + % if blocktype != 'source': const <+ITYPE+> *in = (const <+ITYPE+> *) input_items[0]; -#end if -#if $blocktype == 'sink' -#silent pass -#else + % endif + % if blocktype != 'sink': <+OTYPE+> *out = (<+OTYPE+> *) output_items[0]; -#end if + % endif // Do <+signal processing+> // Tell runtime system how many output items we produced. return noutput_items; } -#end if -#end if + % endif +% endif } /* namespace ${modname} */ } /* namespace gr */ @@ -275,38 +276,38 @@ namespace gr { # Block definition header file (for include/) Templates['block_def_h'] = '''/* -*- c++ -*- */ -${str_to_fancyc_comment($license)} +${str_to_fancyc_comment(license)} -\#ifndef INCLUDED_${modname.upper()}_${blockname.upper()}_H -\#define INCLUDED_${modname.upper()}_${blockname.upper()}_H +#ifndef INCLUDED_${modname.upper()}_${blockname.upper()}_H +#define INCLUDED_${modname.upper()}_${blockname.upper()}_H -\#include <${include_dir_prefix}/api.h> -#if $blocktype != 'noblock' -\#include <gnuradio/${grblocktype}.h> -#end if +#include <${include_dir_prefix}/api.h> +% if blocktype != 'noblock': +#include <gnuradio/${grblocktype}.h> +% endif namespace gr { namespace ${modname} { -#if $blocktype == 'noblock' +% if blocktype == 'noblock': /*! * \\brief <+description+> * */ - class ${modname.upper()}_API $blockname + class ${modname.upper()}_API ${blockname} { public: ${blockname}(${arglist}); ~${blockname}(); private: }; -#else +% else: /*! * \\brief <+description of block+> * \ingroup ${modname} * */ - class ${modname.upper()}_API ${blockname} : virtual public gr::$grblocktype + class ${modname.upper()}_API ${blockname} : virtual public gr::${grblocktype} { public: typedef boost::shared_ptr<${blockname}> sptr; @@ -319,85 +320,94 @@ namespace gr { * class. ${modname}::${blockname}::make is the public interface for * creating new instances. */ - static sptr make($arglist); + static sptr make(${arglist}); }; -#end if +% endif } // namespace ${modname} } // namespace gr -\#endif /* INCLUDED_${modname.upper()}_${blockname.upper()}_H */ +#endif /* INCLUDED_${modname.upper()}_${blockname.upper()}_H */ ''' # Python block -Templates['block_python'] = '''\#!/usr/bin/env python +Templates['block_python'] = '''#!/usr/bin/env python # -*- coding: utf-8 -*- -${str_to_python_comment($license)} -# -#if $blocktype == 'noblock' -#stop -#end if - -#if $blocktype in ('sync', 'sink', 'source') -#set $parenttype = 'gr.sync_block' -#else -#set $parenttype = {'hier': 'gr.hier_block2', 'interpolator': 'gr.interp_block', 'decimator': 'gr.decim_block', 'general': 'gr.basic_block'}[$blocktype] -#end if -#if $blocktype != 'hier' -import numpy -#if $blocktype == 'source' -#set $inputsig = 'None' -#else -#set $inputsig = '[<+numpy.float+>]' -#end if -#if $blocktype == 'sink' -#set $outputsig = 'None' -#else -#set $outputsig = '[<+numpy.float+>]' -#end if -#else -#if $blocktype == 'source' -#set $inputsig = '0, 0, 0' -#else -#set $inputsig = '<+MIN_IN+>, <+MAX_IN+>, gr.sizeof_<+ITYPE+>' -#end if -#if $blocktype == 'sink' -#set $outputsig = '0, 0, 0' -#else -#set $outputsig = '<+MIN_OUT+>, <+MAX_OUT+>, gr.sizeof_<+OTYPE+>' -#end if -#end if -#if $blocktype == 'interpolator' -#set $deciminterp = ', <+interpolation+>' -#else if $blocktype == 'decimator' -#set $deciminterp = ', <+decimation+>' -#else -#set $deciminterp = '' -#end if -from gnuradio import gr +${str_to_python_comment(license)} +#\ +<% + if blocktype == 'noblock': + return + if blocktype in ('sync', 'sink', 'source'): + parenttype = 'gr.sync_block' + else: + parenttype = { + 'hier': 'gr.hier_block2', + 'interpolator': 'gr.interp_block', + 'decimator': 'gr.decim_block', + 'general': 'gr.basic_block' + }[blocktype] +%> +% if blocktype != 'hier': + +import numpy\ +<% + if blocktype == 'source': + inputsig = 'None' + else: + inputsig = '[<+numpy.float32+>]' + if blocktype == 'sink': + outputsig = 'None' + else: + outputsig = '[<+numpy.float32+>]' +%> +% else: +<% + if blocktype == 'source': + inputsig = '0, 0, 0' + else: + inputsig = '<+MIN_IN+>, <+MAX_IN+>, gr.sizeof_<+ITYPE+>' + if blocktype == 'sink': + outputsig = '0, 0, 0' + else: + outputsig = '<+MIN_OUT+>, <+MAX_OUT+>, gr.sizeof_<+OTYPE+>' +%> +% endif +<% + if blocktype == 'interpolator': + deciminterp = ', <+interpolation+>' + elif blocktype == 'decimator': + deciminterp = ', <+decimation+>' + else: + deciminterp = '' + if arglist == '': + arglistsep = '' + else: + arglistsep = ', ' +%>from gnuradio import gr class ${blockname}(${parenttype}): """ docstring for block ${blockname} """ - def __init__(self#if $arglist == '' then '' else ', '#$arglist): + def __init__(self${arglistsep}${arglist}): ${parenttype}.__init__(self, -#if $blocktype == 'hier' - "$blockname", +% if blocktype == 'hier': + "${blockname}", gr.io_signature(${inputsig}), # Input signature gr.io_signature(${outputsig})) # Output signature # Define blocks and connect them self.connect() -#stop -#else +<% return %> +% else: name="${blockname}", in_sig=${inputsig}, out_sig=${outputsig}${deciminterp}) -#end if +% endif -#if $blocktype == 'general' +% if blocktype == 'general': def forecast(self, noutput_items, ninput_items_required): #setup size of input_items[i] for work call for i in range(len(ninput_items_required)): @@ -408,37 +418,37 @@ class ${blockname}(${parenttype}): consume(0, len(input_items[0])) \#self.consume_each(len(input_items[0])) return len(output_items[0]) -#stop -#end if +<% return %> +% endif def work(self, input_items, output_items): -#if $blocktype != 'source' +% if blocktype != 'source': in0 = input_items[0] -#end if -#if $blocktype != 'sink' +% endif +% if blocktype != 'sink': out = output_items[0] -#end if +% endif # <+signal processing here+> -#if $blocktype in ('sync', 'decimator', 'interpolator') +% if blocktype in ('sync', 'decimator', 'interpolator'): out[:] = in0 return len(output_items[0]) -#else if $blocktype == 'sink' +% elif blocktype == 'sink': return len(input_items[0]) -#else if $blocktype == 'source' +% elif blocktype == 'source': out[:] = whatever return len(output_items[0]) -#end if +% endif ''' # C++ file for QA Templates['qa_cpp'] = '''/* -*- c++ -*- */ -${str_to_fancyc_comment($license)} +${str_to_fancyc_comment(license)} -\#include <gnuradio/attributes.h> -\#include <cppunit/TestAssert.h> -\#include "qa_${blockname}.h" -\#include <${include_dir_prefix}/${blockname}.h> +#include <gnuradio/attributes.h> +#include <cppunit/TestAssert.h> +#include "qa_${blockname}.h" +#include <${include_dir_prefix}/${blockname}.h> namespace gr { namespace ${modname} { @@ -456,13 +466,13 @@ namespace gr { # Header file for QA Templates['qa_h'] = '''/* -*- c++ -*- */ -${str_to_fancyc_comment($license)} +${str_to_fancyc_comment(license)} -\#ifndef _QA_${blockname.upper()}_H_ -\#define _QA_${blockname.upper()}_H_ +#ifndef _QA_${blockname.upper()}_H_ +#define _QA_${blockname.upper()}_H_ -\#include <cppunit/extensions/HelperMacros.h> -\#include <cppunit/TestCase.h> +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> namespace gr { namespace ${modname} { @@ -481,25 +491,25 @@ namespace gr { } /* namespace ${modname} */ } /* namespace gr */ -\#endif /* _QA_${blockname.upper()}_H_ */ +#endif /* _QA_${blockname.upper()}_H_ */ ''' # Python QA code -Templates['qa_python'] = '''\#!/usr/bin/env python +Templates['qa_python'] = '''#!/usr/bin/env python # -*- coding: utf-8 -*- -${str_to_python_comment($license)} +${str_to_python_comment(license)} # from gnuradio import gr, gr_unittest from gnuradio import blocks -#if $lang == 'cpp' +% if lang == 'cpp': import ${modname}_swig as ${modname} -#else +% else: from ${blockname} import ${blockname} -#end if +% endif -class qa_$blockname (gr_unittest.TestCase): +class qa_${blockname} (gr_unittest.TestCase): def setUp (self): self.tb = gr.top_block () @@ -519,11 +529,11 @@ if __name__ == '__main__': Templates['grc_xml'] = '''<?xml version="1.0"?> <block> - <name>$blockname</name> - <key>${modname}_$blockname</key> - <category>[$modname]</category> - <import>import $modname</import> - <make>${modname}.${blockname}(${strip_arg_types_grc($arglist)})</make> + <name>${blockname}</name> + <key>${modname}_${blockname}</key> + <category>[${modname}]</category> + <import>import ${modname}</import> + <make>${modname}.${blockname}(${strip_arg_types_grc(arglist)})</make> <!-- Make one 'param' node for every Parameter you want settable from the GUI. Sub-nodes: * name @@ -557,87 +567,86 @@ 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' -GR_SWIG_BLOCK_MAGIC($modname, $blockname); -#end if -%include "${modname}_${blockname}.h" -#else -%include "${include_dir_prefix}/${blockname}.h" -#if $blocktype != 'noblock' -GR_SWIG_BLOCK_MAGIC2($modname, $blockname); -#end if -#end if +Templates['swig_block_magic'] = """% if version == '36': +% if blocktype != 'noblock': +GR_SWIG_BLOCK_MAGIC(${modname}, ${blockname}); +% endif +%%include "${modname}_${blockname}.h" +% else: +%%include "${include_dir_prefix}/${blockname}.h" + % if blocktype != 'noblock': +GR_SWIG_BLOCK_MAGIC2(${modname}, ${blockname}); + % endif +% endif """ ## Old stuff # C++ file of a GR block Templates['block_cpp36'] = '''/* -*- c++ -*- */ -${str_to_fancyc_comment($license)} -\#ifdef HAVE_CONFIG_H -\#include "config.h" -\#endif - -#if $blocktype != 'noblock' -\#include <gr_io_signature.h> -#end if -\#include "${modname}_${blockname}.h" - -#if $blocktype == 'noblock' -${modname}_${blockname}::${modname}_${blockname}(${strip_default_values($arglist)}) +${str_to_fancyc_comment(license)} +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +% if blocktype != 'noblock': +#include <gr_io_signature.h> +% endif +#include "${modname}_${blockname}.h" + +% if blocktype == 'noblock': +${modname}_${blockname}::${modname}_${blockname}(${strip_default_values(arglist)}) { } ${modname}_${blockname}::~${modname}_${blockname}() { } -#else +% else: ${modname}_${blockname}_sptr -${modname}_make_${blockname} (${strip_default_values($arglist)}) +${modname}_make_${blockname} (${strip_default_values(arglist)}) { - return gnuradio::get_initial_sptr (new ${modname}_${blockname}(${strip_arg_types($arglist)})); + return gnuradio::get_initial_sptr (new ${modname}_${blockname}(${strip_arg_types(arglist)})); } -#if $blocktype == 'decimator' -#set $decimation = ', <+decimation+>' -#else if $blocktype == 'interpolator' -#set $decimation = ', <+interpolation+>' -#else -#set $decimation = '' -#end if -#if $blocktype == 'sink' -#set $inputsig = '0, 0, 0' -#else -#set $inputsig = '<+MIN_IN+>, <+MAX_IN+>, sizeof(<+ITYPE+>)' -#end if -#if $blocktype == 'source' -#set $outputsig = '0, 0, 0' -#else -#set $outputsig = '<+MIN_OUT+>, <+MAX_OUT+>, sizeof(<+OTYPE+>)' -#end if +<% + if blocktype == 'interpolator': + deciminterp = ', <+interpolation+>' + elif blocktype == 'decimator': + deciminterp = ', <+decimation+>' + else: + deciminterp = '' + if arglist == '': + arglistsep = '' + else: + arglistsep = ', ' + if blocktype == 'source': + inputsig = '0, 0, 0' + else: + inputsig = '<+MIN_IN+>, <+MAX_IN+>, sizeof(<+ITYPE+>)' + endif + if blocktype == 'sink': + outputsig = '0, 0, 0' + else: + outputsig = '<+MIN_OUT+>, <+MAX_OUT+>, sizeof(<+OTYPE+>)' + endif +%> /* * The private constructor */ -${modname}_${blockname}::${modname}_${blockname} (${strip_default_values($arglist)}) +${modname}_${blockname}::${modname}_${blockname} (${strip_default_values(arglist)}) : gr_${grblocktype} ("${blockname}", - gr_make_io_signature($inputsig), - gr_make_io_signature($outputsig)$decimation) + gr_make_io_signature(${inputsig}), + gr_make_io_signature(${outputsig})${deciminterp}) { -#if $blocktype == 'hier' +% if blocktype == 'hier' connect(self(), 0, d_firstblock, 0); // <+connect other blocks+> connect(d_lastblock, 0, self(), 0); -#else +% else: // Put in <+constructor stuff+> here -#end if +% endif } @@ -648,10 +657,10 @@ ${modname}_${blockname}::~${modname}_${blockname}() { // Put in <+destructor stuff+> here } -#end if +% endif -#if $blocktype == 'general' +% if blocktype == 'general' void ${modname}_${blockname}::forecast (int noutput_items, gr_vector_int &ninput_items_required) { @@ -675,9 +684,8 @@ ${modname}_${blockname}::general_work (int noutput_items, // Tell runtime system how many output items we produced. return noutput_items; } -#else if $blocktype == 'hier' or $blocktype == 'noblock' -#pass -#else +% elif blocktype == 'hier' or $blocktype == 'noblock': +% else: int ${modname}_${blockname}::work(int noutput_items, gr_vector_const_void_star &input_items, @@ -691,51 +699,51 @@ ${modname}_${blockname}::work(int noutput_items, // Tell runtime system how many output items we produced. return noutput_items; } -#end if +% endif ''' # Block definition header file (for include/) Templates['block_h36'] = '''/* -*- c++ -*- */ -${str_to_fancyc_comment($license)} +${str_to_fancyc_comment(license)} -\#ifndef INCLUDED_${modname.upper()}_${blockname.upper()}_H -\#define INCLUDED_${modname.upper()}_${blockname.upper()}_H +#ifndef INCLUDED_${modname.upper()}_${blockname.upper()}_H +#define INCLUDED_${modname.upper()}_${blockname.upper()}_H -\#include <${modname}_api.h> -#if $blocktype == 'noblock' -class ${modname.upper()}_API $blockname +#include <${modname}_api.h> +% if blocktype == 'noblock' +class ${modname.upper()}_API ${blockname} { ${blockname}(${arglist}); ~${blockname}(); private: }; -#else -\#include <gr_${grblocktype}.h> +% else: +#include <gr_${grblocktype}.h> class ${modname}_${blockname}; typedef boost::shared_ptr<${modname}_${blockname}> ${modname}_${blockname}_sptr; -${modname.upper()}_API ${modname}_${blockname}_sptr ${modname}_make_${blockname} ($arglist); +${modname.upper()}_API ${modname}_${blockname}_sptr ${modname}_make_${blockname} (${arglist}); /*! * \\brief <+description+> * \ingroup ${modname} * */ -class ${modname.upper()}_API ${modname}_${blockname} : public gr_$grblocktype +class ${modname.upper()}_API ${modname}_${blockname} : public gr_${grblocktype} { private: - friend ${modname.upper()}_API ${modname}_${blockname}_sptr ${modname}_make_${blockname} (${strip_default_values($arglist)}); + friend ${modname.upper()}_API ${modname}_${blockname}_sptr ${modname}_make_${blockname} (${strip_default_values(arglist)}); - ${modname}_${blockname}(${strip_default_values($arglist)}); + ${modname}_${blockname}(${strip_default_values(arglist)}); public: ~${modname}_${blockname}(); -#if $blocktype == 'general' + % if blocktype == 'general': void forecast (int noutput_items, gr_vector_int &ninput_items_required); // Where all the action really happens @@ -743,43 +751,16 @@ class ${modname.upper()}_API ${modname}_${blockname} : public gr_$grblocktype gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); -#else if $blocktype == 'hier' -#pass -#else + % elif blocktype == 'hier': + % else: // Where all the action really happens int work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); -#end if + % endif }; -#end if - -\#endif /* INCLUDED_${modname.upper()}_${blockname.upper()}_H */ - -''' +% endif -# C++ file for QA -Templates['qa_cpp36'] = '''/* -*- c++ -*- */ -${str_to_fancyc_comment($license)} - -\#include <boost/test/unit_test.hpp> - -BOOST_AUTO_TEST_CASE(qa_${modname}_${blockname}_t1){ - BOOST_CHECK_EQUAL(2 + 2, 4); - // TODO BOOST_* test macros here -} - -BOOST_AUTO_TEST_CASE(qa_${modname}_${blockname}_t2){ - BOOST_CHECK_EQUAL(2 + 2, 4); - // TODO BOOST_* test macros here -} +#endif /* INCLUDED_${modname.upper()}_${blockname.upper()}_H */ ''' - -# Header file for QA -Templates['qa_cmakeentry36'] = """ -add_executable($basename $filename) -target_link_libraries($basename gnuradio-$modname \${Boost_LIBRARIES}) -GR_ADD_TEST($basename $basename) -""" - 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/CMakeLists.txt b/gr-utils/python/utils/CMakeLists.txt index 54eba51170..3ce335c4ed 100644 --- a/gr-utils/python/utils/CMakeLists.txt +++ b/gr-utils/python/utils/CMakeLists.txt @@ -30,7 +30,6 @@ GR_PYTHON_INSTALL( pyqt_plot.py pyqt_filter.py DESTINATION ${GR_PYTHON_DIR}/gnuradio - COMPONENT "utils" ) GR_PYTHON_INSTALL( @@ -50,7 +49,5 @@ GR_PYTHON_INSTALL( gr_plot_short gr_plot_qt gr_read_file_metadata - grcc DESTINATION ${GR_RUNTIME_DIR} - COMPONENT "utils" ) 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) diff --git a/gr-utils/python/utils/gr_plot_char b/gr-utils/python/utils/gr_plot_char index a2b93a63c6..ee644557bb 100755 --- a/gr-utils/python/utils/gr_plot_char +++ b/gr-utils/python/utils/gr_plot_char @@ -26,29 +26,26 @@ except ImportError: print "Please install SciPy to run this script (http://www.scipy.org/)" raise SystemExit, 1 -from optparse import OptionParser +from argparse import ArgumentParser from gnuradio.plot_data import plot_data def main(): - usage="%prog: [options] input_filenames" description = "Takes a GNU Radio byte/char binary file and displays the samples versus time. You can set the block size to specify how many points to read in at a time and the start position in the file. By default, the system assumes a sample rate of 1, so in time, each sample is plotted versus the sample number. To set a true time axis, set the sample rate (-R or --sample-rate) to the sample rate used when capturing the samples." - parser = OptionParser(conflict_handler="resolve", usage=usage, description=description) - parser.add_option("-B", "--block", type="int", default=1000, - help="Specify the block size [default=%default]") - parser.add_option("-s", "--start", type="int", default=0, - help="Specify where to start in the file [default=%default]") - parser.add_option("-R", "--sample-rate", type="float", default=1.0, - help="Set the sampler rate of the data [default=%default]") - - (options, args) = parser.parse_args () - if len(args) < 1: - parser.print_help() - raise SystemExit, 1 - filenames = args - - datatype=scipy.int8 - dc = plot_data(datatype, filenames, options) + parser = ArgumentParser(conflict_handler="resolve", description=description) + parser.add_argument("-B", "--block", type=int, default=1000, + help="Specify the block size [default=%(default)r]") + parser.add_argument("-s", "--start", type=int, default=0, + help="Specify where to start in the file [default=%(default)r]") + parser.add_argument("-R", "--sample-rate", type=float, default=1.0, + help="Set the sampler rate of the data [default=%(default)r]") + parser.add_argument("files", metavar="FILE", nargs="+", + help="Input file with complex samples") + + args = parser.parse_args() + + datatype = scipy.int8 + dc = plot_data(datatype, args.files, args) if __name__ == "__main__": try: diff --git a/gr-utils/python/utils/gr_plot_const b/gr-utils/python/utils/gr_plot_const index e2580dd58f..653a2539b4 100755 --- a/gr-utils/python/utils/gr_plot_const +++ b/gr-utils/python/utils/gr_plot_const @@ -33,7 +33,7 @@ except ImportError: print "Please install Matplotlib to run this script (http://matplotlib.sourceforge.net/)" raise SystemExit, 1 -from optparse import OptionParser +from argparse import ArgumentParser class draw_constellation: def __init__(self, filename, options): @@ -221,24 +221,20 @@ def find(item_in, list_search): def main(): - usage="%prog: [options] input_filename" description = "Takes a GNU Radio complex binary file and displays the I&Q data versus time and the constellation plot (I vs. Q). You can set the block size to specify how many points to read in at a time and the start position in the file. By default, the system assumes a sample rate of 1, so in time, each sample is plotted versus the sample number. To set a true time axis, set the sample rate (-R or --sample-rate) to the sample rate used when capturing the samples." - parser = OptionParser(conflict_handler="resolve", usage=usage, description=description) - parser.add_option("-B", "--block", type="int", default=1000, - help="Specify the block size [default=%default]") - parser.add_option("-s", "--start", type="int", default=0, - help="Specify where to start in the file [default=%default]") - parser.add_option("-R", "--sample-rate", type="float", default=1.0, - help="Set the sampler rate of the data [default=%default]") - - (options, args) = parser.parse_args () - if len(args) != 1: - parser.print_help() - raise SystemExit, 1 - filename = args[0] - - dc = draw_constellation(filename, options) + parser = ArgumentParser(conflict_handler="resolve", description=description) + parser.add_argument("-B", "--block", type=int, default=1000, + help="Specify the block size [default=%(default)r]") + parser.add_argument("-s", "--start", type=int, default=0, + help="Specify where to start in the file [default=%(default)r]") + parser.add_argument("-R", "--sample-rate", type=float, default=1.0, + help="Set the sampler rate of the data [default=%(default)r]") + parser.add_argument("file", metavar="FILE", + help="Input file with complex samples") + args = parser.parse_args() + + dc = draw_constellation(args.file, args) if __name__ == "__main__": try: diff --git a/gr-utils/python/utils/gr_plot_fft b/gr-utils/python/utils/gr_plot_fft index 4343481645..59fc88b994 100644 --- a/gr-utils/python/utils/gr_plot_fft +++ b/gr-utils/python/utils/gr_plot_fft @@ -27,13 +27,9 @@ from gnuradio.plot_fft_base import plot_fft_base def main(): parser = plot_fft_base.setup_options() - (options, args) = parser.parse_args () - if len(args) != 1: - parser.print_help() - raise SystemExit, 1 - filename = args[0] + args = parser.parse_args() - dc = plot_fft_base(options.data_type, filename, options) + dc = plot_fft_base(args.data_type, args.file, args) if __name__ == "__main__": try: diff --git a/gr-utils/python/utils/gr_plot_fft_c b/gr-utils/python/utils/gr_plot_fft_c index 43e808d95a..48d3218586 100755 --- a/gr-utils/python/utils/gr_plot_fft_c +++ b/gr-utils/python/utils/gr_plot_fft_c @@ -26,15 +26,12 @@ from gnuradio.plot_fft_base import plot_fft_base def main(): parser = plot_fft_base.setup_options() - parser.remove_option("--data-type") + parser.add_argument("-d", "--data-type", default="complex64", + choices=("complex64", )) - (options, args) = parser.parse_args () - if len(args) != 1: - parser.print_help() - raise SystemExit, 1 - filename = args[0] + args = parser.parse_args() - dc = plot_fft_base("complex64", filename, options) + dc = plot_fft_base("complex64", args.file, args) if __name__ == "__main__": try: diff --git a/gr-utils/python/utils/gr_plot_fft_f b/gr-utils/python/utils/gr_plot_fft_f index dee9b17dea..d1791419bb 100755 --- a/gr-utils/python/utils/gr_plot_fft_f +++ b/gr-utils/python/utils/gr_plot_fft_f @@ -26,15 +26,11 @@ from gnuradio.plot_fft_base import plot_fft_base def main(): parser = plot_fft_base.setup_options() - parser.remove_option("--data-type") + parser.add_argument("-d", "--data-type", default="float32", + choices=("float32", )) + args = parser.parse_args() - (options, args) = parser.parse_args () - if len(args) != 1: - parser.print_help() - raise SystemExit, 1 - filename = args[0] - - dc = plot_fft_base("float32", filename, options) + dc = plot_fft_base("float32", args.file, args) if __name__ == "__main__": try: diff --git a/gr-utils/python/utils/gr_plot_float b/gr-utils/python/utils/gr_plot_float index 22806e48ae..faf8106d70 100755 --- a/gr-utils/python/utils/gr_plot_float +++ b/gr-utils/python/utils/gr_plot_float @@ -26,29 +26,26 @@ except ImportError: print "Please install SciPy to run this script (http://www.scipy.org/)" raise SystemExit, 1 -from optparse import OptionParser +from argparse import ArgumentParser from gnuradio.plot_data import plot_data def main(): - usage="%prog: [options] input_filenames" description = "Takes a GNU Radio floating point binary file and displays the samples versus time. You can set the block size to specify how many points to read in at a time and the start position in the file. By default, the system assumes a sample rate of 1, so in time, each sample is plotted versus the sample number. To set a true time axis, set the sample rate (-R or --sample-rate) to the sample rate used when capturing the samples." - parser = OptionParser(conflict_handler="resolve", usage=usage, description=description) - parser.add_option("-B", "--block", type="int", default=1000, - help="Specify the block size [default=%default]") - parser.add_option("-s", "--start", type="int", default=0, - help="Specify where to start in the file [default=%default]") - parser.add_option("-R", "--sample-rate", type="float", default=1.0, - help="Set the sampler rate of the data [default=%default]") + parser = ArgumentParser(conflict_handler="resolve", description=description) + parser.add_argument("-B", "--block", type=int, default=1000, + help="Specify the block size [default=%(default)r]") + parser.add_argument("-s", "--start", type=int, default=0, + help="Specify where to start in the file [default=%(default)r]") + parser.add_argument("-R", "--sample-rate", type=float, default=1.0, + help="Set the sampler rate of the data [default=%(default)r]") + parser.add_argument("file", metavar="FILE", nargs='+', + help="Input file with samples") - (options, args) = parser.parse_args () - if len(args) < 1: - parser.print_help() - raise SystemExit, 1 - filenames = args + args = parser.parse_args() datatype=scipy.float32 - dc = plot_data(datatype, filenames, options) + dc = plot_data(datatype, args.file, args) if __name__ == "__main__": try: diff --git a/gr-utils/python/utils/gr_plot_int b/gr-utils/python/utils/gr_plot_int index 355ddf0189..c687f13b17 100755 --- a/gr-utils/python/utils/gr_plot_int +++ b/gr-utils/python/utils/gr_plot_int @@ -26,29 +26,26 @@ except ImportError: print "Please install SciPy to run this script (http://www.scipy.org/)" raise SystemExit, 1 -from optparse import OptionParser +from argparse import ArgumentParser from gnuradio.plot_data import plot_data def main(): - usage="%prog: [options] input_filenames" description = "Takes a GNU Radio integer binary file and displays the samples versus time. You can set the block size to specify how many points to read in at a time and the start position in the file. By default, the system assumes a sample rate of 1, so in time, each sample is plotted versus the sample number. To set a true time axis, set the sample rate (-R or --sample-rate) to the sample rate used when capturing the samples." - parser = OptionParser(conflict_handler="resolve", usage=usage, description=description) - parser.add_option("-B", "--block", type="int", default=1000, - help="Specify the block size [default=%default]") - parser.add_option("-s", "--start", type="int", default=0, - help="Specify where to start in the file [default=%default]") - parser.add_option("-R", "--sample-rate", type="float", default=1.0, - help="Set the sampler rate of the data [default=%default]") + parser = ArgumentParser(conflict_handler="resolve", description=description) + parser.add_argument("-B", "--block", type=int, default=1000, + help="Specify the block size [default=%(default)r]") + parser.add_argument("-s", "--start", type=int, default=0, + help="Specify where to start in the file [default=%(default)r]") + parser.add_argument("-R", "--sample-rate", type=float, default=1.0, + help="Set the sampler rate of the data [default=%(default)r]") + parser.add_argument("file", metavar="FILE", nargs='+', + help="Input file"); - (options, args) = parser.parse_args () - if len(args) < 1: - parser.print_help() - raise SystemExit, 1 - filenames = args + args = parser.parse_args() datatype=scipy.int32 - dc = plot_data(datatype, filenames, options) + dc = plot_data(datatype, args.file, args) if __name__ == "__main__": try: diff --git a/gr-utils/python/utils/gr_plot_iq b/gr-utils/python/utils/gr_plot_iq index bf8077b6b4..7409b73909 100755 --- a/gr-utils/python/utils/gr_plot_iq +++ b/gr-utils/python/utils/gr_plot_iq @@ -32,7 +32,7 @@ except ImportError: print "Please install Matplotlib to run this script (http://matplotlib.sourceforge.net/)" raise SystemExit, 1 -from optparse import OptionParser +from argparse import ArgumentParser class draw_iq: def __init__(self, filename, options): @@ -149,24 +149,21 @@ def find(item_in, list_search): return False def main(): - usage="%prog: [options] input_filename" description = "Takes a GNU Radio complex binary file and displays the I&Q data versus time. You can set the block size to specify how many points to read in at a time and the start position in the file. By default, the system assumes a sample rate of 1, so in time, each sample is plotted versus the sample number. To set a true time axis, set the sample rate (-R or --sample-rate) to the sample rate used when capturing the samples." - parser = OptionParser(conflict_handler="resolve", usage=usage, description=description) - parser.add_option("-B", "--block", type="int", default=1000, - help="Specify the block size [default=%default]") - parser.add_option("-s", "--start", type="int", default=0, - help="Specify where to start in the file [default=%default]") - parser.add_option("-R", "--sample-rate", type="float", default=1.0, - help="Set the sampler rate of the data [default=%default]") - - (options, args) = parser.parse_args () - if len(args) != 1: - parser.print_help() - raise SystemExit, 1 - filename = args[0] - - dc = draw_iq(filename, options) + parser = ArgumentParser(conflict_handler="resolve", description=description) + parser.add_argument("-B", "--block", type=int, default=1000, + help="Specify the block size [default=%(default)r]") + parser.add_argument("-s", "--start", type=int, default=0, + help="Specify where to start in the file [default=%(default)r]") + parser.add_argument("-R", "--sample-rate", type=float, default=1.0, + help="Set the sampler rate of the data [default=%(default)r]") + parser.add_argument("file", metavar="FILE", + help="Input file with complex samples") + + args = parser.parse_args() + + dc = draw_iq(args.file, args) if __name__ == "__main__": try: diff --git a/gr-utils/python/utils/gr_plot_psd b/gr-utils/python/utils/gr_plot_psd index 059ca6b645..b052cbfdd7 100644 --- a/gr-utils/python/utils/gr_plot_psd +++ b/gr-utils/python/utils/gr_plot_psd @@ -27,13 +27,9 @@ from gnuradio.plot_psd_base import plot_psd_base def main(): parser = plot_psd_base.setup_options() - (options, args) = parser.parse_args () - if len(args) != 1: - parser.print_help() - raise SystemExit, 1 - filename = args[0] + args = parser.parse_args() - dc = plot_psd_base(options.data_type, filename, options) + dc = plot_psd_base(args.data_type, args.file, args) if __name__ == "__main__": try: diff --git a/gr-utils/python/utils/gr_plot_psd_c b/gr-utils/python/utils/gr_plot_psd_c index fff2bff0f2..352a838138 100755 --- a/gr-utils/python/utils/gr_plot_psd_c +++ b/gr-utils/python/utils/gr_plot_psd_c @@ -20,22 +20,19 @@ # Boston, MA 02110-1301, USA. # -from optparse import OptionParser +from argparse import ArgumentParser from gnuradio.plot_psd_base import plot_psd_base # This is a wrapper program for plot_psd_base specifically for complex data def main(): parser = plot_psd_base.setup_options() - parser.remove_option("--data-type") + parser.add_argument("-d", "--data-type", default="complex64", + choices=("complex64", )) - (options, args) = parser.parse_args () - if len(args) != 1: - parser.print_help() - raise SystemExit, 1 - filename = args[0] + args = parser.parse_args() - dc = plot_psd_base("complex64", filename, options) + dc = plot_psd_base("complex64", args.file, args) if __name__ == "__main__": try: diff --git a/gr-utils/python/utils/gr_plot_psd_f b/gr-utils/python/utils/gr_plot_psd_f index ec67994797..ab860e3fb8 100755 --- a/gr-utils/python/utils/gr_plot_psd_f +++ b/gr-utils/python/utils/gr_plot_psd_f @@ -20,22 +20,19 @@ # Boston, MA 02110-1301, USA. # -from optparse import OptionParser +from argparse import ArgumentParser from gnuradio.plot_psd_base import plot_psd_base # This is a wrapper program for gr_plot_psd specifically for floating point data def main(): parser = plot_psd_base.setup_options() - parser.remove_option("--data-type") + parser.add_argument("-d", "--data-type", default="complex64", + choices=("float32", )) - (options, args) = parser.parse_args () - if len(args) != 1: - parser.print_help() - raise SystemExit, 1 - filename = args[0] + args = parser.parse_args() - dc = plot_psd_base("float32", filename, options) + dc = plot_psd_base("float32", args.file, args) if __name__ == "__main__": try: diff --git a/gr-utils/python/utils/gr_plot_short b/gr-utils/python/utils/gr_plot_short index 702a2a94a6..f900af1bac 100755 --- a/gr-utils/python/utils/gr_plot_short +++ b/gr-utils/python/utils/gr_plot_short @@ -26,29 +26,26 @@ except ImportError: print "Please install SciPy to run this script (http://www.scipy.org/)" raise SystemExit, 1 -from optparse import OptionParser +from argparse import ArgumentParser from gnuradio.plot_data import plot_data def main(): - usage="%prog: [options] input_filenames" description = "Takes a GNU Radio short integer binary file and displays the samples versus time. You can set the block size to specify how many points to read in at a time and the start position in the file. By default, the system assumes a sample rate of 1, so in time, each sample is plotted versus the sample number. To set a true time axis, set the sample rate (-R or --sample-rate) to the sample rate used when capturing the samples." - parser = OptionParser(conflict_handler="resolve", usage=usage, description=description) - parser.add_option("-B", "--block", type="int", default=1000, - help="Specify the block size [default=%default]") - parser.add_option("-s", "--start", type="int", default=0, - help="Specify where to start in the file [default=%default]") - parser.add_option("-R", "--sample-rate", type="float", default=1.0, - help="Set the sampler rate of the data [default=%default]") + parser = ArgumentParser(conflict_handler="resolve", description=description) + parser.add_argument("-B", "--block", type=int, default=1000, + help="Specify the block size [default=%(default)r]") + parser.add_argument("-s", "--start", type=int, default=0, + help="Specify where to start in the file [default=%(default)r]") + parser.add_argument("-R", "--sample-rate", type=float, default=1.0, + help="Set the sampler rate of the data [default=%(default)r]") + parser.add_argument("files", metavar="FILE", nargs="+", + help="Input file with data (int16_t)") - (options, args) = parser.parse_args () - if len(args) < 1: - parser.print_help() - raise SystemExit, 1 - filenames = args + args = parser.parse_args() datatype=scipy.int16 - dc = plot_data(datatype, filenames, options) + dc = plot_data(datatype, args.files, args) if __name__ == "__main__": try: diff --git a/gr-utils/python/utils/gr_read_file_metadata b/gr-utils/python/utils/gr_read_file_metadata index 429b38310f..a05e7ad2c7 100644 --- a/gr-utils/python/utils/gr_read_file_metadata +++ b/gr-utils/python/utils/gr_read_file_metadata @@ -21,7 +21,7 @@ # import sys -from optparse import OptionParser +from argparse import ArgumentParser import pmt from gnuradio.blocks import parse_file_metadata @@ -69,19 +69,15 @@ def main(filename, detached=False): handle.seek(nread, 0) print "\n\n" + if __name__ == "__main__": - usage="%prog: [options] filename" description = "Read in a GNU Radio file with meta data, extracts the header and prints it." - parser = OptionParser(conflict_handler="resolve", - usage=usage, description=description) - parser.add_option("-D", "--detached", action="store_true", default=False, + parser = ArgumentParser(conflict_handler="resolve", description=description) + parser.add_argument("-D", "--detached", action="store_true", help="Used if header is detached.") - (options, args) = parser.parse_args () - - if(len(args) < 1): - sys.stderr.write("No filename given\n") - sys.exit(1) + parser.add_argument("file", metavar="FILE", + help="Input file"); + args = parser.parse_args() - filename = args[0] - main(filename, options.detached) + main(args.file, args.detached) diff --git a/gr-utils/python/utils/grcc b/gr-utils/python/utils/grcc deleted file mode 100755 index b9bd1551b9..0000000000 --- a/gr-utils/python/utils/grcc +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2012 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 os -import sys -from optparse import OptionParser -import warnings -warnings.simplefilter('ignore') - -from gnuradio import gr - -try: - from grc.core.Platform import Platform -except ImportError: - from gnuradio.grc.core.Platform import Platform - - -class GRCC: - def __init__(self, grcfile, out_dir): - self.out_dir = out_dir - self.platform = Platform( - prefs_file=gr.prefs(), - version=gr.version(), - version_parts=(gr.major_version(), gr.api_version(), gr.minor_version()) - ) - data = self.platform.parse_flow_graph(grcfile) - - self.fg = self.platform.get_new_flow_graph() - self.fg.import_data(data) - self.fg.grc_file_path = os.path.abspath(grcfile) - self.fg.validate() - - if not self.fg.is_valid(): - raise StandardError("\n\n".join( - ["Validation failed:"] + self.fg.get_error_messages() - )) - - self.gen = self.platform.Generator(self.fg, out_dir) - self.gen.write() - - def exec_program(self): - progname = self.fg.get_option('id') - os.system("{0}/{1}.py".format(self.out_dir, progname)) - - -def main(): - usage="%prog: [options] filename" - description = "Compiles a GRC file (.grc) into a GNU Radio Python program. The program is stored in ~/.grc_gnuradio by default, but this location can be changed with the -d option." - - parser = OptionParser(conflict_handler="resolve", usage=usage, description=description) - parser.add_option("-d", "--directory", type="string", default='{0}/.grc_gnuradio/'.format(os.environ["HOME"]), - help="Specify the directory to output the compile program [default=%default]") - parser.add_option("-e", "--execute", action="store_true", default=False, - help="Run the program after compiling [default=%default]") - (options, args) = parser.parse_args () - - if len(args) != 1: - sys.stderr.write("Please specify a GRC file name to compile.\n") - sys.exit(1) - - try: - g = GRCC(args[0], options.directory + "/") - except Exception as e: - sys.stderr.write(str(e) + "\n") - sys.stderr.write("Error during file compilation.\n") - sys.exit(1) - - if options.execute: - g.exec_program() - - -if __name__ == "__main__": - main() diff --git a/gr-utils/python/utils/plot_data.py b/gr-utils/python/utils/plot_data.py index 2ae3b1d5b3..7d80c714fe 100644 --- a/gr-utils/python/utils/plot_data.py +++ b/gr-utils/python/utils/plot_data.py @@ -34,7 +34,6 @@ except ImportError: print "Please install Matplotlib to run this script (http://matplotlib.sourceforge.net/)" raise SystemExit, 1 -from optparse import OptionParser class plot_data: def __init__(self, datatype, filenames, options): diff --git a/gr-utils/python/utils/plot_fft_base.py b/gr-utils/python/utils/plot_fft_base.py index c4bc484d97..c99462147d 100755 --- a/gr-utils/python/utils/plot_fft_base.py +++ b/gr-utils/python/utils/plot_fft_base.py @@ -33,7 +33,7 @@ except ImportError: print "Please install Python Matplotlib (http://matplotlib.sourceforge.net/) and Python TkInter https://wiki.python.org/moin/TkInter to run this script" raise SystemExit, 1 -from optparse import OptionParser +from argparse import ArgumentParser class plot_fft_base: def __init__(self, datatype, filename, options): @@ -209,18 +209,21 @@ class plot_fft_base: @staticmethod def setup_options(): - usage="%prog: [options] input_filename" description = "Takes a GNU Radio complex binary file and displays the I&Q data versus time as well as the frequency domain (FFT) plot. The y-axis values are plotted assuming volts as the amplitude of the I&Q streams and converted into dBm in the frequency domain (the 1/N power adjustment out of the FFT is performed internally). The script plots a certain block of data at a time, specified on the command line as -B or --block. This value defaults to 1000. The start position in the file can be set by specifying -s or --start and defaults to 0 (the start of the file). By default, the system assumes a sample rate of 1, so in time, each sample is plotted versus the sample number. To set a true time and frequency axis, set the sample rate (-R or --sample-rate) to the sample rate used when capturing the samples." - parser = OptionParser(conflict_handler="resolve", usage=usage, description=description) - parser.add_option("-d", "--data-type", type="string", default="complex64", - help="Specify the data type (complex64, float32, (u)int32, (u)int16, (u)int8) [default=%default]") - parser.add_option("-B", "--block", type="int", default=1000, - help="Specify the block size [default=%default]") - parser.add_option("-s", "--start", type="int", default=0, - help="Specify where to start in the file [default=%default]") - parser.add_option("-R", "--sample-rate", type="float", default=1.0, - help="Set the sampler rate of the data [default=%default]") + parser = ArgumentParser(conflict_handler="resolve", description=description) + parser.add_argument("-d", "--data-type", default="complex64", + choices=("complex64", "float32", "uint32", "int32", "uint16", + "int16", "uint8", "int8"), + help="Specify the data type [default=%(default)r]") + parser.add_argument("-B", "--block", type=int, default=1000, + help="Specify the block size [default=%(default)r]") + parser.add_argument("-s", "--start", type=int, default=0, + help="Specify where to start in the file [default=%(default)r]") + parser.add_argument("-R", "--sample-rate", type=float, default=1.0, + help="Set the sampler rate of the data [default=%(default)r]") + parser.add_argument("file", metavar="FILE", + help="Input file with samples") return parser def find(item_in, list_search): @@ -231,13 +234,9 @@ def find(item_in, list_search): def main(): parser = plot_fft_base.setup_options() - (options, args) = parser.parse_args () - if len(args) != 1: - parser.print_help() - raise SystemExit, 1 - filename = args[0] + args = parser.parse_args() - dc = plot_fft_base(options.data_type, filename, options) + dc = plot_fft_base(args.data_type, args.file, args) if __name__ == "__main__": try: diff --git a/gr-utils/python/utils/plot_psd_base.py b/gr-utils/python/utils/plot_psd_base.py index fe3c9e12b7..2611ed4be2 100755 --- a/gr-utils/python/utils/plot_psd_base.py +++ b/gr-utils/python/utils/plot_psd_base.py @@ -33,9 +33,9 @@ except ImportError: print "Please install Matplotlib to run this script (http://matplotlib.sourceforge.net/)" raise SystemExit, 1 -from optparse import OptionParser +from argparse import ArgumentParser from scipy import log10 -from gnuradio.eng_option import eng_option +from gnuradio.eng_arg import eng_float, intx class plot_psd_base: def __init__(self, datatype, filename, options): @@ -244,25 +244,27 @@ class plot_psd_base: @staticmethod def setup_options(): - usage="%prog: [options] input_filename" description = "Takes a GNU Radio binary file (with specified data type using --data-type) and displays the I&Q data versus time as well as the power spectral density (PSD) plot. The y-axis values are plotted assuming volts as the amplitude of the I&Q streams and converted into dBm in the frequency domain (the 1/N power adjustment out of the FFT is performed internally). The script plots a certain block of data at a time, specified on the command line as -B or --block. The start position in the file can be set by specifying -s or --start and defaults to 0 (the start of the file). By default, the system assumes a sample rate of 1, so in time, each sample is plotted versus the sample number. To set a true time and frequency axis, set the sample rate (-R or --sample-rate) to the sample rate used when capturing the samples. Finally, the size of the FFT to use for the PSD and spectrogram plots can be set independently with --psd-size and --spec-size, respectively. The spectrogram plot does not display by default and is turned on with -S or --enable-spec." - parser = OptionParser(option_class=eng_option, conflict_handler="resolve", - usage=usage, description=description) - parser.add_option("-d", "--data-type", type="string", default="complex64", - help="Specify the data type (complex64, float32, (u)int32, (u)int16, (u)int8) [default=%default]") - parser.add_option("-B", "--block", type="int", default=8192, - help="Specify the block size [default=%default]") - parser.add_option("-s", "--start", type="int", default=0, - help="Specify where to start in the file [default=%default]") - parser.add_option("-R", "--sample-rate", type="eng_float", default=1.0, - help="Set the sampler rate of the data [default=%default]") - parser.add_option("", "--psd-size", type="int", default=1024, - help="Set the size of the PSD FFT [default=%default]") - parser.add_option("", "--spec-size", type="int", default=256, - help="Set the size of the spectrogram FFT [default=%default]") - parser.add_option("-S", "--enable-spec", action="store_true", default=False, - help="Turn on plotting the spectrogram [default=%default]") + parser = ArgumentParser(conflict_handler="resolve", description=description) + parser.add_argument("-d", "--data-type", default="complex64", + choices=("complex64", "float32", "int32", "uint32", "int16", + "uint16", "int8", "uint8" ), + help="Specify the data type [default=%(default)r]") + parser.add_argument("-B", "--block", type=int, default=8192, + help="Specify the block size [default=%(default)r]") + parser.add_argument("-s", "--start", type=int, default=0, + help="Specify where to start in the file [default=%(default)r]") + parser.add_argument("-R", "--sample-rate", type=eng_float, default=1.0, + help="Set the sampler rate of the data [default=%(default)r]") + parser.add_argument("--psd-size", type=int, default=1024, + help="Set the size of the PSD FFT [default=%(default)r]") + parser.add_argument("--spec-size", type=int, default=256, + help="Set the size of the spectrogram FFT [default=%(default)r]") + parser.add_argument("-S", "--enable-spec", action="store_true", + help="Turn on plotting the spectrogram [default=%(default)r]") + parser.add_argument("file", metavar="FILE", + help="Input file with samples") return parser @@ -274,13 +276,9 @@ def find(item_in, list_search): def main(): parser = plot_psd_base.setup_options() - (options, args) = parser.parse_args () - if len(args) != 1: - parser.print_help() - raise SystemExit, 1 - filename = args[0] + args = parser.parse_args() - dc = plot_psd_base(options.data_type, filename, options) + dc = plot_psd_base(args.data_type, args.file, args) if __name__ == "__main__": try: |