]> git.proxmox.com Git - mirror_frr.git/blob - yang/embedmodel.py
doc: Add `show ipv6 rpf X:X::X:X` command to docs
[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 try:
16 os.makedirs(outdir)
17 except FileExistsError:
18 pass
19
20 # these are regexes to avoid a compile-time/host dependency on yang-tools
21 # or python-yang. Cross-compiling FRR is already somewhat involved, no need
22 # to make it even harder.
23
24 re_name = re.compile(r"\bmodule\s+([^\s]+)\s+\{")
25 re_subname = re.compile(r"\bsubmodule\s+([^\s]+)\s+\{")
26 re_mainname = re.compile(r"\bbelongs-to\s+([^\s]+)\s+\{")
27 re_rev = re.compile(r"\brevision\s+([\d-]+)\s+\{")
28
29
30 template = """/* autogenerated by embedmodel.py. DO NOT EDIT */
31
32 #include <zebra.h>
33 #include "yang.h"
34
35 static const char model[] =
36 \t"%s";
37
38 static struct yang_module_embed embed = {
39 \t.mod_name = "%s",
40 \t.mod_rev = "%s",
41 \t.sub_mod_name = "%s",
42 \t.sub_mod_rev = "%s",
43 \t.data = model,
44 \t.format = %s,
45 };
46
47 static void embed_register(void) __attribute__((_CONSTRUCTOR(2000)));
48 static void embed_register(void)
49 {
50 \tyang_module_embed(&embed);
51 }
52 """
53
54 passchars = set(string.printable) - set("\\'\"%\r\n\t\x0b\x0c")
55
56
57 def escapech(char):
58 if char in passchars:
59 return char
60 if char == "\n":
61 return "\\n"
62 if char == "\t":
63 return "\\t"
64 if char in "\"\\'":
65 return "\\" + char
66 return "\\x%02x" % (ord(char))
67
68
69 def escape(line):
70 return "".join([escapech(i) for i in line])
71
72
73 with open(inname, "r") as fd:
74 data = fd.read()
75
76 sub_name = ""
77 rev = ""
78 sub_rev = ""
79
80 # XML support isn't actively used currently, but it's here in case the need
81 # arises. It does avoid the regex'ing.
82 if "<?xml" in data:
83 from xml.etree import ElementTree
84
85 xml = ElementTree.fromstring(data)
86 name = xml.get("name")
87 rev = xml.find("{urn:ietf:params:xml:ns:yang:yin:1}revision").get("date")
88 fmt = "LYS_YIN"
89 else:
90 search_name = re_name.search(data)
91 if search_name:
92 name = search_name.group(1)
93 rev = re_rev.search(data).group(1)
94 else:
95 search_name = re_subname.search(data)
96 sub_name = search_name.group(1)
97 name = re_mainname.search(data).group(1)
98 sub_rev = re_rev.search(data).group(1)
99 fmt = "LYS_IN_YANG"
100
101 if name is None or rev is None:
102 raise ValueError("cannot determine YANG module name and revision")
103
104 lines = [escape(row) for row in data.split("\n")]
105 text = '\\n"\n\t"'.join(lines)
106
107 with open(outname, "w") as fd:
108 fd.write(
109 template
110 % (text, escape(name), escape(rev), escape(sub_name), escape(sub_rev), fmt)
111 )