diff options
author | Swapnil Negi <swapnil.negi09@gmail.com> | 2019-01-04 18:29:50 +0100 |
---|---|---|
committer | Andrej Rode <mail@andrejro.de> | 2019-01-04 18:58:02 +0100 |
commit | 055287896c8c97eb0cdda825559e217d8db54a14 (patch) | |
tree | 613262f5ed45ba4eaadf1bd76009aa16ad22806f /gr-utils/python/modtool/parser_cc_block.py | |
parent | 2fcf3b8afe51092003b7f916edb9e5d6372d4842 (diff) |
modtool: gr-modtool overhaul GSoC 2018
This commit contains all the changes done during the 2018 GSoC
"gr-modtool overhaul".
Changes include:
- Rewrite of gr-modtool based on Python Click
- Split of gr-modtool in cli and core
- Adherence to new GNU Radio 3.8 API for OOTs
- Pylint improvements
- Py3k and Py2k compatibility
This feature is merged in a squash-merge due to big refactoring
on the head and base branch and the impossibility to unclutter both.
Diffstat (limited to 'gr-utils/python/modtool/parser_cc_block.py')
-rw-r--r-- | gr-utils/python/modtool/parser_cc_block.py | 228 |
1 files changed, 0 insertions, 228 deletions
diff --git a/gr-utils/python/modtool/parser_cc_block.py b/gr-utils/python/modtool/parser_cc_block.py deleted file mode 100644 index 766b063ccd..0000000000 --- a/gr-utils/python/modtool/parser_cc_block.py +++ /dev/null @@ -1,228 +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. -# -''' A parser for blocks written in C++ ''' - -from __future__ import print_function -from __future__ import unicode_literals - -import re -import sys - -def dummy_translator(the_type, default_v=None): - """ Doesn't really translate. """ - return the_type - -class ParserCCBlock(object): - """ Class to read blocks written in C++ """ - def __init__(self, filename_cc, filename_h, blockname, version, type_trans=dummy_translator): - self.code_cc = open(filename_cc).read() - self.code_h = open(filename_h).read() - self.blockname = blockname - self.type_trans = type_trans - self.version = version - - def read_io_signature(self): - """ Scans a .cc file for an IO signature. """ - def _figure_out_iotype_and_vlen(iosigcall, typestr): - """ From a type identifier, returns the data type. - E.g., for sizeof(int), it will return 'int'. - Returns a list! """ - if 'gr::io_signature::makev' in iosigcall: - print('tbi') - raise ValueError - return {'type': [_typestr_to_iotype(x) for x in typestr.split(',')], - 'vlen': [_typestr_to_vlen(x) for x in typestr.split(',')] - } - def _typestr_to_iotype(typestr): - """ Convert a type string (e.g. sizeof(int) * vlen) to the type (e.g. 'int'). """ - type_match = re.search(r'sizeof\s*\(([^)]*)\)', typestr) - if type_match is None: - return self.type_trans('char') - return self.type_trans(type_match.group(1)) - def _typestr_to_vlen(typestr): - """ From a type identifier, returns the vector length of the block's - input/out. E.g., for 'sizeof(int) * 10', it returns 10. For - 'sizeof(int)', it returns '1'. For 'sizeof(int) * vlen', it returns - the string vlen. """ - # Catch fringe case where no sizeof() is given - if typestr.find('sizeof') == -1: - return typestr - if typestr.find('*') == -1: - return '1' - vlen_parts = typestr.split('*') - for fac in vlen_parts: - if fac.find('sizeof') != -1: - vlen_parts.remove(fac) - if len(vlen_parts) == 1: - return vlen_parts[0].strip() - elif len(vlen_parts) > 1: - return '*'.join(vlen_parts).strip() - iosig = {} - iosig_regex = r'(?P<incall>gr::io_signature::make[23v]?)\s*\(\s*(?P<inmin>[^,]+),\s*(?P<inmax>[^,]+),' + \ - r'\s*(?P<intype>(\([^\)]*\)|[^)])+)\),\s*' + \ - r'(?P<outcall>gr::io_signature::make[23v]?)\s*\(\s*(?P<outmin>[^,]+),\s*(?P<outmax>[^,]+),' + \ - r'\s*(?P<outtype>(\([^\)]*\)|[^)])+)\)' - iosig_match = re.compile(iosig_regex, re.MULTILINE).search(self.code_cc) - try: - iosig['in'] = _figure_out_iotype_and_vlen(iosig_match.group('incall'), - iosig_match.group('intype')) - iosig['in']['min_ports'] = iosig_match.group('inmin') - iosig['in']['max_ports'] = iosig_match.group('inmax') - except Exception: - print("Error: Can't parse input signature.") - try: - iosig['out'] = _figure_out_iotype_and_vlen(iosig_match.group('outcall'), - iosig_match.group('outtype')) - iosig['out']['min_ports'] = iosig_match.group('outmin') - iosig['out']['max_ports'] = iosig_match.group('outmax') - except Exception: - print("Error: Can't parse output signature.") - return iosig - - - def read_params(self): - """ Read the parameters required to initialize the block """ - def _scan_param_list(start_idx): - """ Go through a parameter list and return a tuple each: - (type, name, default_value). Python's re just doesn't cut - it for C++ code :( """ - i = start_idx - c = self.code_h - if c[i] != '(': - raise ValueError - i += 1 - - param_list = [] - read_state = 'type' - in_string = False - parens_count = 0 # Counts () - brackets_count = 0 # Counts <> - end_of_list = False - this_type = '' - this_name = '' - this_defv = '' - WHITESPACE = ' \t\n\r\f\v' - while not end_of_list: - # Keep track of (), stop when reaching final closing parens - if not in_string: - if c[i] == ')': - if parens_count == 0: - if read_state == 'type' and len(this_type): - raise ValueError( - 'Found closing parentheses before finishing last argument (this is how far I got: %s)' - % str(param_list) - ) - if len(this_type): - param_list.append((this_type, this_name, this_defv)) - end_of_list = True - break - else: - parens_count -= 1 - elif c[i] == '(': - parens_count += 1 - # Parameter type (int, const std::string, std::vector<gr_complex>, unsigned long ...) - if read_state == 'type': - if c[i] == '<': - brackets_count += 1 - if c[i] == '>': - brackets_count -= 1 - if c[i] == '&': - i += 1 - continue - if c[i] in WHITESPACE and brackets_count == 0: - while c[i] in WHITESPACE: - i += 1 - continue - if this_type == 'const' or this_type == '': # Ignore this - this_type = '' - elif this_type == 'unsigned': # Continue - this_type += ' ' - continue - else: - read_state = 'name' - continue - this_type += c[i] - i += 1 - continue - # Parameter name - if read_state == 'name': - if c[i] == '&' or c[i] in WHITESPACE: - i += 1 - elif c[i] == '=': - if parens_count != 0: - raise ValueError( - 'While parsing argument %d (%s): name finished but no closing parentheses.' - % (len(param_list)+1, this_type + ' ' + this_name) - ) - read_state = 'defv' - i += 1 - elif c[i] == ',': - if parens_count: - raise ValueError( - 'While parsing argument %d (%s): name finished but no closing parentheses.' - % (len(param_list)+1, this_type + ' ' + this_name) - ) - read_state = 'defv' - else: - this_name += c[i] - i += 1 - continue - # Default value - if read_state == 'defv': - if in_string: - if c[i] == '"' and c[i-1] != '\\': - in_string = False - else: - this_defv += c[i] - elif c[i] == ',': - if parens_count: - raise ValueError( - 'While parsing argument %d (%s): default value finished but no closing parentheses.' - % (len(param_list)+1, this_type + ' ' + this_name) - ) - read_state = 'type' - param_list.append((this_type, this_name, this_defv)) - this_type = '' - this_name = '' - this_defv = '' - else: - this_defv += c[i] - i += 1 - continue - return param_list - # Go, go, go! - if self.version in ('37', '38'): - make_regex = r'static\s+sptr\s+make\s*' - else: - make_regex = r'(?<=_API)\s+\w+_sptr\s+\w+_make_\w+\s*' - make_match = re.compile(make_regex, re.MULTILINE).search(self.code_h) - try: - params_list = _scan_param_list(make_match.end(0)) - except ValueError as ve: - print("Can't parse the argument list: ", ve.args[0]) - sys.exit(0) - params = [] - for plist in params_list: - params.append({'type': self.type_trans(plist[0], plist[2]), - 'key': plist[1], - 'default': plist[2], - 'in_constructor': True}) - return params |