aboutsummaryrefslogtreecommitdiff
path: root/tools/Internals/headers/output.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/Internals/headers/output.py')
-rw-r--r--tools/Internals/headers/output.py70
1 files changed, 70 insertions, 0 deletions
diff --git a/tools/Internals/headers/output.py b/tools/Internals/headers/output.py
new file mode 100644
index 0000000..e75833a
--- /dev/null
+++ b/tools/Internals/headers/output.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python3
+""" Output a header. """
+
+import sys as _sys
+import string as _string
+
+from .parse import *
+
+__all__ = ["output_header"]
+
+def __validmacroname(name):
+ return all(c in _string.ascii_letters + '_' for c in name)
+
+def __output_recursive(content, out=_sys.stdout, sep='\n'):
+ """ Output the content in a recursive manner. """
+
+ for ins in content:
+ if type(ins) == CppRaw:
+ nxt = sep.join(ins.content)
+ elif type(ins) == CppDefine:
+ nxt = "#define {}".format(ins.name)
+ if ins.args != None:
+ nxt += "({})".format(', '.join(ins.args))
+ nxt += " {}".format((' \\' + sep).join(ins.expr))
+ elif type(ins) == CppUndef:
+ nxt = "#undef {}".format(ins.name)
+ elif type(ins) == CppInclude:
+ nxt = ins.name
+ if ins.typ == "local":
+ nxt = '"{}"'.format(nxt)
+ elif ins.typ == "path":
+ nxt = '<{}>'.format(nxt)
+ nxt = "#include {}".format(nxt)
+ elif type(ins) == CppError:
+ nxt = '#error "{}"'.format(nxt)
+ elif type(ins) == CppIf:
+ expr = (' \\' + sep).join(ins.conds[0][0])
+ if expr[0:8] == 'defined(' and expr[-1] == ')' \
+ and __validmacroname(expr[8:-1].strip()):
+ print("#ifdef {}".format(expr[8:-1].strip()),
+ end=sep, file=out)
+ elif expr[0:9] == '!defined(' and expr[-1] == ')' \
+ and __validmacroname(expr[9:-1].strip()):
+ print("#ifndef {}".format(expr[9:-1].strip()),
+ end=sep, file=out)
+ else:
+ print("#if {}".format(expr), end=sep, file=out)
+
+ __output_recursive(ins.conds[0][1], out=out, sep=sep)
+
+ for cond, sub in ins.conds[1:]:
+ print('#elif {}'.format(cond[0][0]), *cond[0][1:],
+ sep=sep, end=sep, file=out)
+ __output_recursive(cond[1], out=out, sep=sep)
+
+ nxt = '#endif'
+ else:
+ # We really shouldn't be here.
+ # But in case, here is a way to identify the problem.
+ nxt = '#<{}>'.format(type(ins).__name__)
+
+ print(nxt, end=sep, file=out)
+
+def output_header(topc, content, out=_sys.stdout, sep='\n'):
+ """ Output a header from its parsed form. """
+
+ print(sep.join(topc.split('\n')), end='', file=out)
+ __output_recursive(content, out=out, sep=sep)
+
+# End of file.