diff options
Diffstat (limited to 'tools/Internals/headers/output.py')
-rw-r--r-- | tools/Internals/headers/output.py | 70 |
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. |