.maven.plugins.autogen.7.source-code.autogen.py Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of autogen Show documentation
Show all versions of autogen Show documentation
A simple template expander inspired by Scheme.
The newest version!
class AutogenException(Exception):
def __init__(self, msg):
Exception.__init__(self, msg)
def doFor(content, defines, output, globals, locals):
# Do a for loop over a list in the definitions. The mess here is to
# support a separator character.
params = eval(content[0].replace('\r\n','\n'), globals, locals)
if isinstance(params, tuple):
if len(params) != 2:
raise AutogenException("for: wrong number of arguments (2 expected).");
items = params[0]
sep = params[1]
else:
items = params
sep = ''
if not isinstance(items, list):
items = [items]
for i in xrange(len(items)):
autogen(content[1:], items[i], output, globals, locals)
if i < len(items)-1:
output.write(sep)
def doIf(entry, defines, output, globals, locals):
# If blocks have a condition, and hide the 'elif' and 'else' clauses
# in a third element of the tuple.
content = entry[1]
test = eval(content[0].replace('\r\n','\n'), globals, locals)
if test:
autogen(content[1:], defines, output, globals, locals)
elif len(entry[2]) != 0:
entry = entry[2][0]
if entry[0] == 'else':
autogen(entry[1], defines, output, globals, locals)
elif entry[0] == 'elif':
doIf(entry, defines, output, globals, locals)
def autogen(template, defines, output, globals=None, locals=None):
if globals is None:
globals = {}
# Copy local scope so we can modify things in this template scope.
if locals is None:
locals = {}
else:
locals = dict(locals)
# If this part of the definitions is a dictionary add the keys to the
# local scope, otherwise, set the variable 'value' to the current
# definitions.
if isinstance(defines, dict):
locals.update(defines)
else:
locals['value'] = defines
#print "template: %r" % template
#print "globals: %r" % globals.keys()
#print "locals: %r" % locals.keys()
# Go through this level of the template.
for entry in template:
if isinstance(entry, unicode) or isinstance(entry, str):
output.write(entry)
else:
type, content = entry[0:2]
if type == 'define':
exec content[0].replace('\r\n','\n') in globals, locals
elif type == 'eval':
try:
output.write(unicode(eval(content[0].replace('\r\n','\n'),
globals, locals)))
except KeyError, e:
raise AutogenException('In "%s", threw KeyError: %s.' % (content[0], e))
elif type == 'for':
doFor(content, defines, output, globals, locals)
elif type == 'if':
doIf(entry, defines, output, globals, locals)
if __name__ == '__main__':
import getopt, sys, codecs, time, os
import data
import template
def usage():
print >> sys.stderr, """Usage:
%s [-t template] [-o output] defines
""" % sys.argv[0]
sys.exit(1)
# Parse command line arguments, this is uglier than it has to be.
try:
opts, args = getopt.getopt(sys.argv[1:], "t:o:D:", ["template=", "output="])
except getopt.GetoptError:
usage()
templateFile = None
outputFile = None
defineFile = None
globals = {}
for o, a in opts:
if o in ('-t', "--template"):
templateFile = a
elif o in ('-o', "--output"):
outputFile = a
elif o == '-D':
i = a.find('=')
globals[a[0:i]] = a[i+1:]
if len(args) > 1:
print >> sys.stderr, "Too many options!"
usage()
if len(args) == 1:
defineFile = args[0]
defines = open(defineFile)
else:
defineFile = 'stdin'
defines = sys.stdin
if templateFile is None:
print >> sys.stderr, "No template given!"
usage()
tmpl = codecs.open(templateFile, "r", "utf-8")
# Read in definition file.
try:
dataParser = data.Parser()
inputData = dataParser.parse(defines)
except data.ParserException, e:
print str(e)
sys.exit(1)
# Read in template file.
try:
dataTemplate = tmpl.read()
dataTemplate = template.parse(dataTemplate)
except template.ParserException, e:
print str(e)
sys.exit(1)
# Generate the "do not edit this file" message.
def dne(prefix=''):
eol = ''
if 'COMSPEC' in os.environ:
eol = '\r\n'
else:
eol = '\n'
s = eol + prefix + " DO NOT EDIT THIS FILE " + outputFile.replace("\\", "/") + eol
s += eol + prefix + " It has been AutoGen-ed " + time.ctime() + eol
s += eol + prefix + " and the template file " + templateFile.replace("\\", "/") + eol
return s
globals['dne'] = dne
if outputFile is None:
outputFile = 'stdout'
output = sys.stdout
else:
output = codecs.open(outputFile, "w", "utf-8")
# Go!
autogen(dataTemplate, inputData, output, globals)