#!/usr/bin/python # # extract_conversion_functions.py # # Extract pytoguile and guiletopy conversion functions, and create # calls to bind_g2p_function/bind_p2g_function as needed. # # This script is an auxiliary script for building PyGuile. # ######################################################################## # # Copyright (C) 2008 Omer Zak. # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this library, in a file named COPYING; if not, write to the # Free Software Foundation, Inc., 59 Temple Place, Suite 330, # Boston, MA 02111-1307 USA # # For licensing issues, contact . # ######################################################################## # $Id: $ ######################################################################## import re import sys import exceptions import time from optparse import OptionParser ######################################################################## class error(exceptions.Exception): def __init__(self,*args): self.args = args ######################################################################## # Common code ######################################################################## def extract_fnames(inptext=None): """Extract g2p and p2g function names from the input text. The return value is 2-tuple of (g2p_funcs,p2g_funcs), each element being list of the names of the corresponding functions. """ g2p_pattern = re.compile(r'PyObject\s+\*\s+(g\w+)\s*\(\s*SCM\s+[^)]+\)',re.S) p2g_pattern = re.compile(r'SCM\s+(p\w+)\s*\(\s*PyObject\s*\*\s*[^)]+\)',re.S) g2p_funcs = g2p_pattern.findall(inptext) p2g_funcs = p2g_pattern.findall(inptext) return((g2p_funcs,p2g_funcs)) ######################################################################## def extract_converters(stdin=sys.stdin,stdout=sys.stdout,stderr=sys.stderr): """Extract function declarations for *.inc files, as needed by the PyGuile project. """ (g2p_funcs,p2g_funcs) = extract_fnames(inptext=stdin.read()) tstamp = time.strftime("%Y%b%d-%H:%M:%S") if (len(g2p_funcs) > 0): stdout.write("// Registration of guiletopy functions\n") stdout.write("// Autogenerated at date %s\n" % tstamp) stdout.write("void\nbind_g2p_functions(void)\n{\n") for g2p_func in g2p_funcs: if (g2p_func == "guile2python"): stdout.write(""" guile2python_smob = scm_permanent_object(bind_g2p_function(%(fname)s,"%(fname)s"));\n""" % { "fname" : g2p_func}) stdout.write(""" guile2python_template_default = scm_permanent_object(scm_list_1(guile2python_smob));\n""") stdout.write(""" guile2python_pair_template_default = scm_permanent_object(scm_cons(guile2python_template_default,guile2python_template_default));\n""") stdout.write(""" guileassoc2pythondict_default = scm_permanent_object(scm_c_make_hash_table (2));\n""") stdout.write(""" g2p_alist_template_default = scm_permanent_object(scm_list_1(scm_cons(guile2python_smob,guile2python_smob)));\n""") else: stdout.write(""" bind_g2p_function(%(fname)s,"%(fname)s");\n""" % { "fname" : g2p_func}) stdout.write("}\n") stdout.write("// End of guiletopy functions\n") if (len(p2g_funcs) > 0): stdout.write("// Registration of pytoguile functions\n") stdout.write("// Autogenerated at date %s\n" % tstamp) stdout.write("void\nbind_p2g_functions(void)\n{\n") for p2g_func in p2g_funcs: if (p2g_func == "python2guile"): stdout.write(""" python2guile_smob = scm_permanent_object(bind_p2g_function(%(fname)s,"%(fname)s"));\n""" % { "fname" : p2g_func}) stdout.write(""" python2guile_dict_default = scm_permanent_object(scm_cons(python2guile_smob,python2guile_smob));\n""") else: stdout.write(""" bind_p2g_function(%(fname)s,"%(fname)s");\n""" % { "fname" : p2g_func}) stdout.write("}\n") stdout.write("// End of pytoguile functions\n") ######################################################################## def extract_exports(template=None,stdin=sys.stdin,stdout=sys.stdout,stderr=sys.stderr): """Prepare list of exports for pyguile.scm. """ (g2p_funcs,p2g_funcs) = extract_fnames(inptext=stdin.read()) tstamp = time.strftime("%Y%b%d-%H:%M:%S") exports = "(export " + " ".join(g2p_funcs) + " " + " ".join(p2g_funcs) + ")\n" stdout.write(template % {"timestamp" : tstamp, "autogeneratedexports" : exports}) ######################################################################## # Main Program ######################################################################## def main(argv=None): """Main program of the script - used to test the actual script code. """ op = OptionParser() op.add_option("-i","--input",action="store", dest="input",default=None, help="Name of input file. Default is sys.stdin.") op.add_option("-o","--output",action="store", dest="output",default=None, help="Name of output file. Default is sys.stdout.") op.add_option("-e","--error",action="store", dest="error",default=None, help="Name of error output file. Default is sys.stderr.") op.add_option("--inc",action="store_true", dest="inc",default=False, help="Create *.inc file.") op.add_option("--scm",action="store", dest="scm",default=None, help="Create *.scm file. The argument is the corresponding .scm.in file to be used as template.") (options,args) = op.parse_args(argv[1:]) # Process input/output/error files' parameters. if (options.input == None): stdin = sys.stdin else: stdin = open(options.input) if (options.output == None): stdout = sys.stdout else: stdout = open(options.output,'w') if (options.error == None): stderr = sys.stderr else: stderr = open(options.error,'w') if (options.inc): extract_converters(stdin=stdin,stdout=stdout,stderr=stderr) elif (options.scm != None): scminfile = open(options.scm) scmintxt = scminfile.read() scminfile.close() extract_exports(template=scmintxt,stdin=stdin,stdout=stdout,stderr=stderr) return(0) ######################################################################## if (__name__ == '__main__'): sys.exit(main(sys.argv)) else: # I have been imported as a module. pass # End of extract_conversion_functions.py