-
Notifications
You must be signed in to change notification settings - Fork 8
/
rbgen.in
179 lines (167 loc) · 6.4 KB
/
rbgen.in
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#!@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: