1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#
# Copyright 2018 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
#
""" A tool for generating YAML bindings """
from __future__ import print_function
from __future__ import absolute_import
from __future__ import unicode_literals
from collections import OrderedDict
import yaml
try:
from yaml import CLoader as Loader, CDumper as Dumper
except:
from yaml import Loader, Dumper
from .util_functions import is_number
## setup dumper for dumping OrderedDict ##
_mapping_tag = yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG
def dict_representer(dumper, data):
""" Representer to represent special OrderedDict """
return dumper.represent_dict(data.items())
def dict_constructor(loader, node):
""" Construct an OrderedDict for dumping """
return OrderedDict(loader.construct_pairs(node))
Dumper.add_representer(OrderedDict, dict_representer)
Loader.add_constructor(_mapping_tag, dict_constructor)
class GRCYAMLGenerator(object):
""" Create and write the YAML bindings for a GRC block. """
def __init__(self, modname=None, blockname=None, doc=None, params=None, iosig=None):
"""docstring for __init__"""
params_list = ['${'+s['key']+'}' for s in params if s['in_constructor']]
# Can't make a dict 'cause order matters
self._header = (('id', '{}_{}'.format(modname, blockname)),
('label', blockname.replace('_', ' ')),
('category', '[{}]'.format(modname.capitalize()))
)
self._templates = (('imports', 'import {}'.format(modname)),
('make', '{}.{}({})'.format(modname, blockname, ', '.join(params_list)))
)
self.params = params
self.iosig = iosig
self.doc = doc
self.data = None
def make_yaml(self):
""" Create the actual tag tree """
data = OrderedDict()
for tag, value in self._header:
data[tag] = value
templates = OrderedDict()
for tag, value in self._templates:
templates[tag] = value
data['templates'] = templates
parameters = []
for param in self.params:
parameter = OrderedDict()
parameter['id'] = param['key']
parameter['label'] = param['key'].capitalize()
if param['default']:
parameter['default'] = param['default']
parameter['dtype'] = param['type']
parameters.append(parameter)
if parameters:
data['parameters'] = parameters
inputs = []
outputs = []
iosig = self.iosig
for inout in sorted(iosig.keys()):
if iosig[inout]['max_ports'] == '0':
continue
for i in range(len(iosig[inout]['type'])):
s_type = {'in': 'input', 'out': 'output'}[inout]
s_obj = OrderedDict()
s_obj['label'] = inout
s_obj['domain'] = 'stream'
s_obj['dtype'] = iosig[inout]['type'][i]
if iosig[inout]['vlen'][i] != '1':
vlen = iosig[inout]['vlen'][i]
if is_number(vlen):
s_obj['vlen'] = vlen
else:
s_obj['vlen'] = '${ '+vlen+' }'
if i == len(iosig[inout]['type'])-1:
if not is_number(iosig[inout]['max_ports']):
s_obj['multiplicity'] = iosig[inout]['max_ports']
elif len(iosig[inout]['type']) < int(iosig[inout]['max_ports']):
s_obj['multiplicity'] = str(int(iosig[inout]['max_ports']) -
len(iosig[inout]['type'])+1)
if s_type == 'input':
inputs.append(s_obj)
elif s_type == 'output':
outputs.append(s_obj)
if inputs:
data['inputs'] = inputs
if outputs:
data['outputs'] = outputs
if self.doc is not None:
data['documentation'] = self.doc
self.data = data
data['file_format'] = 1
def save(self, filename):
""" Write the YAML file """
self.make_yaml()
with open(filename, 'w') as f:
yaml.dump(self.data, f, Dumper=Dumper, default_flow_style=False)
|