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