-
Notifications
You must be signed in to change notification settings - Fork 1
/
cpaths.py
128 lines (102 loc) · 3.9 KB
/
cpaths.py
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
"""
Output paths in C header file format
"""
import sys
import os.path
import re
from pyang import plugin
from pyang import statements
from pyang import error
def pyang_plugin_init():
plugin.register_plugin(PathPlugin())
class PathPlugin(plugin.PyangPlugin):
def add_output_format(self, fmts):
self.multiple_modules = True
fmts['cpaths'] = self
def emit(self, ctx, modules, fd):
for module in modules:
children = [child for child in module.i_children]
for child in children:
print_node(child, module, fd, ctx)
fd.write('\n')
def mk_path_str(s, level=0, strip=0, fd=None):
#print('LEVEL: ' + str(level) + ' STRIP:' + str(strip) + ' ' + s.arg)
if level > strip:
p = mk_path_str(s.parent, level - 1, strip)
if p != "":
return p + "/" + s.arg
return s.arg
if level == strip:
return s.arg
else:
return ""
def mk_path_str_define(s):
if s.parent.keyword in ['module', 'submodule']:
return "/" + s.arg
else:
p = mk_path_str_define(s.parent)
return p + "/" + s.arg
def print_node(node, module, fd, ctx, level=0, strip=0):
#print('TYPE:' + node.keyword + 'LEVEL:' + str(level) + 'STRIP:' + str(strip))
# No need to include these nodes
if node.keyword in ['rpc', 'notification']:
return
# Strip all nodes from the path at list items
if node.parent.keyword == 'list':
strip = level
# Create path value
value = mk_path_str(node, level, strip, fd)
if strip == 0:
value = "/" + value
# Create define
if node.keyword in ['choice', 'case']:
pathstr = mk_path_str_define(node)
else:
pathstr = statements.mk_path_str(node, False)
if node.keyword == 'container' or node.keyword == 'list':
define = pathstr[1:].upper().replace('/', '_').replace('-', '_') + '_PATH'
else:
define = pathstr[1:].upper().replace('/', '_').replace('-', '_')
# Description
descr = node.search_one('description')
if descr is not None:
descr.arg = descr.arg.replace('\r', ' ').replace('\n', ' ')
fd.write('/* ' + descr.arg + ' */\n')
# Ouput define
fd.write('#define ' + define + ' "' + value + '"\n')
type = node.search_one('type')
if type is not None:
if type.arg == 'boolean':
fd.write('#define ' + define + '_TRUE "true"\n')
fd.write('#define ' + define + '_FALSE "false"\n')
if type.arg == 'enumeration':
count = 0
for enum in type.substmts:
val = enum.search_one('value')
if val is not None:
fd.write('#define ' + define + '_' + enum.arg.upper().replace('-', '_') + ' ' + str(val.arg) + '\n')
try:
val_int = int(val.arg)
except:
val_int = None
if val_int is not None:
count = val_int
else:
fd.write('#define ' + define + '_' + enum.arg.upper().replace('-', '_') + ' ' + str(count) + '\n')
count = count + 1
# Default value
def_val = node.search_one('default')
if def_val is not None:
if type is not None and 'int' in type.arg:
fd.write('#define ' + define + '_DEFAULT ' + def_val.arg + '\n')
elif type is not None and type.arg == 'enumeration':
for enum in type.substmts:
val = enum.search_one('value')
if def_val.arg == enum.arg and val is not None:
fd.write('#define ' + define + '_DEFAULT ' + val.arg + '\n')
else:
fd.write('#define ' + define + '_DEFAULT "' + def_val.arg + '"\n')
# Process children
if hasattr(node, 'i_children'):
for child in node.i_children:
print_node(child, module, fd, ctx, level + 1, strip)