blob: ae7e991c1e95ef819c71eafa1ce880c7da6865ef [file] [log] [blame]
#!@PATH_PYTHON_PROG@
#
# $Id: rbgen.in,v 1.3 2003/10/24 01:31:21 damo Exp $
#
# rbgen -- generate a redblack customized search library
#
# $Log: rbgen.in,v $
# Revision 1.3 2003/10/24 01:31:21 damo
# Patches from Eric Raymond: %prefix is implemented. Various other small
# changes avoid stepping on global namespaces and improve the documentation.
#
# Revision 1.2 2003/10/23 04:18:47 damo
# Fixed up the rbgen stuff ready for the 1.3 release
#
# Revision 1.1 2002/08/26 03:11:40 damo
# Fixed up a bunch of compiler warnings when compiling example4
#
# Tidies up the Makefile.am & Specfile.
#
# Renamed redblack to rbgen
#
#
import sys, string, os
fpin = sys.stdin
lineno = 0
def error(msg, warning=0):
sys.stderr.write('"%s", line %d: %s\n\n' % (fpin.name, lineno, msg))
if not warning:
raise SyntaxError
def startswith(line, prefix):
return line[:len(prefix)] == prefix
def include(file, fpout):
try:
fp = open(file)
fpout.write(fp.read())
fp.close()
except IOError:
error("missing skeleton file %s!" % file)
def redblack(filename, lines):
rb_type = rb_cmp = rb_alloc = rb_free = rb_access = None
rb_prefix = "rb"
sbrk = static = 0
global lineno
ext = string.find(filename, ".rb")
if ext == -1:
sys.stderr.write("redblack: extension on %s doesn't look right.\n" % filename)
raise SyntaxError
else:
outfile = filename[:ext] + ".c"
fpin = open(filename, "r")
fpout = open(outfile, "w")
if lines:
fpout.write('#line 1 "%s"\n' % filename)
while 1:
line = fpin.readline()
lineno = lineno + 1
if not line:
break
if startswith(line, "%%rbgen"):
fpout.write("/* rbgen generated code begins here */\n")
fpout.write("/* rbgen: $Id: rbgen.in,v 1.3 2003/10/24 01:31:21 damo Exp $ */\n")
while 1:
line = fpin.readline()
lineno = lineno + 1
if not line:
break
comment = string.find(line, "//")
if comment > -1:
line = line[:comment] + "\n"
if line[0] == "\n":
continue
elif startswith(line, "%%rbgen"):
fpout.write("#define RB_CUSTOMIZE\n")
if not rb_type:
error("%type directive is required.")
else:
fpout.write("#define %sdata_t %s\n" % (rb_prefix, rb_type))
if not rb_cmp:
error("%cmp directive is required.")
else:
fpout.write("#define RB_CMP(s, t) %s(s, t)\n" % rb_cmp)
if rb_alloc:
fpout.write("#define RB_ALLOC %s\n" % rb_alloc)
if rb_free:
fpout.write("#define RB_FREE %s\n"% rb_free)
if rb_prefix:
fpout.write("#define RB_ENTRY(name) %s##name\n" % rb_prefix)
if rb_access is None or rb_access == "pointer":
fpout.write("#undef RB_INLINE\n")
elif rb_access == "inline":
fpout.write("#define RB_INLINE\n")
for func in rb_omit:
fpout.write("#define no_%s\n" % func)
if static:
fpout.write("#define RB_STATIC static\n")
else:
fpout.write("#define RB_STATIC\n")
if sbrk:
fpout.write("#define RB_USE_SBRK\n")
if lines:
fpout.write('#line 1 "%s"\n' % outfile)
include(h_skel, fpout)
include(c_skel, fpout)
fpout.write("/* rbgen generated code ends here */\n")
if lines:
fpout.write('#line %d "%s"\n' % (lineno, filename))
fpout.write(fpin.read())
return
elif line[0] == "%":
tokens = string.split(line)
if tokens[0] in("%type","%cmp","%alloc","%free","%prefix"):
exec "rb_" + tokens[0][1:] + " = '" + tokens[1] + "'"
elif tokens[0] == "%access":
if tokens[1] in ("inline", "pointer"):
rb_access = tokens[1]
else:
error("unknown access type")
elif tokens[0] == "%omit":
omittable = ("destroy", "search", "find",
"delete", "walk", "readlist",
"lookup", "destroy", "delete",
"readlist")
rb_omit = tokens[1:]
for func in rb_omit:
if func not in omittable:
error("%s cannot be omitted" % func)
elif tokens[0] == "%sbrk":
sbrk = 1
elif tokens[0] == "%static":
static = 1
else:
error("unknown directive %s" % string.split(line)[0])
else:
error("garbage on line beginning %s." % line[0])
else:
sys.stderr.write("rbgen: no end on directives section.\n")
else:
fpout.write(line)
sys.stderr.write("rbgen: no directives found.\n")
raise SyntaxError
if __name__ == "__main__":
import getopt
(options, arguments) = getopt.getopt(sys.argv[1:], "lS:")
lines = 1;
skelpath = [".", "@prefix@/share/@PACKAGE@" "/share/redblack"]
for (switch, val) in options:
if (switch == '-l'):
lines = 0
elif (switch == '-S'):
skeldir = val
for skeldir in skelpath:
h_skel = os.path.join(skeldir, "redblack.h")
c_skel = os.path.join(skeldir, "redblack.c")
if os.path.exists(h_skel) and os.path.exists(c_skel):
break
else:
sys.stderr.write("rbgen: can't find skeleton file\n")
for file in arguments:
try:
redblack(file, lines)
raise SystemExit, 0
except SyntaxError:
raise SystemExit, 1
# The following sets edit modes for GNU EMACS
# Local Variables:
# mode:python
# End: