]> git.proxmox.com Git - mirror_frr.git/blob - yang/embedmodel.py
Merge pull request #6943 from ton31337/fix/replace_sizeof_instead_of_constant_for_bgp...
[mirror_frr.git] / yang / embedmodel.py
1 #!/usr/bin/python3
2 #
3 # YANG module to C wrapper
4 # written 2018 by David Lamparter, placed in Public Domain.
5
6 import sys
7 import os
8 import string
9 import re
10
11 inname = sys.argv[1]
12 outname = sys.argv[2]
13
14 outdir = os.path.dirname(os.path.abspath(outname))
15 if not os.path.isdir(outdir):
16 os.makedirs(outdir)
17
18 # these are regexes to avoid a compile-time/host dependency on yang-tools
19 # or python-yang. Cross-compiling FRR is already somewhat involved, no need
20 # to make it even harder.
21
22 re_name = re.compile(r'\bmodule\s+([^\s]+)\s+\{')
23 re_subname = re.compile(r'\bsubmodule\s+([^\s]+)\s+\{')
24 re_mainname = re.compile(r'\bbelongs-to\s+([^\s]+)\s+\{')
25 re_rev = re.compile(r'\brevision\s+([\d-]+)\s+\{')
26
27
28 template = '''/* autogenerated by embedmodel.py. DO NOT EDIT */
29
30 #include <zebra.h>
31 #include "yang.h"
32
33 static const char model[] =
34 \t"%s";
35
36 static struct yang_module_embed embed = {
37 \t.mod_name = "%s",
38 \t.mod_rev = "%s",
39 \t.sub_mod_name = "%s",
40 \t.sub_mod_rev = "%s",
41 \t.data = model,
42 \t.format = %s,
43 };
44
45 static void embed_register(void) __attribute__((_CONSTRUCTOR(2000)));
46 static void embed_register(void)
47 {
48 \tyang_module_embed(&embed);
49 }
50 '''
51
52 passchars = set(string.printable) - set('\\\'"%\r\n\t\x0b\x0c')
53 def escapech(char):
54 if char in passchars:
55 return char
56 if char == '\n':
57 return '\\n'
58 if char == '\t':
59 return '\\t'
60 if char in '"\\\'':
61 return '\\' + char
62 return '\\x%02x' % (ord(char))
63 def escape(line):
64 return ''.join([escapech(i) for i in line])
65
66 with open(inname, 'r') as fd:
67 data = fd.read()
68
69 sub_name = ""
70 rev = ""
71 sub_rev = ""
72
73 # XML support isn't actively used currently, but it's here in case the need
74 # arises. It does avoid the regex'ing.
75 if '<?xml' in data:
76 from xml.etree import ElementTree
77 xml = ElementTree.fromstring(data)
78 name = xml.get('name')
79 rev = xml.find('{urn:ietf:params:xml:ns:yang:yin:1}revision').get('date')
80 fmt = 'LYS_YIN'
81 else:
82 search_name = re_name.search(data)
83 if search_name :
84 name = search_name.group(1)
85 rev = re_rev.search(data).group(1)
86 else :
87 search_name = re_subname.search(data)
88 sub_name = search_name.group(1)
89 name = re_mainname.search(data).group(1)
90 sub_rev = re_rev.search(data).group(1)
91 fmt = 'LYS_YANG'
92
93 if name is None or rev is None:
94 raise ValueError('cannot determine YANG module name and revision')
95
96 lines = [escape(row) for row in data.split('\n')]
97 text = '\\n"\n\t"'.join(lines)
98
99 with open(outname, 'w') as fd:
100 fd.write(template % (text, escape(name), escape(rev), escape(sub_name), escape(sub_rev), fmt))