#!/usr/bin/python3 # # YANG module to C wrapper # written 2018 by David Lamparter, placed in Public Domain. import sys import os import string import re inname = sys.argv[1] outname = sys.argv[2] outdir = os.path.dirname(os.path.abspath(outname)) if not os.path.isdir(outdir): os.makedirs(outdir) # these are regexes to avoid a compile-time/host dependency on yang-tools # or python-yang. Cross-compiling FRR is already somewhat involved, no need # to make it even harder. re_name = re.compile(r"\bmodule\s+([^\s]+)\s+\{") re_subname = re.compile(r"\bsubmodule\s+([^\s]+)\s+\{") re_mainname = re.compile(r"\bbelongs-to\s+([^\s]+)\s+\{") re_rev = re.compile(r"\brevision\s+([\d-]+)\s+\{") template = """/* autogenerated by embedmodel.py. DO NOT EDIT */ #include #include "yang.h" static const char model[] = \t"%s"; static struct yang_module_embed embed = { \t.mod_name = "%s", \t.mod_rev = "%s", \t.sub_mod_name = "%s", \t.sub_mod_rev = "%s", \t.data = model, \t.format = %s, }; static void embed_register(void) __attribute__((_CONSTRUCTOR(2000))); static void embed_register(void) { \tyang_module_embed(&embed); } """ passchars = set(string.printable) - set("\\'\"%\r\n\t\x0b\x0c") def escapech(char): if char in passchars: return char if char == "\n": return "\\n" if char == "\t": return "\\t" if char in "\"\\'": return "\\" + char return "\\x%02x" % (ord(char)) def escape(line): return "".join([escapech(i) for i in line]) with open(inname, "r") as fd: data = fd.read() sub_name = "" rev = "" sub_rev = "" # XML support isn't actively used currently, but it's here in case the need # arises. It does avoid the regex'ing. if "