diff options
Diffstat (limited to 'gr-utils/python/blocktool/core')
-rw-r--r-- | gr-utils/python/blocktool/core/CMakeLists.txt | 19 | ||||
-rw-r--r-- | gr-utils/python/blocktool/core/Constants.py | 55 | ||||
-rw-r--r-- | gr-utils/python/blocktool/core/__init__.py | 0 | ||||
-rw-r--r-- | gr-utils/python/blocktool/core/base.py | 41 | ||||
-rw-r--r-- | gr-utils/python/blocktool/core/comments.py | 258 | ||||
-rw-r--r-- | gr-utils/python/blocktool/core/iosignature.py | 182 | ||||
-rw-r--r-- | gr-utils/python/blocktool/core/outputschema.py | 157 | ||||
-rw-r--r-- | gr-utils/python/blocktool/core/parseheader.py | 271 |
8 files changed, 0 insertions, 983 deletions
diff --git a/gr-utils/python/blocktool/core/CMakeLists.txt b/gr-utils/python/blocktool/core/CMakeLists.txt deleted file mode 100644 index 697e477caf..0000000000 --- a/gr-utils/python/blocktool/core/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2019 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# SPDX-License-Identifier: GPL-3.0-or-later -# - -include(GrPython) - -GR_PYTHON_INSTALL(FILES - __init__.py - base.py - comments.py - parseheader.py - iosignature.py - outputschema.py - Constants.py - DESTINATION ${GR_PYTHON_DIR}/gnuradio/blocktool/core -) diff --git a/gr-utils/python/blocktool/core/Constants.py b/gr-utils/python/blocktool/core/Constants.py deleted file mode 100644 index be79631b97..0000000000 --- a/gr-utils/python/blocktool/core/Constants.py +++ /dev/null @@ -1,55 +0,0 @@ -# -# Copyright 2019 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# SPDX-License-Identifier: GPL-3.0-or-later -# -# -""" constants file """ - -# Kernel Namespace -KERNEL = 'kernel' - -# I/O Signature (Symbols and constants) -IO_SIGNATURE = 'io_signature::' -SIGNATURE_LIST = ['makev', 'make3', 'make2', 'make'] -MAKE = 'make' -MAKE2 = 'make2' -MAKE3 = 'make3' -MAKEV = 'makev' - - -# message ports id -MESSAGE_INPUT = 'message_port_register_in' -MESSAGE_OUTPUT = 'message_port_register_out' - -# Symbols and constants required for parsing -GR = 'gr-' -UTILS = 'utils' -OPEN_BRACKET = '(' -CLOSE_BRACKET = ')' -STRIP_SYMBOLS = ' ,:)' -EXCLAMATION = '!' - -# Blocktool special comments -BLOCKTOOL = '! BlockTool' -END_BLOCKTOOL = 'EndTool !' -INPUT_SIG = 'input_signature' -OUTPUT_SIG = 'output_signature' -INPUT_MIN = 'input_min_streams' -INPUT_MAX = 'input_max_streams' -OUTPUT_MIN = 'output_min_streams' -OUTPUT_MAX = 'output_max_streams' -INPUT_MAKE_SIZE = 'input_sizeof_stream_item' -INPUT_MAKEV_SIZE = 'input_sizeof_stream_items' -INPUT_MAKE_SIZE1 = 'input_sizeof_stream_item1' -INPUT_MAKE_SIZE2 = 'input_sizeof_stream_item2' -INPUT_MAKE_SIZE3 = 'input_sizeof_stream_item3' -OUTPUT_MAKE_SIZE = 'output_sizeof_stream_item' -OUTPUT_MAKEV_SIZE = 'output_sizeof_stream_items' -OUTPUT_MAKE_SIZE1 = 'output_sizeof_stream_item1' -OUTPUT_MAKE_SIZE2 = 'output_sizeof_stream_item2' -OUTPUT_MAKE_SIZE3 = 'output_sizeof_stream_item3' -INPUT_PORT = 'message_input' -OUTPUT_PORT = 'message_output' diff --git a/gr-utils/python/blocktool/core/__init__.py b/gr-utils/python/blocktool/core/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 --- a/gr-utils/python/blocktool/core/__init__.py +++ /dev/null diff --git a/gr-utils/python/blocktool/core/base.py b/gr-utils/python/blocktool/core/base.py deleted file mode 100644 index 30c6577398..0000000000 --- a/gr-utils/python/blocktool/core/base.py +++ /dev/null @@ -1,41 +0,0 @@ -# -# Copyright 2019 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# SPDX-License-Identifier: GPL-3.0-or-later -# -# -""" Base class for the modules """ - -from __future__ import print_function -from __future__ import absolute_import -from __future__ import unicode_literals - -from abc import ABC, abstractmethod - - -class BlockToolException(Exception): - """ Standard exception for blocktool classes. """ - pass - - -class BlockTool(ABC): - """ Base class for all blocktool command classes. """ - name = 'base' - description = None - - def __init__(self, modname=None, filename=None, targetdir=None, - target_file=None, module=None, impldir=None, impl_file=None, - yaml=False, json=False, include_paths=None, **kwargs): - """ __init__ """ - pass - - def _validate(self): - """ Validates the arguments """ - pass - - @abstractmethod - def run_blocktool(self): - """ Override this. """ - pass diff --git a/gr-utils/python/blocktool/core/comments.py b/gr-utils/python/blocktool/core/comments.py deleted file mode 100644 index d7919609bb..0000000000 --- a/gr-utils/python/blocktool/core/comments.py +++ /dev/null @@ -1,258 +0,0 @@ -# -# Copyright 2019 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# SPDX-License-Identifier: GPL-3.0-or-later -# -# -""" Module to read and add special blocktool comments in the public header """ - -from __future__ import print_function -from __future__ import absolute_import -from __future__ import unicode_literals - -import warnings - -from ..core import Constants - - -def strip_symbols(line): - """ - helper function to strip symbols - from blocktool comment syntax - """ - return line.split(':')[-1].lstrip().rstrip() - - -def exist_comments(self): - """ - function to check if blocktool special comments - already exist in the public header - """ - _comments = True - _index = None - lines = [] - with open(self.target_file, 'r') as header: - lines = header.readlines() - for line in lines: - if Constants.BLOCKTOOL in line: - _index = lines.index(line) - return bool(_index) - - -def validate_message_port(self, message_ports, suppress_input, suppress_output): - """ - function to solve conflicts if any in the - *message_port* comments and the implementation information - """ - if message_ports['input'] != self.parsed_data['message_port']['input']: - if not suppress_input: - warnings.warn( - 'Conflict in values input message port Id. Add ! at the start of the key-value line to mandatory use the comment value.') - self.parsed_data['message_port']['input'] = message_ports['input'] - if message_ports['output'] != self.parsed_data['message_port']['output']: - if not suppress_output: - warnings.warn( - 'Conflict in values output message port Id. Add ! at the start of the key-value line to mandatory use the comment value.') - self.parsed_data['message_port']['output'] = message_ports['output'] - - -def read_comments(self): - """ - function to read special blocktool comments - in the public header - """ - temp_parsed_data = {} - if self.parsed_data['io_signature'] or self.parsed_data['message_port']: - temp_parsed_data['io_signature'] = self.parsed_data['io_signature'] - temp_parsed_data['message_port'] = self.parsed_data['message_port'] - self.parsed_data['io_signature'] = { - "input": { - "signature": None - }, - "output": { - "signature": None - } - } - self.parsed_data['message_port'] = { - "input": [], - "output": [] - } - _suppress_input = False - _suppress_output = False - parsed_io = self.parsed_data['io_signature'] - message_port = self.parsed_data['message_port'] - special_comments = [] - _index = None - lines = [] - with open(self.target_file, 'r') as header: - lines = header.readlines() - for line in lines: - if Constants.BLOCKTOOL in line: - _index = lines.index(line) - - if _index is not None: - _index = _index+1 - for num in range(_index, len(lines)): - if Constants.END_BLOCKTOOL in lines[num]: - break - special_comments.append(lines[num]) - for comment in special_comments: - if Constants.INPUT_SIG in comment: - parsed_io['input']['signature'] = strip_symbols(comment) - if Constants.INPUT_MAX in comment: - parsed_io['input']['max_streams'] = strip_symbols(comment) - if Constants.INPUT_MIN in comment: - parsed_io['input']['min_streams'] = strip_symbols(comment) - if parsed_io['input']['signature'] is Constants.MAKE and not None: - if Constants.INPUT_MAKE_SIZE in comment: - parsed_io['input']['sizeof_stream_item'] = strip_symbols( - comment) - elif parsed_io['input']['signature'] is Constants.MAKE2 and not None: - if Constants.INPUT_MAKE_SIZE1 in comment: - parsed_io['input']['sizeof_stream_item1'] = strip_symbols( - comment) - if Constants.INPUT_MAKE_SIZE2 in comment: - parsed_io['input']['sizeof_stream_item2'] = strip_symbols( - comment) - elif parsed_io['input']['signature'] is Constants.MAKE3 and not None: - if Constants.INPUT_MAKE_SIZE1 in comment: - parsed_io['input']['sizeof_stream_item1'] = strip_symbols( - comment) - if Constants.INPUT_MAKE_SIZE2 in comment: - parsed_io['input']['sizeof_stream_item2'] = strip_symbols( - comment) - if Constants.INPUT_MAKE_SIZE3 in comment: - parsed_io['input']['sizeof_stream_item3'] = strip_symbols( - comment) - elif parsed_io['input']['signature'] is Constants.MAKEV and not None: - if Constants.INPUT_MAKEV_SIZE in comment: - parsed_io['input']['sizeof_stream_items'] = strip_symbols( - comment) - - if Constants.OUTPUT_SIG in comment: - parsed_io['output']['signature'] = strip_symbols(comment) - if Constants.OUTPUT_MAX in comment: - parsed_io['output']['max_streams'] = strip_symbols(comment) - if Constants.OUTPUT_MIN in comment: - parsed_io['output']['min_streams'] = strip_symbols(comment) - if parsed_io['output']['signature'] is Constants.MAKE and not None: - if Constants.OUTPUT_MAKE_SIZE in comment: - parsed_io['output']['sizeof_stream_item'] = strip_symbols( - comment) - elif parsed_io['output']['signature'] is Constants.MAKE2: - if Constants.OUTPUT_MAKE_SIZE1 in comment: - parsed_io['output']['sizeof_stream_item1'] = strip_symbols( - comment) - if Constants.OUTPUT_MAKE_SIZE2 in comment: - parsed_io['output']['sizeof_stream_item2'] = strip_symbols( - comment) - elif parsed_io['output']['signature'] is Constants.MAKE3 and not None: - if Constants.OUTPUT_MAKE_SIZE1 in comment: - parsed_io['output']['sizeof_stream_item1'] = strip_symbols( - comment) - if Constants.OUTPUT_MAKE_SIZE2 in comment: - parsed_io['output']['sizeof_stream_item2'] = strip_symbols( - comment) - if Constants.OUTPUT_MAKE_SIZE3 in comment: - parsed_io['output']['sizeof_stream_item3'] = strip_symbols( - comment) - elif parsed_io['output']['signature'] is Constants.MAKEV and not None: - if Constants.OUTPUT_MAKEV_SIZE in comment: - parsed_io['output']['sizeof_stream_items'] = strip_symbols( - comment) - - if Constants.INPUT_PORT in comment: - if Constants.EXCLAMATION in comment: - _suppress_input = True - if strip_symbols(comment): - message_port['input'] = strip_symbols(comment).split(', ') - if Constants.OUTPUT_PORT in comment: - if Constants.EXCLAMATION in comment: - _suppress_output = True - if strip_symbols(comment): - message_port['output'] = strip_symbols(comment).split(', ') - validate_message_port( - self, temp_parsed_data['message_port'], _suppress_input, _suppress_output) - self.parsed_data['io_signature'] = temp_parsed_data['io_signature'] - - -def add_comments(self): - """ - function to add special blocktool comments - in the public header - """ - _index = None - lines = [] - parsed_io = self.parsed_data['io_signature'] - message_port = self.parsed_data['message_port'] - with open(self.target_file, 'r') as header: - lines = header.readlines() - for line in lines: - if Constants.BLOCKTOOL in line: - _index = lines.index(line) - if _index is None: - with open(self.target_file, 'a') as header: - header.write('\n') - header.write('/* '+Constants.BLOCKTOOL + '\n') - header.write('input_signature: ' + - parsed_io['input']['signature'] + '\n') - header.write('input_min_streams: ' + - parsed_io['input']['min_streams'] + '\n') - header.write('input_max_streams: ' + - parsed_io['input']['max_streams'] + '\n') - if parsed_io['input']['signature'] is Constants.MAKE: - header.write('input_sizeof_stream_item: ' + - parsed_io['input']['sizeof_stream_item'] + '\n') - elif parsed_io['input']['signature'] is Constants.MAKE2: - header.write('input_sizeof_stream_item1: ' + - parsed_io['input']['sizeof_stream_item1'] + '\n') - header.write('input_sizeof_stream_item2: ' + - parsed_io['input']['sizeof_stream_item2'] + '\n') - elif parsed_io['input']['signature'] is Constants.MAKE3: - header.write('input_sizeof_stream_item1: ' + - parsed_io['input']['sizeof_stream_item1'] + '\n') - header.write('input_sizeof_stream_item2: ' + - parsed_io['input']['sizeof_stream_item2'] + '\n') - header.write('input_sizeof_stream_item3: ' + - parsed_io['input']['sizeof_stream_item3'] + '\n') - elif parsed_io['input']['signature'] is Constants.MAKEV: - header.write('input_sizeof_stream_item: ' + - parsed_io['input']['sizeof_stream_items'] + '\n') - header.write('output_signature: ' + - parsed_io['output']['signature'] + '\n') - header.write('output_min_streams: ' + - parsed_io['output']['min_streams'] + '\n') - header.write('output_max_streams: ' + - parsed_io['output']['max_streams'] + '\n') - if parsed_io['output']['signature'] is Constants.MAKE: - header.write('output_sizeof_stream_item: ' + - parsed_io['output']['sizeof_stream_item'] + '\n') - elif parsed_io['output']['signature'] is Constants.MAKE2: - header.write('output_sizeof_stream_item1: ' + - parsed_io['output']['sizeof_stream_item1'] + '\n') - header.write('output_sizeof_stream_item2: ' + - parsed_io['output']['sizeof_stream_item2'] + '\n') - elif parsed_io['output']['signature'] is Constants.MAKE3: - header.write('output_sizeof_stream_item1: ' + - parsed_io['output']['sizeof_stream_item1'] + '\n') - header.write('output_sizeof_stream_item2: ' + - parsed_io['output']['sizeof_stream_item2'] + '\n') - header.write('output_sizeof_stream_item3: ' + - parsed_io['output']['sizeof_stream_item3'] + '\n') - elif parsed_io['output']['signature'] is Constants.MAKEV: - header.write('output_sizeof_stream_item: ' + - parsed_io['output']['sizeof_stream_items'] + '\n') - - if message_port['input']: - header.write('message_input: ' + - ', '.join(message_port['input']) + '\n') - else: - header.write('message_input: ' + '\n') - if message_port['output']: - header.write('message_output: ' + - ', '.join(message_port['output']) + '\n') - else: - header.write('message_output: ' + '\n') - header.write(Constants.END_BLOCKTOOL + '*/' + '\n') diff --git a/gr-utils/python/blocktool/core/iosignature.py b/gr-utils/python/blocktool/core/iosignature.py deleted file mode 100644 index bf3f04d781..0000000000 --- a/gr-utils/python/blocktool/core/iosignature.py +++ /dev/null @@ -1,182 +0,0 @@ -# -# Copyright 2019 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# SPDX-License-Identifier: GPL-3.0-or-later -# -# -""" Module to get io_signature of the header block """ - -from __future__ import print_function -from __future__ import absolute_import -from __future__ import unicode_literals - -import re -import itertools -import logging -import string - -from ..core import Constants - -LOGGER = logging.getLogger(__name__) - - -def io_signature(impl_file): - """ - function to generate the io_signature of the block - : returns the io parmaters - """ - parsed_io = { - "input": { - "signature": None - }, - "output": { - "signature": None - } - } - with open(impl_file, 'r') as impl: - io_lines = [] - for line in impl: - if Constants.IO_SIGNATURE in line: - io_lines.append(line) - if len(io_lines) > 2: - io_lines = io_lines[0:2] - _io_sig = [] - for line in io_lines: - if Constants.IO_SIGNATURE in line: - line = line.lstrip().rstrip().split(Constants.IO_SIGNATURE) - _io_sig.append(line) - _io_sig = list(itertools.chain.from_iterable(_io_sig)) - for index, _element in enumerate(_io_sig): - _io_sig[index] = _element.lstrip().rstrip() - if all(i in string.punctuation for i in _element): - _io_sig.remove(_element) - _io_sig = list(filter(None, _io_sig)) - io_func = [] - for _io in _io_sig: - if Constants.MAKE in _io: - io_func.append(_io.lstrip().rstrip(Constants.STRIP_SYMBOLS)) - for signature in Constants.SIGNATURE_LIST: - if signature in io_func[0] and parsed_io['input']['signature'] is None: - parsed_io['input']['signature'] = signature - io_func[0] = io_func[0].lstrip(signature+' (') - if signature in io_func[1] and parsed_io['output']['signature'] is None: - parsed_io['output']['signature'] = signature - io_func[1] = io_func[1].lstrip(signature+' (') - io_elements = [] - for _io in io_func: - _io = _io.split(',') - io_elements.append(_io) - io_elements = list(itertools.chain.from_iterable(io_elements)) - for index, _io in enumerate(io_elements): - _io = _io.lstrip(' (').rstrip(' )') - if Constants.OPEN_BRACKET in _io: - _io = _io + Constants.CLOSE_BRACKET - io_elements[index] = _io - - # Because of any possible combination of I/O signature and different number - # of arguments, manual if else loop is required - if parsed_io['input']['signature'] is Constants.MAKE: - parsed_io['input']['min_streams'] = io_elements[0] - parsed_io['input']['max_streams'] = io_elements[1] - parsed_io['input']['sizeof_stream_item'] = io_elements[2] - del io_elements[0:3] - elif parsed_io['input']['signature'] is Constants.MAKE2: - parsed_io['input']['min_streams'] = io_elements[0] - parsed_io['input']['max_streams'] = io_elements[1] - parsed_io['input']['sizeof_stream_item1'] = io_elements[2] - parsed_io['input']['sizeof_stream_item2'] = io_elements[3] - del io_elements[0:4] - elif parsed_io['input']['signature'] is Constants.MAKE3: - parsed_io['input']['min_streams'] = io_elements[0] - parsed_io['input']['max_streams'] = io_elements[1] - parsed_io['input']['sizeof_stream_item1'] = io_elements[2] - parsed_io['input']['sizeof_stream_item2'] = io_elements[3] - parsed_io['input']['sizeof_stream_item3'] = io_elements[4] - del io_elements[0:5] - elif parsed_io['input']['signature'] is Constants.MAKEV: - parsed_io['input']['min_streams'] = io_elements[0] - parsed_io['input']['max_streams'] = io_elements[1] - parsed_io['input']['sizeof_stream_items'] = io_elements[2] - del io_elements[0:3] - - if parsed_io['output']['signature'] is Constants.MAKE: - parsed_io['output']['min_streams'] = io_elements[0] - parsed_io['output']['max_streams'] = io_elements[1] - parsed_io['output']['sizeof_stream_item'] = io_elements[2] - del io_elements[0:3] - elif parsed_io['output']['signature'] is Constants.MAKE2: - parsed_io['output']['min_streams'] = io_elements[0] - parsed_io['output']['max_streams'] = io_elements[1] - parsed_io['output']['sizeof_stream_item1'] = io_elements[2] - parsed_io['output']['sizeof_stream_item2'] = io_elements[3] - del io_elements[0:4] - elif parsed_io['output']['signature'] is Constants.MAKE3: - parsed_io['output']['min_streams'] = io_elements[0] - parsed_io['output']['max_streams'] = io_elements[1] - parsed_io['output']['sizeof_stream_item1'] = io_elements[2] - parsed_io['output']['sizeof_stream_item2'] = io_elements[3] - parsed_io['output']['sizeof_stream_item3'] = io_elements[4] - del io_elements[0:5] - elif parsed_io['output']['signature'] is Constants.MAKEV: - parsed_io['output']['min_streams'] = io_elements[0] - parsed_io['output']['max_streams'] = io_elements[1] - parsed_io['output']['sizeof_stream_items'] = io_elements[2] - del io_elements[0:3] - return parsed_io - - -def message_port(impl_file): - """ - parses message ports from implementation file - """ - parsed_message_port = { - "input": [], - "output": [] - } - with open(impl_file, 'r') as impl: - _input = [] - _output = [] - for line in impl: - if Constants.MESSAGE_INPUT in line: - _input.append(line) - if Constants.MESSAGE_OUTPUT in line: - _output.append(line) - - input_port = [] - output_port = [] - if _input: - for port in _input: - port = port.lstrip().rstrip().strip(Constants.MESSAGE_INPUT) - pattern = port.find('\"') - if pattern != -1: - if re.findall(r'"([^"]*)"', port)[0]: - input_port.append(re.findall(r'"([^"]*)"', port)[0]) - else: - input_port.append(port[port.find('(')+1:port.rfind(')')]) - _temp_port = ''.join(map(str, input_port)) - input_port.clear() - input_port.append(_temp_port) - - if _output: - for port in _output: - port = port.lstrip().rstrip().strip(Constants.MESSAGE_OUTPUT) - pattern = port.find('\"') - if pattern != -1: - if re.findall(r'"([^"]*)"', port)[0]: - output_port.append(re.findall(r'"([^"]*)"', port)[0]) - else: - output_port.append(port[port.find('(')+1:port.rfind(')')]) - _temp_port = ''.join(map(str, output_port)) - output_port.clear() - output_port.append(_temp_port) - - if input_port: - for port in input_port: - parsed_message_port['input'].append(port) - - if output_port: - for port in output_port: - parsed_message_port['output'].append(port) - return parsed_message_port diff --git a/gr-utils/python/blocktool/core/outputschema.py b/gr-utils/python/blocktool/core/outputschema.py deleted file mode 100644 index 4d1bcf88b7..0000000000 --- a/gr-utils/python/blocktool/core/outputschema.py +++ /dev/null @@ -1,157 +0,0 @@ -# -# Copyright 2019 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# SPDX-License-Identifier: GPL-3.0-or-later -# -# -""" Schema to be strictly followed be parsed header output """ - - -RESULT_SCHEMA = { - "title": "JSON SCHEMA TO BE FOLLOWED BY BLOCK HEADER PARSING TOOL", - "description": "Schema designed for the header file parsed python dict output", - "type": "object", - "properties": { - "namespace": { - "description": "List of nested namspace", - "type": "array", - "minItems": 1, - "uniqueItems": True, - "items": { - "type": "string", - "minLength": 1 - } - }, - "class": { - "description": "Class name", - "type": "string", - "minLength": 1 - }, - "io_signature": { - "description": "I/O signature", - "type": "object", - "properties": { - "input": { - "description": "Input ports", - "type": "object" - }, - "output": { - "description": "Output ports", - "type": "object" - } - }, - "required": ["input", "output"] - }, - "make": { - "description": "Make function", - "type": "object", - "properties": { - "arguments": { - "description": "Arguments of make function", - "type": "array", - "minItems": 1, - "uniqueItems": True, - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "minLength": 1 - }, - "dtype": { - "type": "string", - "minLength": 1 - }, - "default": { - "type": "string" - } - }, - "required": ["name"], - "dependencies": { - "name": [ - "dtype", - "default" - ] - } - } - } - } - }, - "methods": { - "description": "Setters", - "type": "array", - "minItems": 0, - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "minLength": 1 - }, - "arguments_type": { - "type": "array", - "uniqueItems": True, - "properties": { - "name": { - "type": "string", - "minLength": 1 - }, - "dtype": { - "type": "string", - "minLength": 1 - } - }, - "required": ["name"], - "dependencies": { - "name": ["dtype"] - } - } - }, - "required": ["name"] - } - }, - "properties": { - "description": "Getters", - "type": "array", - "uniqueItems": True, - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "minLength": 1 - }, - "dtype": { - "type": "string", - "minLength": 1 - }, - "read_only": { - "type": "boolean" - } - }, - "required": ["name"], - "dependencies": { - "name": [ - "dtype", - "read_only" - ] - } - } - }, - "docstring": { - "description": "documentation of the header file", - "type": "array" - } - }, - "required": [ - "namespace", - "class", - "io_signature", - "make", - "methods", - "properties", - "docstring" - ] -} diff --git a/gr-utils/python/blocktool/core/parseheader.py b/gr-utils/python/blocktool/core/parseheader.py deleted file mode 100644 index 59d4ac33f3..0000000000 --- a/gr-utils/python/blocktool/core/parseheader.py +++ /dev/null @@ -1,271 +0,0 @@ -# -# Copyright 2019 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# SPDX-License-Identifier: GPL-3.0-or-later -# -# -""" Module to generate AST for the headers and parse it """ - -from __future__ import print_function -from __future__ import absolute_import -from __future__ import unicode_literals - -import os -import re -import codecs -import logging - -from pygccxml import parser, declarations, utils - -from ..core.base import BlockToolException, BlockTool -from ..core.iosignature import io_signature, message_port -from ..core.comments import read_comments, add_comments, exist_comments -from ..core import Constants - -LOGGER = logging.getLogger(__name__) - - -class BlockHeaderParser(BlockTool): - """ - : Single argument required: file_path - file_path: enter path for the header block in any of GNU Radio module - : returns the parsed header data in python dict - : return dict keys: namespace, class, io_signature, make, - properties, methods - : Can be used as an CLI command or an extenal API - """ - name = 'Block Parse Header' - description = 'Create a parsed output from a block header file' - - def __init__(self, file_path=None, blocktool_comments=False, include_paths=None, **kwargs): - """ __init__ """ - BlockTool.__init__(self, **kwargs) - self.parsed_data = {} - self.addcomments = blocktool_comments - self.include_paths = None - if (include_paths): - self.include_paths = [p.strip() for p in include_paths.split(',')] - if not os.path.isfile(file_path): - raise BlockToolException('file does not exist') - file_path = os.path.abspath(file_path) - self.target_file = file_path - self.initialize() - self.validate() - - def initialize(self): - """ - initialize all the required API variables - """ - self.module = self.target_file - for dirs in self.module: - if not os.path.basename(self.module).startswith(Constants.GR): - self.module = os.path.abspath( - os.path.join(self.module, os.pardir)) - self.modname = os.path.basename(self.module) - self.filename = os.path.basename(self.target_file) - self.targetdir = os.path.dirname(self.target_file) - for dirs in os.scandir(self.module): - if dirs.is_dir(): - if dirs.path.endswith('lib'): - self.impldir = dirs.path - self.impl_file = os.path.join(self.impldir, - self.filename.split('.')[0]+'_impl.cc') - - def validate(self): - """ Override the Blocktool validate function """ - BlockTool._validate(self) - if not self.filename.endswith('.h'): - raise BlockToolException( - 'Cannot parse a non-header file') - - def get_header_info(self): - """ - PyGCCXML header code parser - magic happens here! - : returns the parsed header data in python dict - : return dict keys: namespace, class, io_signature, make, - properties, methods - : Can be used as an CLI command or an extenal API - """ - gr = self.modname.split('-')[0] - module = self.modname.split('-')[-1] - generator_path, generator_name = utils.find_xml_generator() - xml_generator_config = parser.xml_generator_configuration_t( - xml_generator_path=generator_path, - xml_generator=generator_name, - include_paths=self.include_paths, - compiler='gcc', - define_symbols=['BOOST_ATOMIC_DETAIL_EXTRA_BACKEND_GENERIC'], - cflags='-std=c++11') - decls = parser.parse( - [self.target_file], xml_generator_config) - global_namespace = declarations.get_global_namespace(decls) - - # namespace - try: - self.parsed_data['namespace'] = [] - ns = global_namespace.namespace(gr) - if ns is None: - raise BlockToolException - main_namespace = ns.namespace(module) - if main_namespace is None: - raise BlockToolException('namespace cannot be none') - self.parsed_data['namespace'] = [gr, module] - if main_namespace.declarations: - for _namespace in main_namespace.declarations: - if isinstance(_namespace, declarations.namespace_t): - if Constants.KERNEL not in str(_namespace): - main_namespace = _namespace - self.parsed_data['namespace'].append( - str(_namespace).split('::')[-1].split(' ')[0]) - except RuntimeError: - raise BlockToolException( - 'Invalid namespace format in the block header file') - - # class - try: - self.parsed_data['class'] = '' - for _class in main_namespace.declarations: - if isinstance(_class, declarations.class_t): - main_class = _class - self.parsed_data['class'] = str(_class).split('::')[ - 2].split(' ')[0] - except RuntimeError: - raise BlockToolException( - 'Block header namespace {} must consist of a valid class instance'.format(module)) - - # io_signature, message_ports - self.parsed_data['io_signature'] = {} - self.parsed_data['message_port'] = {} - if os.path.isfile(self.impl_file) and exist_comments(self): - self.parsed_data['io_signature'] = io_signature( - self.impl_file) - self.parsed_data['message_port'] = message_port( - self.impl_file) - read_comments(self) - elif os.path.isfile(self.impl_file) and not exist_comments(self): - self.parsed_data['io_signature'] = io_signature( - self.impl_file) - self.parsed_data['message_port'] = message_port( - self.impl_file) - if self.addcomments: - add_comments(self) - elif not os.path.isfile(self.impl_file) and exist_comments(self): - read_comments(self) - else: - self.parsed_data['io_signature'] = { - "input": [], - "output": [] - } - self.parsed_data['message_port'] = self.parsed_data['io_signature'] - - # make - try: - self.parsed_data['make'] = {} - self.parsed_data['make']['arguments'] = [] - query_m = declarations.custom_matcher_t( - lambda mem_fun: mem_fun.name.startswith('make')) - query_make = query_m & declarations.access_type_matcher_t('public') - make_func = main_class.member_functions(function=query_make, - allow_empty=True, - header_file=self.target_file) - criteria = declarations.calldef_matcher(name='make') - _make_fun = declarations.matcher.get_single(criteria, main_class) - _make_fun = str(_make_fun).split( - 'make')[-1].split(')')[0].split('(')[1].lstrip().rstrip().split(',') - if make_func: - for arg in make_func[0].arguments: - for _arg in _make_fun: - if str(arg.name) in _arg: - make_arguments = { - "name": str(arg.name), - "dtype": str(arg.decl_type), - "default": "" - } - if re.findall(r'[-+]?\d*\.\d+|\d+', _arg): - make_arguments['default'] = re.findall( - r'[-+]?\d*\.\d+|\d+', _arg)[0] - elif re.findall(r'\"(.+?)\"', _arg): - make_arguments['default'] = re.findall( - r'\"(.+?)\"', _arg)[0] - elif "true" in _arg: - make_arguments['default'] = "True" - elif "false" in _arg: - make_arguments['default'] = "False" - self.parsed_data['make']['arguments'].append( - make_arguments.copy()) - except RuntimeError: - self.parsed_data['make'] = {} - self.parsed_data['make']['arguments'] = [] - - # setters - try: - self.parsed_data['methods'] = [] - query_methods = declarations.access_type_matcher_t('public') - setters = main_class.member_functions(function=query_methods, - allow_empty=True, - header_file=self.target_file) - getter_arguments = [] - if setters: - for setter in setters: - if str(setter.name).startswith('set_') and setter.arguments: - setter_args = { - "name": str(setter.name), - "arguments_type": [] - } - for argument in setter.arguments: - args = { - "name": str(argument.name), - "dtype": str(argument.decl_type) - } - getter_arguments.append(args['name']) - setter_args['arguments_type'].append(args.copy()) - self.parsed_data['methods'].append(setter_args.copy()) - except RuntimeError: - self.parsed_data['methods'] = [] - - # getters - try: - self.parsed_data['properties'] = [] - query_properties = declarations.access_type_matcher_t('public') - getters = main_class.member_functions(function=query_properties, - allow_empty=True, - header_file=self.target_file) - if getters: - for getter in getters: - if not getter.arguments or getter.has_const: - getter_args = { - "name": str(getter.name), - "dtype": str(getter.return_type), - "read_only": True - } - if getter_args['name'] in getter_arguments: - getter_args["read_only"] = False - self.parsed_data['properties'].append( - getter_args.copy()) - except RuntimeError: - self.parsed_data['properties'] = [] - - # documentation - try: - _index = None - header_file = codecs.open(self.target_file, 'r', 'cp932') - self.parsed_data['docstring'] = re.compile( - r'//.*?$|/\*.*?\*/', re.DOTALL | re.MULTILINE).findall( - header_file.read())[2:] - header_file.close() - for doc in self.parsed_data['docstring']: - if Constants.BLOCKTOOL in doc: - _index = self.parsed_data['docstring'].index(doc) - if _index is not None: - self.parsed_data['docstring'] = self.parsed_data['docstring'][: _index] - except: - self.parsed_data['docstring'] = [] - - return self.parsed_data - - def run_blocktool(self): - """ Run, run, run. """ - self.get_header_info() |