-
Notifications
You must be signed in to change notification settings - Fork 1
/
yang-catalog-index.py
145 lines (118 loc) · 4.82 KB
/
yang-catalog-index.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
from pyang import plugin, statements
import json
import optparse
import re
_yang_catalog_index_fd = None
def pyang_plugin_init():
plugin.register_plugin(IndexerPlugin())
class IndexerPlugin(plugin.PyangPlugin):
def add_output_format(self, fmts):
self.multiple_modules = True
fmts['yang-catalog-index'] = self
def add_opts(self, optparser):
optlist = [
optparse.make_option("--yang-index-no-schema",
dest="yang_index_no_schema",
action="store_true",
help="""Do not include SQLite schema in output"""),
optparse.make_option("--yang-index-schema-only",
dest="yang_index_schema_only",
action="store_true",
help="""Only include the SQLite schema in output"""),
optparse.make_option("--yang-index-make-module-table",
dest="yang_index_make_module_table",
action="store_true",
help="""Generate a modules table that includes various aspects about the modules themselves""")
]
g = optparser.add_option_group("YANG Catalog Index specific options")
g.add_options(optlist)
def setup_fmt(self, ctx):
ctx.implicit_errors = False
def emit(self, ctx, modules, fd):
global _yang_catalog_index_fd
_yang_catalog_index_fd = fd
emit_index(ctx, modules, fd)
def emit_index(ctx, modules, fd):
if not ctx.opts.yang_index_no_schema:
fd.write(
"create table yindex(module, path, statement, argument, description, properties);\n")
if ctx.opts.yang_index_make_module_table:
fd.write(
"create table modules(module, belongs_to, namespace, prefix, organization, maturity);\n")
if not ctx.opts.yang_index_schema_only:
for module in modules:
if ctx.opts.yang_index_make_module_table:
index_mprinter(module)
non_chs = module.i_typedefs.values() + module.i_features.values() + module.i_identities.values() + \
module.i_groupings.values() + module.i_extensions.values()
for nch in non_chs:
index_printer(nch)
for child in module.i_children:
statements.iterate_i_children(child, index_printer)
def index_mprinter(module):
global _yang_catalog_index_fd
params = [module.arg]
args = ['belongs-to', 'namespace', 'prefix', 'organization']
for a in args:
nlist = module.search(a)
nstr = ''
if nlist:
nstr = nlist[0].arg
nstr = nstr.replace("'", r"''")
params.append(nstr)
else:
params.append('')
# Attempt to normalize the organization for catalog retrieval.
m = re.search(r"urn:([^:]+):", params[2])
if m:
params[4] = m.group(1)
# We don't yet know the maturity of the module, but we can get that from
# the catalog later.
_yang_catalog_index_fd.write(
"insert into modules values('%s', '%s', '%s', '%s', '%s', '');" % tuple(params) + "\n")
def index_escape_json(s):
return s.replace("\\", r"\\").replace("'", r"''").replace("\n", r"\n").replace("\t", r"\t").replace("\"", r"\"")
def index_get_other(stmt):
a = stmt.arg
k = stmt.keyword
if type(stmt.keyword) is tuple:
k = ':'.join(map(str, stmt.keyword))
if a:
a = index_escape_json(a)
else:
a = ''
child = {k: {'value': a, 'has_children': False}}
child[k]['children'] = []
for ss in stmt.substmts:
child[k]['has_children'] = True
child[k]['children'].append(index_get_other(ss))
return child
def index_printer(stmt):
global _yang_catalog_index_fd
if stmt.arg is None:
return
module = stmt.main_module()
path = statements.mk_path_str(stmt, True)
descr = stmt.search('description')
dstr = ''
if descr:
dstr = descr[0].arg
dstr = dstr.replace("'", r"''")
subs = []
for i in stmt.substmts:
a = i.arg
k = i.keyword
if type(i.keyword) is tuple:
k = ':'.join(map(str, i.keyword))
if i.keyword not in statements.data_definition_keywords:
subs.append(index_get_other(i))
else:
has_children = hasattr(i, 'i_children') and len(i.i_children) > 0
if not a:
a = ''
else:
a = index_escape_json(a)
subs.append(
{k: {'value': a, 'has_children': has_children, 'children': []}})
_yang_catalog_index_fd.write("insert into yindex values('%s', '%s', '%s', '%s', '%s', '%s');" % (
module.arg, path, stmt.keyword, stmt.arg, dstr, json.dumps(subs)) + "\n")