summaryrefslogtreecommitdiff
path: root/gr-utils/python/blocktool/cli.py
diff options
context:
space:
mode:
authorArpit Gupta <guptarpit1997@gmail.com>2019-12-19 22:48:00 +0530
committerMarcus Müller <mmueller@gnuradio.org>2019-12-19 18:18:00 +0100
commit116f0401f54e4c8483952118c013b8c668eb3682 (patch)
treec4362ba8274ff68d78f8179603d3173481134775 /gr-utils/python/blocktool/cli.py
parentf3dcc45afea4fafa84b0c0e861031105a67bbaf2 (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.py140
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')