diff options
author | Arpit Gupta <guptarpit1997@gmail.com> | 2019-12-19 22:48:00 +0530 |
---|---|---|
committer | Marcus Müller <mmueller@gnuradio.org> | 2019-12-19 18:18:00 +0100 |
commit | 116f0401f54e4c8483952118c013b8c668eb3682 (patch) | |
tree | c4362ba8274ff68d78f8179603d3173481134775 /gr-utils/python/blocktool/cli.py | |
parent | f3dcc45afea4fafa84b0c0e861031105a67bbaf2 (diff) |
Block header parsing tool: GSoC 2019 (#2750)
* Add base.py file in cli module to import override Click functions
* Create cli and core base module for AST generation of header blocks
* Create basic CLI for blocktool with minimal support
* Add Sequence Completer to CLI and successful generation of AST
* CLI structure complete with parseheader command
* Basic core structure complete
* Add test script gr_blocktool to run the tool
* Add JSON schema and validation for parsed json output file
* Change properties and methods key to list in JSON schema
* Create an independent api from blocktool
* Bug fix for abslute path of the header files
* Create basic parser core api
* Parse the block header documentation
* Expose the core api, minor bug fixes
* Create the code pylint compatible
* Modify cli to accept file_path as an argument, parse default values of make function arguments
* Fix: Namespace parsing of block header file
* Parse the io_signature from the implementation file of the block header
* Create json file generator
* Add key-value io_signature and docstring in json schema, change sample generated json output
* Fix: squash an I/O parsing bug
* Change directory structure for blocktool tests
* Add Blocktool unittest
* Removed empty strings, make the code pylint compatible
* Use str.format() to get output
* Implement YAML generator
* Add a new CLI argument to parse a complete header directory
* Add Logger to log errors without raising exceptions
* Create output schema file in blocktool core
* Change directory structure of blocktool and cli commands
* write unittests for Blocktool Excceptions
* Add sample yaml files
* Simplify blocktool cli structure
* Refactor blocktool exception handling
* Split long blocktool unit-tests
* Parse message ports from the implementation file
* Add tests for parsed message port id, update sample json files
* Add blocktool subdirectory, files in CMakeLists.txt
* Remove test files to run Blocktool
* Fix: locates implementation file by traversing the module
* Integrate blocktool with modtool as an external plugin
* Create proper formatting of io_signature for yaml files
* Extend modtool makeyaml command to extend support for blocktool
* Remove external plugin for modtool support, add blocktool independent script
* Minor formatiing, change function name due to conflict with modtool function
* Add support to read and add blocktool special comments in header file
* Fix: Key Errors, Modify Documentation Reader
* Raise warning in case of conflict in the parsed information and blocktool comments
* Remove all the blocktool boilerplate cli code and provide minimal support
* Remove gr_blocktool script and use blocktool as a python module
* Major refactoring of the modtool cli structure to support the blocktool API
* Check for PyGCCXML dependency during build
* Add README.md for gr-blocktool and remove modtool cli warnings
Diffstat (limited to 'gr-utils/python/blocktool/cli.py')
-rw-r--r-- | gr-utils/python/blocktool/cli.py | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/gr-utils/python/blocktool/cli.py b/gr-utils/python/blocktool/cli.py new file mode 100644 index 0000000000..dbb7b7cbc5 --- /dev/null +++ b/gr-utils/python/blocktool/cli.py @@ -0,0 +1,140 @@ +# +# Copyright 2019 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. +# +""" Module to generate parsed header output data """ + +from __future__ import print_function +from __future__ import absolute_import +from __future__ import unicode_literals + +import os +import sys +import json +import logging + +import click +from click import ClickException + +from gnuradio.modtool.core import yaml_generator + +from .core.parseheader import BlockHeaderParser + +LOGGER = logging.getLogger(__name__) + + +class BlockToolException(ClickException): + """ Exception class for enhanced CLI interface """ + + def show(self, file=None): + """ displays the colored message """ + click.secho('BlockToolException: {}'.format( + self.format_message()), fg='red') + + +def run_blocktool(module): + """Call the run function of the core modules.""" + try: + module.run_blocktool() + except BlockToolException as err: + click.echo(err, file=sys.stderr) + exit(1) + + +@click.command('parseheader', + short_help='Generate the parsed output for the header file or directory in a specified format') +@click.argument('file-path', nargs=1) +@click.option('--yaml', is_flag=True, + help='If given, a YAML response will be printed, else default json will be printed') +@click.option('-c', '--blocktool-comments', is_flag=True, + help='blocktool helper comments will be added in the header file') +@click.option('-o', '--output', is_flag=True, + help='If given, a file with desired output format will be generated') +def cli(**kwargs): + """ + Block header parsing tool. + \b + A tool that can be used to automatically parse the headers in GNU Radio project + or the OOT modules + """ + kwargs['modtool'] = False + if os.path.isfile(kwargs['file_path']): + parser = BlockHeaderParser(**kwargs) + run_blocktool(parser) + if kwargs['yaml']: + parser.yaml = True + yaml_generator(parser, **kwargs) + else: + parser.json_confirm = True + json_generator(parser, **kwargs) + elif os.path.isdir(kwargs['file_path']): + parse_directory(**kwargs) + else: + raise BlockToolException('Invalid file or directory path.') + + +def json_generator(parser, **kwargs): + """ + Generate JSON file for the block header + """ + header = parser.filename.split('.')[0] + block = parser.modname.split('-')[-1] + if kwargs['output']: + json_file = os.path.join('.', block+'_'+header + '.json') + with open(json_file, 'w') as _file: + json.dump(parser.parsed_data, _file, indent=4) + else: + print(json.dumps(parser.parsed_data, indent=4)) + + +def parse_directory(**kwargs): + """ + Get parsed json and yaml output for complete header directory + """ + kwargs['output'] = True + dir_path = kwargs['file_path'] + dir_path = os.path.abspath(dir_path) + list_header = [] + dir_name = os.path.basename(dir_path) + for _header in os.listdir(dir_path): + if _header.endswith('.h') and os.path.isfile(os.path.join(dir_path, _header)): + list_header.append(os.path.join(dir_path, _header)) + list_header = sorted(list_header) + if list_header: + for header_path in list_header: + kwargs['file_path'] = header_path + header = os.path.basename(header_path) + try: + parse_dir = BlockHeaderParser(**kwargs) + parse_dir.yaml = True + parse_dir.json = True + run_blocktool(parse_dir) + yaml_generator(parse_dir, **kwargs) + if not kwargs['modtool']: + json_generator(parse_dir, **kwargs) + except: + logging.basicConfig(level=logging.DEBUG, + filename=os.path.join('.', dir_name+'_log.out')) + logging.exception( + 'Log for Exception raised for the header: {}\n'.format(header)) + click.secho('Parsing unsuccessful: {}'.format( + header), fg='yellow') + else: + raise BlockToolException( + 'Invalid directory! No header found to be parsed') |