Marcus Müller 6982b777f9 GRC: enable setting of documentation URLs, relative or absolute in yaml
Signed-off-by: Marcus Müller <mmueller@gnuradio.org>
2023-12-02 15:08:58 -05:00

171 lines
5.4 KiB
Python

# Copyright 2016 Free Software Foundation, Inc.
# This file is part of GNU Radio
#
# SPDX-License-Identifier: GPL-2.0-or-later
#
import itertools
import re
from typing import Type
from ..Constants import ADVANCED_PARAM_TAB
from ..utils import to_list
from ..Messages import send_warning
from .block import Block
from ._flags import Flags
from ._templates import MakoTemplates
def build(id,
label='',
category='',
flags='',
documentation='',
value=None,
asserts=None,
parameters=None,
inputs=None,
outputs=None,
templates=None,
cpp_templates=None,
doc_url=None,
**kwargs) -> Type[Block]:
block_id = id
cls = type(str(block_id), (Block,), {})
cls.key = block_id
cls.label = label or block_id.title()
cls.category = [cat.strip() for cat in category.split('/') if cat.strip()]
cls.flags = Flags(flags)
if re.match(r'options$|variable|virtual', block_id):
cls.flags.set(Flags.NOT_DSP, Flags.DISABLE_BYPASS)
cls.documentation = {'': documentation.strip('\n\t ').replace('\\\n', '')}
cls.asserts = [_single_mako_expr(a, block_id) for a in to_list(asserts)]
cls.inputs_data = build_ports(inputs, 'sink') if inputs else []
cls.outputs_data = build_ports(outputs, 'source') if outputs else []
cls.parameters_data = build_params(parameters or [],
bool(cls.inputs_data), bool(cls.outputs_data), cls.flags, block_id)
cls.extra_data = kwargs
templates = templates or {}
cls.templates = MakoTemplates(
imports=templates.get('imports', ''),
make=templates.get('make', ''),
callbacks=templates.get('callbacks', []),
var_make=templates.get('var_make', ''),
)
cpp_templates = cpp_templates or {}
cls.cpp_templates = MakoTemplates(
includes=cpp_templates.get('includes', []),
make=cpp_templates.get('make', ''),
callbacks=cpp_templates.get('callbacks', []),
var_make=cpp_templates.get('var_make', ''),
link=cpp_templates.get('link', []),
packages=cpp_templates.get('packages', []),
translations=cpp_templates.get('translations', []),
declarations=cpp_templates.get('declarations', ''),
)
cls.doc_url = doc_url if doc_url else ""
# todo: MakoTemplates.compile() to check for errors
cls.value = _single_mako_expr(value, block_id)
return cls
def build_ports(ports_raw, direction):
ports = []
port_ids = set()
stream_port_ids = itertools.count()
for i, port_params in enumerate(ports_raw):
port = port_params.copy()
port['direction'] = direction
port_id = port.setdefault('id', str(next(stream_port_ids)))
if port_id in port_ids:
raise Exception(
'Port id "{}" already exists in {}s'.format(port_id, direction))
port_ids.add(port_id)
ports.append(port)
return ports
def build_params(params_raw, have_inputs, have_outputs, flags, block_id):
params = []
def add_param(**data):
params.append(data)
if flags.SHOW_ID in flags:
add_param(id='id', name='ID', dtype='id', hide='none')
else:
add_param(id='id', name='ID', dtype='id', hide='all')
if not flags.not_dsp:
add_param(id='alias', name='Block Alias', dtype='string',
hide='part', category=ADVANCED_PARAM_TAB)
if have_outputs or have_inputs:
add_param(id='affinity', name='Core Affinity', dtype='int_vector',
hide='part', category=ADVANCED_PARAM_TAB)
if have_outputs:
add_param(id='minoutbuf', name='Min Output Buffer', dtype='int',
hide='part', default='0', category=ADVANCED_PARAM_TAB)
add_param(id='maxoutbuf', name='Max Output Buffer', dtype='int',
hide='part', default='0', category=ADVANCED_PARAM_TAB)
base_params_n = {}
for param_data in params_raw:
param_id = param_data['id']
if param_id in params:
raise Exception('Param id "{}" is not unique'.format(param_id))
base_key = param_data.get('base_key', None)
param_data_ext = base_params_n.get(base_key, {}).copy()
param_data_ext.update(param_data)
if 'option_attributes' in param_data:
_validate_option_attributes(param_data_ext, block_id)
add_param(**param_data_ext)
base_params_n[param_id] = param_data_ext
add_param(id='comment', name='Comment', dtype='_multiline', hide='part',
default='', category=ADVANCED_PARAM_TAB)
return params
def _single_mako_expr(value, block_id):
if not value:
return None
value = value.strip()
if not (value.startswith('${') and value.endswith('}')):
raise ValueError(
'{} is not a mako substitution in {}'.format(value, block_id))
return value[2:-1].strip()
def _validate_option_attributes(param_data, block_id):
if param_data['dtype'] != 'enum':
send_warning(
'{} - option_attributes are for enums only, ignoring'.format(block_id))
del param_data['option_attributes']
else:
for key in list(param_data['option_attributes'].keys()):
if key in dir(str):
del param_data['option_attributes'][key]
send_warning(
'{} - option_attribute "{}" overrides str, ignoring'.format(block_id, key))