# HG changeset patch # User paulb # Date 1117288546 0 # Node ID ddddd136fcaad9b4f4f93022614cb6fbd4fc7143 # Parent a4ead372eaa2bd11867788950b6002f0a8209ebf [project @ 2005-05-28 13:55:44 by paulb] Moved libxml2macro.py into the tools directory. diff -r a4ead372eaa2 -r ddddd136fcaa README.txt --- a/README.txt Fri May 27 20:31:30 2005 +0000 +++ b/README.txt Sat May 28 13:55:46 2005 +0000 @@ -51,7 +51,7 @@ Then, run libxml2macro.py on the module like this (using tests/macrotest.py as an example): - libxml2macro.py tests/macrotest.py + tools/libxml2macro.py tests/macrotest.py This produces a compiled module that can be imported into Python; for example: diff -r a4ead372eaa2 -r ddddd136fcaa libxml2macro.py --- a/libxml2macro.py Fri May 27 20:31:30 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,256 +0,0 @@ -#!/usr/bin/env python - -import compiler -import marshal, imp, os, stat, struct - -# Originally from Analysis/Writers/Python. - -def write_module(module, source_filename, target_filename, syntax_check=1): - - """ - Write the given 'module', associated with the given 'source_filename', to a - file with the given 'target_filename'. The optional 'syntax_check' flag (set - by default) ensures that the module is syntactically correct. - """ - - if syntax_check: - compiler.syntax.check(module) - compiler.misc.set_filename(source_filename, module) - generator = compiler.pycodegen.ModuleCodeGenerator(module) - f = open(target_filename, "wb") - f.write(get_header(source_filename)) - marshal.dump(generator.getCode(), f) - f.close() - -def get_header(filename): - - "Taken from compiler.pycodegen. Prepare the compiled module header." - - MAGIC = imp.get_magic() - mtime = os.stat(filename)[stat.ST_MTIME] - mtime = struct.pack(' Node_attr(node, args) - # fn(node.attr) -> fn(Node_attr(node)) - - if isinstance(parent, compiler.ast.CallFunc): - - # If this node is not an argument, transform the call. - - if index is None: - parent.node = compiler.ast.Name("Node_%s" % node.attrname) - parent.args.insert(0, node.expr) - - else: - replacement = compiler.ast.CallFunc( - compiler.ast.Name("Node_%s" % node.attrname), - [node.expr] - ) - parent.args[index] = replacement - - # Replace plain Getattr nodes: - # node.attr -> Node_attr(node) - # NOTE: Nasty but necessary rewiring of the parent node required. - - else: - replacement = compiler.ast.CallFunc( - compiler.ast.Name("Node_%s" % node.attrname), - [node.expr] - ) - for key, value in parent.__dict__.items(): - # Detect lists. - if hasattr(value, "__len__") and node in value: - index = value.index(node) - value[index] = replacement - elif value is node: - parent.__dict__[key] = replacement - - # Propagate whether the kind of result might need transforming itself. - - return node.attrname - - else: - process_nodes(node, prefix) - return None - -def propagated_prefix(attrname): - - """ - Return whether the given 'attrname' used in a transformation should be - considered significant at the parent level. - """ - - return attrname in ("ownerElement", "ownerDocument") - -def getattr_has_prefix(node, prefix): - - """ - Determine whether the given Getattr 'node' employs the special 'prefix' in a - number of ways. - """ - - # Check the expression as a simple name: - # node.attr - - if isinstance(node.expr, compiler.ast.Name) and node.expr.name.startswith(prefix): - return 1 - - # Check the attribute name of child expressions: - # (obj.node).attr - - elif isinstance(node.expr, compiler.ast.Getattr) and node.expr.attrname.startswith(prefix): - return 1 - else: - return 0 - -def include_import(module): - - """ - Include an import statement in 'module' to make the macro library available. - """ - - module.node.nodes.insert(0, compiler.ast.From("libxml2dom.macrolib", [("*", None)])) - -def process_file(filename): - - """ - Process the module given by the specified 'filename'. The optional special - 'prefix' marks those variables to be processed. - """ - - # Open the module as an AST. - - module = compiler.parseFile(filename) - - # Find references to special variables. - - process_nodes(module) - - # Add necessary imports. - - include_import(module) - - # Write the module. - - write_module(module, filename, os.path.splitext(filename)[0] + ".pyc") - return module - -if __name__ == "__main__": - import sys - if len(sys.argv) < 2: - print "libxml2macro.py " - sys.exit(1) - process_file(sys.argv[1]) - -# vim: tabstop=4 expandtab shiftwidth=4 diff -r a4ead372eaa2 -r ddddd136fcaa tools/libxml2macro.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxml2macro.py Sat May 28 13:55:46 2005 +0000 @@ -0,0 +1,256 @@ +#!/usr/bin/env python + +import compiler +import marshal, imp, os, stat, struct + +# Originally from Analysis/Writers/Python. + +def write_module(module, source_filename, target_filename, syntax_check=1): + + """ + Write the given 'module', associated with the given 'source_filename', to a + file with the given 'target_filename'. The optional 'syntax_check' flag (set + by default) ensures that the module is syntactically correct. + """ + + if syntax_check: + compiler.syntax.check(module) + compiler.misc.set_filename(source_filename, module) + generator = compiler.pycodegen.ModuleCodeGenerator(module) + f = open(target_filename, "wb") + f.write(get_header(source_filename)) + marshal.dump(generator.getCode(), f) + f.close() + +def get_header(filename): + + "Taken from compiler.pycodegen. Prepare the compiled module header." + + MAGIC = imp.get_magic() + mtime = os.stat(filename)[stat.ST_MTIME] + mtime = struct.pack(' Node_attr(node, args) + # fn(node.attr) -> fn(Node_attr(node)) + + if isinstance(parent, compiler.ast.CallFunc): + + # If this node is not an argument, transform the call. + + if index is None: + parent.node = compiler.ast.Name("Node_%s" % node.attrname) + parent.args.insert(0, node.expr) + + else: + replacement = compiler.ast.CallFunc( + compiler.ast.Name("Node_%s" % node.attrname), + [node.expr] + ) + parent.args[index] = replacement + + # Replace plain Getattr nodes: + # node.attr -> Node_attr(node) + # NOTE: Nasty but necessary rewiring of the parent node required. + + else: + replacement = compiler.ast.CallFunc( + compiler.ast.Name("Node_%s" % node.attrname), + [node.expr] + ) + for key, value in parent.__dict__.items(): + # Detect lists. + if hasattr(value, "__len__") and node in value: + index = value.index(node) + value[index] = replacement + elif value is node: + parent.__dict__[key] = replacement + + # Propagate whether the kind of result might need transforming itself. + + return node.attrname + + else: + process_nodes(node, prefix) + return None + +def propagated_prefix(attrname): + + """ + Return whether the given 'attrname' used in a transformation should be + considered significant at the parent level. + """ + + return attrname in ("ownerElement", "ownerDocument") + +def getattr_has_prefix(node, prefix): + + """ + Determine whether the given Getattr 'node' employs the special 'prefix' in a + number of ways. + """ + + # Check the expression as a simple name: + # node.attr + + if isinstance(node.expr, compiler.ast.Name) and node.expr.name.startswith(prefix): + return 1 + + # Check the attribute name of child expressions: + # (obj.node).attr + + elif isinstance(node.expr, compiler.ast.Getattr) and node.expr.attrname.startswith(prefix): + return 1 + else: + return 0 + +def include_import(module): + + """ + Include an import statement in 'module' to make the macro library available. + """ + + module.node.nodes.insert(0, compiler.ast.From("libxml2dom.macrolib", [("*", None)])) + +def process_file(filename): + + """ + Process the module given by the specified 'filename'. The optional special + 'prefix' marks those variables to be processed. + """ + + # Open the module as an AST. + + module = compiler.parseFile(filename) + + # Find references to special variables. + + process_nodes(module) + + # Add necessary imports. + + include_import(module) + + # Write the module. + + write_module(module, filename, os.path.splitext(filename)[0] + ".pyc") + return module + +if __name__ == "__main__": + import sys + if len(sys.argv) < 2: + print "libxml2macro.py " + sys.exit(1) + process_file(sys.argv[1]) + +# vim: tabstop=4 expandtab shiftwidth=4