event_rpcgen.py revision 1.1.1.1.8.2 1 1.1.1.1.8.2 tls #!/usr/bin/env python2
2 1.1.1.1.8.2 tls #
3 1.1.1.1.8.2 tls # Copyright (c) 2005-2007 Niels Provos <provos (at] citi.umich.edu>
4 1.1.1.1.8.2 tls # Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
5 1.1.1.1.8.2 tls # All rights reserved.
6 1.1.1.1.8.2 tls #
7 1.1.1.1.8.2 tls # Generates marshaling code based on libevent.
8 1.1.1.1.8.2 tls
9 1.1.1.1.8.2 tls # TODO:
10 1.1.1.1.8.2 tls # 1) use optparse to allow the strategy shell to parse options, and
11 1.1.1.1.8.2 tls # to allow the instantiated factory (for the specific output language)
12 1.1.1.1.8.2 tls # to parse remaining options
13 1.1.1.1.8.2 tls # 2) move the globals into a class that manages execution (including the
14 1.1.1.1.8.2 tls # progress outputs that space stderr at the moment)
15 1.1.1.1.8.2 tls # 3) emit other languages
16 1.1.1.1.8.2 tls
17 1.1.1.1.8.2 tls import sys
18 1.1.1.1.8.2 tls import re
19 1.1.1.1.8.2 tls
20 1.1.1.1.8.2 tls _NAME = "event_rpcgen.py"
21 1.1.1.1.8.2 tls _VERSION = "0.1"
22 1.1.1.1.8.2 tls
23 1.1.1.1.8.2 tls # Globals
24 1.1.1.1.8.2 tls line_count = 0
25 1.1.1.1.8.2 tls
26 1.1.1.1.8.2 tls white = re.compile(r'\s+')
27 1.1.1.1.8.2 tls cppcomment = re.compile(r'\/\/.*$')
28 1.1.1.1.8.2 tls nonident = re.compile(r'[^a-zA-Z0-9_]')
29 1.1.1.1.8.2 tls structref = re.compile(r'^struct\[([a-zA-Z_][a-zA-Z0-9_]*)\]$')
30 1.1.1.1.8.2 tls structdef = re.compile(r'^struct +[a-zA-Z_][a-zA-Z0-9_]* *{$')
31 1.1.1.1.8.2 tls
32 1.1.1.1.8.2 tls headerdirect = []
33 1.1.1.1.8.2 tls cppdirect = []
34 1.1.1.1.8.2 tls
35 1.1.1.1.8.2 tls QUIETLY = 0
36 1.1.1.1.8.2 tls
37 1.1.1.1.8.2 tls def declare(s):
38 1.1.1.1.8.2 tls if not QUIETLY:
39 1.1.1.1.8.2 tls print s
40 1.1.1.1.8.2 tls
41 1.1.1.1.8.2 tls def TranslateList(mylist, mydict):
42 1.1.1.1.8.2 tls return map(lambda x: x % mydict, mylist)
43 1.1.1.1.8.2 tls
44 1.1.1.1.8.2 tls # Exception class for parse errors
45 1.1.1.1.8.2 tls class RpcGenError(Exception):
46 1.1.1.1.8.2 tls def __init__(self, why):
47 1.1.1.1.8.2 tls self.why = why
48 1.1.1.1.8.2 tls def __str__(self):
49 1.1.1.1.8.2 tls return str(self.why)
50 1.1.1.1.8.2 tls
51 1.1.1.1.8.2 tls # Holds everything that makes a struct
52 1.1.1.1.8.2 tls class Struct:
53 1.1.1.1.8.2 tls def __init__(self, name):
54 1.1.1.1.8.2 tls self._name = name
55 1.1.1.1.8.2 tls self._entries = []
56 1.1.1.1.8.2 tls self._tags = {}
57 1.1.1.1.8.2 tls declare(' Created struct: %s' % name)
58 1.1.1.1.8.2 tls
59 1.1.1.1.8.2 tls def AddEntry(self, entry):
60 1.1.1.1.8.2 tls if self._tags.has_key(entry.Tag()):
61 1.1.1.1.8.2 tls raise RpcGenError(
62 1.1.1.1.8.2 tls 'Entry "%s" duplicates tag number %d from "%s" '
63 1.1.1.1.8.2 tls 'around line %d' % (entry.Name(), entry.Tag(),
64 1.1.1.1.8.2 tls self._tags[entry.Tag()], line_count))
65 1.1.1.1.8.2 tls self._entries.append(entry)
66 1.1.1.1.8.2 tls self._tags[entry.Tag()] = entry.Name()
67 1.1.1.1.8.2 tls declare(' Added entry: %s' % entry.Name())
68 1.1.1.1.8.2 tls
69 1.1.1.1.8.2 tls def Name(self):
70 1.1.1.1.8.2 tls return self._name
71 1.1.1.1.8.2 tls
72 1.1.1.1.8.2 tls def EntryTagName(self, entry):
73 1.1.1.1.8.2 tls """Creates the name inside an enumeration for distinguishing data
74 1.1.1.1.8.2 tls types."""
75 1.1.1.1.8.2 tls name = "%s_%s" % (self._name, entry.Name())
76 1.1.1.1.8.2 tls return name.upper()
77 1.1.1.1.8.2 tls
78 1.1.1.1.8.2 tls def PrintIndented(self, file, ident, code):
79 1.1.1.1.8.2 tls """Takes an array, add indentation to each entry and prints it."""
80 1.1.1.1.8.2 tls for entry in code:
81 1.1.1.1.8.2 tls print >>file, '%s%s' % (ident, entry)
82 1.1.1.1.8.2 tls
83 1.1.1.1.8.2 tls class StructCCode(Struct):
84 1.1.1.1.8.2 tls """ Knows how to generate C code for a struct """
85 1.1.1.1.8.2 tls
86 1.1.1.1.8.2 tls def __init__(self, name):
87 1.1.1.1.8.2 tls Struct.__init__(self, name)
88 1.1.1.1.8.2 tls
89 1.1.1.1.8.2 tls def PrintTags(self, file):
90 1.1.1.1.8.2 tls """Prints the tag definitions for a structure."""
91 1.1.1.1.8.2 tls print >>file, '/* Tag definition for %s */' % self._name
92 1.1.1.1.8.2 tls print >>file, 'enum %s_ {' % self._name.lower()
93 1.1.1.1.8.2 tls for entry in self._entries:
94 1.1.1.1.8.2 tls print >>file, ' %s=%d,' % (self.EntryTagName(entry),
95 1.1.1.1.8.2 tls entry.Tag())
96 1.1.1.1.8.2 tls print >>file, ' %s_MAX_TAGS' % (self._name.upper())
97 1.1.1.1.8.2 tls print >>file, '};\n'
98 1.1.1.1.8.2 tls
99 1.1.1.1.8.2 tls def PrintForwardDeclaration(self, file):
100 1.1.1.1.8.2 tls print >>file, 'struct %s;' % self._name
101 1.1.1.1.8.2 tls
102 1.1.1.1.8.2 tls def PrintDeclaration(self, file):
103 1.1.1.1.8.2 tls print >>file, '/* Structure declaration for %s */' % self._name
104 1.1.1.1.8.2 tls print >>file, 'struct %s_access_ {' % self._name
105 1.1.1.1.8.2 tls for entry in self._entries:
106 1.1.1.1.8.2 tls dcl = entry.AssignDeclaration('(*%s_assign)' % entry.Name())
107 1.1.1.1.8.2 tls dcl.extend(
108 1.1.1.1.8.2 tls entry.GetDeclaration('(*%s_get)' % entry.Name()))
109 1.1.1.1.8.2 tls if entry.Array():
110 1.1.1.1.8.2 tls dcl.extend(
111 1.1.1.1.8.2 tls entry.AddDeclaration('(*%s_add)' % entry.Name()))
112 1.1.1.1.8.2 tls self.PrintIndented(file, ' ', dcl)
113 1.1.1.1.8.2 tls print >>file, '};\n'
114 1.1.1.1.8.2 tls
115 1.1.1.1.8.2 tls print >>file, 'struct %s {' % self._name
116 1.1.1.1.8.2 tls print >>file, ' struct %s_access_ *base;\n' % self._name
117 1.1.1.1.8.2 tls for entry in self._entries:
118 1.1.1.1.8.2 tls dcl = entry.Declaration()
119 1.1.1.1.8.2 tls self.PrintIndented(file, ' ', dcl)
120 1.1.1.1.8.2 tls print >>file, ''
121 1.1.1.1.8.2 tls for entry in self._entries:
122 1.1.1.1.8.2 tls print >>file, ' ev_uint8_t %s_set;' % entry.Name()
123 1.1.1.1.8.2 tls print >>file, '};\n'
124 1.1.1.1.8.2 tls
125 1.1.1.1.8.2 tls print >>file, \
126 1.1.1.1.8.2 tls """struct %(name)s *%(name)s_new(void);
127 1.1.1.1.8.2 tls struct %(name)s *%(name)s_new_with_arg(void *);
128 1.1.1.1.8.2 tls void %(name)s_free(struct %(name)s *);
129 1.1.1.1.8.2 tls void %(name)s_clear(struct %(name)s *);
130 1.1.1.1.8.2 tls void %(name)s_marshal(struct evbuffer *, const struct %(name)s *);
131 1.1.1.1.8.2 tls int %(name)s_unmarshal(struct %(name)s *, struct evbuffer *);
132 1.1.1.1.8.2 tls int %(name)s_complete(struct %(name)s *);
133 1.1.1.1.8.2 tls void evtag_marshal_%(name)s(struct evbuffer *, ev_uint32_t,
134 1.1.1.1.8.2 tls const struct %(name)s *);
135 1.1.1.1.8.2 tls int evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t,
136 1.1.1.1.8.2 tls struct %(name)s *);""" % { 'name' : self._name }
137 1.1.1.1.8.2 tls
138 1.1.1.1.8.2 tls
139 1.1.1.1.8.2 tls # Write a setting function of every variable
140 1.1.1.1.8.2 tls for entry in self._entries:
141 1.1.1.1.8.2 tls self.PrintIndented(file, '', entry.AssignDeclaration(
142 1.1.1.1.8.2 tls entry.AssignFuncName()))
143 1.1.1.1.8.2 tls self.PrintIndented(file, '', entry.GetDeclaration(
144 1.1.1.1.8.2 tls entry.GetFuncName()))
145 1.1.1.1.8.2 tls if entry.Array():
146 1.1.1.1.8.2 tls self.PrintIndented(file, '', entry.AddDeclaration(
147 1.1.1.1.8.2 tls entry.AddFuncName()))
148 1.1.1.1.8.2 tls
149 1.1.1.1.8.2 tls print >>file, '/* --- %s done --- */\n' % self._name
150 1.1.1.1.8.2 tls
151 1.1.1.1.8.2 tls def PrintCode(self, file):
152 1.1.1.1.8.2 tls print >>file, ('/*\n'
153 1.1.1.1.8.2 tls ' * Implementation of %s\n'
154 1.1.1.1.8.2 tls ' */\n') % self._name
155 1.1.1.1.8.2 tls
156 1.1.1.1.8.2 tls print >>file, \
157 1.1.1.1.8.2 tls 'static struct %(name)s_access_ %(name)s_base__ = {' % \
158 1.1.1.1.8.2 tls { 'name' : self._name }
159 1.1.1.1.8.2 tls for entry in self._entries:
160 1.1.1.1.8.2 tls self.PrintIndented(file, ' ', entry.CodeBase())
161 1.1.1.1.8.2 tls print >>file, '};\n'
162 1.1.1.1.8.2 tls
163 1.1.1.1.8.2 tls # Creation
164 1.1.1.1.8.2 tls print >>file, (
165 1.1.1.1.8.2 tls 'struct %(name)s *\n'
166 1.1.1.1.8.2 tls '%(name)s_new(void)\n'
167 1.1.1.1.8.2 tls '{\n'
168 1.1.1.1.8.2 tls ' return %(name)s_new_with_arg(NULL);\n'
169 1.1.1.1.8.2 tls '}\n'
170 1.1.1.1.8.2 tls '\n'
171 1.1.1.1.8.2 tls 'struct %(name)s *\n'
172 1.1.1.1.8.2 tls '%(name)s_new_with_arg(void *unused)\n'
173 1.1.1.1.8.2 tls '{\n'
174 1.1.1.1.8.2 tls ' struct %(name)s *tmp;\n'
175 1.1.1.1.8.2 tls ' if ((tmp = malloc(sizeof(struct %(name)s))) == NULL) {\n'
176 1.1.1.1.8.2 tls ' event_warn("%%s: malloc", __func__);\n'
177 1.1.1.1.8.2 tls ' return (NULL);\n'
178 1.1.1.1.8.2 tls ' }\n'
179 1.1.1.1.8.2 tls ' tmp->base = &%(name)s_base__;\n') % { 'name' : self._name }
180 1.1.1.1.8.2 tls
181 1.1.1.1.8.2 tls for entry in self._entries:
182 1.1.1.1.8.2 tls self.PrintIndented(file, ' ', entry.CodeInitialize('tmp'))
183 1.1.1.1.8.2 tls print >>file, ' tmp->%s_set = 0;\n' % entry.Name()
184 1.1.1.1.8.2 tls
185 1.1.1.1.8.2 tls print >>file, (
186 1.1.1.1.8.2 tls ' return (tmp);\n'
187 1.1.1.1.8.2 tls '}\n')
188 1.1.1.1.8.2 tls
189 1.1.1.1.8.2 tls # Adding
190 1.1.1.1.8.2 tls for entry in self._entries:
191 1.1.1.1.8.2 tls if entry.Array():
192 1.1.1.1.8.2 tls self.PrintIndented(file, '', entry.CodeAdd())
193 1.1.1.1.8.2 tls print >>file, ''
194 1.1.1.1.8.2 tls
195 1.1.1.1.8.2 tls # Assigning
196 1.1.1.1.8.2 tls for entry in self._entries:
197 1.1.1.1.8.2 tls self.PrintIndented(file, '', entry.CodeAssign())
198 1.1.1.1.8.2 tls print >>file, ''
199 1.1.1.1.8.2 tls
200 1.1.1.1.8.2 tls # Getting
201 1.1.1.1.8.2 tls for entry in self._entries:
202 1.1.1.1.8.2 tls self.PrintIndented(file, '', entry.CodeGet())
203 1.1.1.1.8.2 tls print >>file, ''
204 1.1.1.1.8.2 tls
205 1.1.1.1.8.2 tls # Clearing
206 1.1.1.1.8.2 tls print >>file, ( 'void\n'
207 1.1.1.1.8.2 tls '%(name)s_clear(struct %(name)s *tmp)\n'
208 1.1.1.1.8.2 tls '{'
209 1.1.1.1.8.2 tls ) % { 'name' : self._name }
210 1.1.1.1.8.2 tls for entry in self._entries:
211 1.1.1.1.8.2 tls self.PrintIndented(file, ' ', entry.CodeClear('tmp'))
212 1.1.1.1.8.2 tls
213 1.1.1.1.8.2 tls print >>file, '}\n'
214 1.1.1.1.8.2 tls
215 1.1.1.1.8.2 tls # Freeing
216 1.1.1.1.8.2 tls print >>file, ( 'void\n'
217 1.1.1.1.8.2 tls '%(name)s_free(struct %(name)s *tmp)\n'
218 1.1.1.1.8.2 tls '{'
219 1.1.1.1.8.2 tls ) % { 'name' : self._name }
220 1.1.1.1.8.2 tls
221 1.1.1.1.8.2 tls for entry in self._entries:
222 1.1.1.1.8.2 tls self.PrintIndented(file, ' ', entry.CodeFree('tmp'))
223 1.1.1.1.8.2 tls
224 1.1.1.1.8.2 tls print >>file, (' free(tmp);\n'
225 1.1.1.1.8.2 tls '}\n')
226 1.1.1.1.8.2 tls
227 1.1.1.1.8.2 tls # Marshaling
228 1.1.1.1.8.2 tls print >>file, ('void\n'
229 1.1.1.1.8.2 tls '%(name)s_marshal(struct evbuffer *evbuf, '
230 1.1.1.1.8.2 tls 'const struct %(name)s *tmp)'
231 1.1.1.1.8.2 tls '{') % { 'name' : self._name }
232 1.1.1.1.8.2 tls for entry in self._entries:
233 1.1.1.1.8.2 tls indent = ' '
234 1.1.1.1.8.2 tls # Optional entries do not have to be set
235 1.1.1.1.8.2 tls if entry.Optional():
236 1.1.1.1.8.2 tls indent += ' '
237 1.1.1.1.8.2 tls print >>file, ' if (tmp->%s_set) {' % entry.Name()
238 1.1.1.1.8.2 tls self.PrintIndented(
239 1.1.1.1.8.2 tls file, indent,
240 1.1.1.1.8.2 tls entry.CodeMarshal('evbuf', self.EntryTagName(entry),
241 1.1.1.1.8.2 tls entry.GetVarName('tmp'),
242 1.1.1.1.8.2 tls entry.GetVarLen('tmp')))
243 1.1.1.1.8.2 tls if entry.Optional():
244 1.1.1.1.8.2 tls print >>file, ' }'
245 1.1.1.1.8.2 tls
246 1.1.1.1.8.2 tls print >>file, '}\n'
247 1.1.1.1.8.2 tls
248 1.1.1.1.8.2 tls # Unmarshaling
249 1.1.1.1.8.2 tls print >>file, ('int\n'
250 1.1.1.1.8.2 tls '%(name)s_unmarshal(struct %(name)s *tmp, '
251 1.1.1.1.8.2 tls ' struct evbuffer *evbuf)\n'
252 1.1.1.1.8.2 tls '{\n'
253 1.1.1.1.8.2 tls ' ev_uint32_t tag;\n'
254 1.1.1.1.8.2 tls ' while (evbuffer_get_length(evbuf) > 0) {\n'
255 1.1.1.1.8.2 tls ' if (evtag_peek(evbuf, &tag) == -1)\n'
256 1.1.1.1.8.2 tls ' return (-1);\n'
257 1.1.1.1.8.2 tls ' switch (tag) {\n'
258 1.1.1.1.8.2 tls ) % { 'name' : self._name }
259 1.1.1.1.8.2 tls for entry in self._entries:
260 1.1.1.1.8.2 tls print >>file, ' case %s:\n' % self.EntryTagName(entry)
261 1.1.1.1.8.2 tls if not entry.Array():
262 1.1.1.1.8.2 tls print >>file, (
263 1.1.1.1.8.2 tls ' if (tmp->%s_set)\n'
264 1.1.1.1.8.2 tls ' return (-1);'
265 1.1.1.1.8.2 tls ) % (entry.Name())
266 1.1.1.1.8.2 tls
267 1.1.1.1.8.2 tls self.PrintIndented(
268 1.1.1.1.8.2 tls file, ' ',
269 1.1.1.1.8.2 tls entry.CodeUnmarshal('evbuf',
270 1.1.1.1.8.2 tls self.EntryTagName(entry),
271 1.1.1.1.8.2 tls entry.GetVarName('tmp'),
272 1.1.1.1.8.2 tls entry.GetVarLen('tmp')))
273 1.1.1.1.8.2 tls
274 1.1.1.1.8.2 tls print >>file, ( ' tmp->%s_set = 1;\n' % entry.Name() +
275 1.1.1.1.8.2 tls ' break;\n' )
276 1.1.1.1.8.2 tls print >>file, ( ' default:\n'
277 1.1.1.1.8.2 tls ' return -1;\n'
278 1.1.1.1.8.2 tls ' }\n'
279 1.1.1.1.8.2 tls ' }\n' )
280 1.1.1.1.8.2 tls # Check if it was decoded completely
281 1.1.1.1.8.2 tls print >>file, ( ' if (%(name)s_complete(tmp) == -1)\n'
282 1.1.1.1.8.2 tls ' return (-1);'
283 1.1.1.1.8.2 tls ) % { 'name' : self._name }
284 1.1.1.1.8.2 tls
285 1.1.1.1.8.2 tls # Successfully decoded
286 1.1.1.1.8.2 tls print >>file, ( ' return (0);\n'
287 1.1.1.1.8.2 tls '}\n')
288 1.1.1.1.8.2 tls
289 1.1.1.1.8.2 tls # Checking if a structure has all the required data
290 1.1.1.1.8.2 tls print >>file, (
291 1.1.1.1.8.2 tls 'int\n'
292 1.1.1.1.8.2 tls '%(name)s_complete(struct %(name)s *msg)\n'
293 1.1.1.1.8.2 tls '{' ) % { 'name' : self._name }
294 1.1.1.1.8.2 tls for entry in self._entries:
295 1.1.1.1.8.2 tls if not entry.Optional():
296 1.1.1.1.8.2 tls code = [
297 1.1.1.1.8.2 tls 'if (!msg->%(name)s_set)',
298 1.1.1.1.8.2 tls ' return (-1);' ]
299 1.1.1.1.8.2 tls code = TranslateList(code, entry.GetTranslation())
300 1.1.1.1.8.2 tls self.PrintIndented(
301 1.1.1.1.8.2 tls file, ' ', code)
302 1.1.1.1.8.2 tls
303 1.1.1.1.8.2 tls self.PrintIndented(
304 1.1.1.1.8.2 tls file, ' ',
305 1.1.1.1.8.2 tls entry.CodeComplete('msg', entry.GetVarName('msg')))
306 1.1.1.1.8.2 tls print >>file, (
307 1.1.1.1.8.2 tls ' return (0);\n'
308 1.1.1.1.8.2 tls '}\n' )
309 1.1.1.1.8.2 tls
310 1.1.1.1.8.2 tls # Complete message unmarshaling
311 1.1.1.1.8.2 tls print >>file, (
312 1.1.1.1.8.2 tls 'int\n'
313 1.1.1.1.8.2 tls 'evtag_unmarshal_%(name)s(struct evbuffer *evbuf, '
314 1.1.1.1.8.2 tls 'ev_uint32_t need_tag, struct %(name)s *msg)\n'
315 1.1.1.1.8.2 tls '{\n'
316 1.1.1.1.8.2 tls ' ev_uint32_t tag;\n'
317 1.1.1.1.8.2 tls ' int res = -1;\n'
318 1.1.1.1.8.2 tls '\n'
319 1.1.1.1.8.2 tls ' struct evbuffer *tmp = evbuffer_new();\n'
320 1.1.1.1.8.2 tls '\n'
321 1.1.1.1.8.2 tls ' if (evtag_unmarshal(evbuf, &tag, tmp) == -1'
322 1.1.1.1.8.2 tls ' || tag != need_tag)\n'
323 1.1.1.1.8.2 tls ' goto error;\n'
324 1.1.1.1.8.2 tls '\n'
325 1.1.1.1.8.2 tls ' if (%(name)s_unmarshal(msg, tmp) == -1)\n'
326 1.1.1.1.8.2 tls ' goto error;\n'
327 1.1.1.1.8.2 tls '\n'
328 1.1.1.1.8.2 tls ' res = 0;\n'
329 1.1.1.1.8.2 tls '\n'
330 1.1.1.1.8.2 tls ' error:\n'
331 1.1.1.1.8.2 tls ' evbuffer_free(tmp);\n'
332 1.1.1.1.8.2 tls ' return (res);\n'
333 1.1.1.1.8.2 tls '}\n' ) % { 'name' : self._name }
334 1.1.1.1.8.2 tls
335 1.1.1.1.8.2 tls # Complete message marshaling
336 1.1.1.1.8.2 tls print >>file, (
337 1.1.1.1.8.2 tls 'void\n'
338 1.1.1.1.8.2 tls 'evtag_marshal_%(name)s(struct evbuffer *evbuf, ev_uint32_t tag, '
339 1.1.1.1.8.2 tls 'const struct %(name)s *msg)\n'
340 1.1.1.1.8.2 tls '{\n'
341 1.1.1.1.8.2 tls ' struct evbuffer *buf_ = evbuffer_new();\n'
342 1.1.1.1.8.2 tls ' assert(buf_ != NULL);\n'
343 1.1.1.1.8.2 tls ' %(name)s_marshal(buf_, msg);\n'
344 1.1.1.1.8.2 tls ' evtag_marshal_buffer(evbuf, tag, buf_);\n '
345 1.1.1.1.8.2 tls ' evbuffer_free(buf_);\n'
346 1.1.1.1.8.2 tls '}\n' ) % { 'name' : self._name }
347 1.1.1.1.8.2 tls
348 1.1.1.1.8.2 tls class Entry:
349 1.1.1.1.8.2 tls def __init__(self, type, name, tag):
350 1.1.1.1.8.2 tls self._type = type
351 1.1.1.1.8.2 tls self._name = name
352 1.1.1.1.8.2 tls self._tag = int(tag)
353 1.1.1.1.8.2 tls self._ctype = type
354 1.1.1.1.8.2 tls self._optional = 0
355 1.1.1.1.8.2 tls self._can_be_array = 0
356 1.1.1.1.8.2 tls self._array = 0
357 1.1.1.1.8.2 tls self._line_count = -1
358 1.1.1.1.8.2 tls self._struct = None
359 1.1.1.1.8.2 tls self._refname = None
360 1.1.1.1.8.2 tls
361 1.1.1.1.8.2 tls self._optpointer = True
362 1.1.1.1.8.2 tls self._optaddarg = True
363 1.1.1.1.8.2 tls
364 1.1.1.1.8.2 tls def GetInitializer(self):
365 1.1.1.1.8.2 tls assert 0, "Entry does not provide initializer"
366 1.1.1.1.8.2 tls
367 1.1.1.1.8.2 tls def SetStruct(self, struct):
368 1.1.1.1.8.2 tls self._struct = struct
369 1.1.1.1.8.2 tls
370 1.1.1.1.8.2 tls def LineCount(self):
371 1.1.1.1.8.2 tls assert self._line_count != -1
372 1.1.1.1.8.2 tls return self._line_count
373 1.1.1.1.8.2 tls
374 1.1.1.1.8.2 tls def SetLineCount(self, number):
375 1.1.1.1.8.2 tls self._line_count = number
376 1.1.1.1.8.2 tls
377 1.1.1.1.8.2 tls def Array(self):
378 1.1.1.1.8.2 tls return self._array
379 1.1.1.1.8.2 tls
380 1.1.1.1.8.2 tls def Optional(self):
381 1.1.1.1.8.2 tls return self._optional
382 1.1.1.1.8.2 tls
383 1.1.1.1.8.2 tls def Tag(self):
384 1.1.1.1.8.2 tls return self._tag
385 1.1.1.1.8.2 tls
386 1.1.1.1.8.2 tls def Name(self):
387 1.1.1.1.8.2 tls return self._name
388 1.1.1.1.8.2 tls
389 1.1.1.1.8.2 tls def Type(self):
390 1.1.1.1.8.2 tls return self._type
391 1.1.1.1.8.2 tls
392 1.1.1.1.8.2 tls def MakeArray(self, yes=1):
393 1.1.1.1.8.2 tls self._array = yes
394 1.1.1.1.8.2 tls
395 1.1.1.1.8.2 tls def MakeOptional(self):
396 1.1.1.1.8.2 tls self._optional = 1
397 1.1.1.1.8.2 tls
398 1.1.1.1.8.2 tls def Verify(self):
399 1.1.1.1.8.2 tls if self.Array() and not self._can_be_array:
400 1.1.1.1.8.2 tls raise RpcGenError(
401 1.1.1.1.8.2 tls 'Entry "%s" cannot be created as an array '
402 1.1.1.1.8.2 tls 'around line %d' % (self._name, self.LineCount()))
403 1.1.1.1.8.2 tls if not self._struct:
404 1.1.1.1.8.2 tls raise RpcGenError(
405 1.1.1.1.8.2 tls 'Entry "%s" does not know which struct it belongs to '
406 1.1.1.1.8.2 tls 'around line %d' % (self._name, self.LineCount()))
407 1.1.1.1.8.2 tls if self._optional and self._array:
408 1.1.1.1.8.2 tls raise RpcGenError(
409 1.1.1.1.8.2 tls 'Entry "%s" has illegal combination of optional and array '
410 1.1.1.1.8.2 tls 'around line %d' % (self._name, self.LineCount()))
411 1.1.1.1.8.2 tls
412 1.1.1.1.8.2 tls def GetTranslation(self, extradict = {}):
413 1.1.1.1.8.2 tls mapping = {
414 1.1.1.1.8.2 tls "parent_name" : self._struct.Name(),
415 1.1.1.1.8.2 tls "name" : self._name,
416 1.1.1.1.8.2 tls "ctype" : self._ctype,
417 1.1.1.1.8.2 tls "refname" : self._refname,
418 1.1.1.1.8.2 tls "optpointer" : self._optpointer and "*" or "",
419 1.1.1.1.8.2 tls "optreference" : self._optpointer and "&" or "",
420 1.1.1.1.8.2 tls "optaddarg" :
421 1.1.1.1.8.2 tls self._optaddarg and ", const %s value" % self._ctype or ""
422 1.1.1.1.8.2 tls }
423 1.1.1.1.8.2 tls for (k, v) in extradict.items():
424 1.1.1.1.8.2 tls mapping[k] = v
425 1.1.1.1.8.2 tls
426 1.1.1.1.8.2 tls return mapping
427 1.1.1.1.8.2 tls
428 1.1.1.1.8.2 tls def GetVarName(self, var):
429 1.1.1.1.8.2 tls return '%(var)s->%(name)s_data' % self.GetTranslation({ 'var' : var })
430 1.1.1.1.8.2 tls
431 1.1.1.1.8.2 tls def GetVarLen(self, var):
432 1.1.1.1.8.2 tls return 'sizeof(%s)' % self._ctype
433 1.1.1.1.8.2 tls
434 1.1.1.1.8.2 tls def GetFuncName(self):
435 1.1.1.1.8.2 tls return '%s_%s_get' % (self._struct.Name(), self._name)
436 1.1.1.1.8.2 tls
437 1.1.1.1.8.2 tls def GetDeclaration(self, funcname):
438 1.1.1.1.8.2 tls code = [ 'int %s(struct %s *, %s *);' % (
439 1.1.1.1.8.2 tls funcname, self._struct.Name(), self._ctype ) ]
440 1.1.1.1.8.2 tls return code
441 1.1.1.1.8.2 tls
442 1.1.1.1.8.2 tls def CodeGet(self):
443 1.1.1.1.8.2 tls code = (
444 1.1.1.1.8.2 tls 'int',
445 1.1.1.1.8.2 tls '%(parent_name)s_%(name)s_get(struct %(parent_name)s *msg, '
446 1.1.1.1.8.2 tls '%(ctype)s *value)',
447 1.1.1.1.8.2 tls '{',
448 1.1.1.1.8.2 tls ' if (msg->%(name)s_set != 1)',
449 1.1.1.1.8.2 tls ' return (-1);',
450 1.1.1.1.8.2 tls ' *value = msg->%(name)s_data;',
451 1.1.1.1.8.2 tls ' return (0);',
452 1.1.1.1.8.2 tls '}' )
453 1.1.1.1.8.2 tls code = '\n'.join(code)
454 1.1.1.1.8.2 tls code = code % self.GetTranslation()
455 1.1.1.1.8.2 tls return code.split('\n')
456 1.1.1.1.8.2 tls
457 1.1.1.1.8.2 tls def AssignFuncName(self):
458 1.1.1.1.8.2 tls return '%s_%s_assign' % (self._struct.Name(), self._name)
459 1.1.1.1.8.2 tls
460 1.1.1.1.8.2 tls def AddFuncName(self):
461 1.1.1.1.8.2 tls return '%s_%s_add' % (self._struct.Name(), self._name)
462 1.1.1.1.8.2 tls
463 1.1.1.1.8.2 tls def AssignDeclaration(self, funcname):
464 1.1.1.1.8.2 tls code = [ 'int %s(struct %s *, const %s);' % (
465 1.1.1.1.8.2 tls funcname, self._struct.Name(), self._ctype ) ]
466 1.1.1.1.8.2 tls return code
467 1.1.1.1.8.2 tls
468 1.1.1.1.8.2 tls def CodeAssign(self):
469 1.1.1.1.8.2 tls code = [ 'int',
470 1.1.1.1.8.2 tls '%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg,'
471 1.1.1.1.8.2 tls ' const %(ctype)s value)',
472 1.1.1.1.8.2 tls '{',
473 1.1.1.1.8.2 tls ' msg->%(name)s_set = 1;',
474 1.1.1.1.8.2 tls ' msg->%(name)s_data = value;',
475 1.1.1.1.8.2 tls ' return (0);',
476 1.1.1.1.8.2 tls '}' ]
477 1.1.1.1.8.2 tls code = '\n'.join(code)
478 1.1.1.1.8.2 tls code = code % self.GetTranslation()
479 1.1.1.1.8.2 tls return code.split('\n')
480 1.1.1.1.8.2 tls
481 1.1.1.1.8.2 tls def CodeClear(self, structname):
482 1.1.1.1.8.2 tls code = [ '%s->%s_set = 0;' % (structname, self.Name()) ]
483 1.1.1.1.8.2 tls
484 1.1.1.1.8.2 tls return code
485 1.1.1.1.8.2 tls
486 1.1.1.1.8.2 tls def CodeComplete(self, structname, var_name):
487 1.1.1.1.8.2 tls return []
488 1.1.1.1.8.2 tls
489 1.1.1.1.8.2 tls def CodeFree(self, name):
490 1.1.1.1.8.2 tls return []
491 1.1.1.1.8.2 tls
492 1.1.1.1.8.2 tls def CodeBase(self):
493 1.1.1.1.8.2 tls code = [
494 1.1.1.1.8.2 tls '%(parent_name)s_%(name)s_assign,',
495 1.1.1.1.8.2 tls '%(parent_name)s_%(name)s_get,'
496 1.1.1.1.8.2 tls ]
497 1.1.1.1.8.2 tls if self.Array():
498 1.1.1.1.8.2 tls code.append('%(parent_name)s_%(name)s_add,')
499 1.1.1.1.8.2 tls
500 1.1.1.1.8.2 tls code = '\n'.join(code)
501 1.1.1.1.8.2 tls code = code % self.GetTranslation()
502 1.1.1.1.8.2 tls return code.split('\n')
503 1.1.1.1.8.2 tls
504 1.1.1.1.8.2 tls class EntryBytes(Entry):
505 1.1.1.1.8.2 tls def __init__(self, type, name, tag, length):
506 1.1.1.1.8.2 tls # Init base class
507 1.1.1.1.8.2 tls Entry.__init__(self, type, name, tag)
508 1.1.1.1.8.2 tls
509 1.1.1.1.8.2 tls self._length = length
510 1.1.1.1.8.2 tls self._ctype = 'ev_uint8_t'
511 1.1.1.1.8.2 tls
512 1.1.1.1.8.2 tls def GetInitializer(self):
513 1.1.1.1.8.2 tls return "NULL"
514 1.1.1.1.8.2 tls
515 1.1.1.1.8.2 tls def GetVarLen(self, var):
516 1.1.1.1.8.2 tls return '(%s)' % self._length
517 1.1.1.1.8.2 tls
518 1.1.1.1.8.2 tls def CodeArrayAdd(self, varname, value):
519 1.1.1.1.8.2 tls # XXX: copy here
520 1.1.1.1.8.2 tls return [ '%(varname)s = NULL;' % { 'varname' : varname } ]
521 1.1.1.1.8.2 tls
522 1.1.1.1.8.2 tls def GetDeclaration(self, funcname):
523 1.1.1.1.8.2 tls code = [ 'int %s(struct %s *, %s **);' % (
524 1.1.1.1.8.2 tls funcname, self._struct.Name(), self._ctype ) ]
525 1.1.1.1.8.2 tls return code
526 1.1.1.1.8.2 tls
527 1.1.1.1.8.2 tls def AssignDeclaration(self, funcname):
528 1.1.1.1.8.2 tls code = [ 'int %s(struct %s *, const %s *);' % (
529 1.1.1.1.8.2 tls funcname, self._struct.Name(), self._ctype ) ]
530 1.1.1.1.8.2 tls return code
531 1.1.1.1.8.2 tls
532 1.1.1.1.8.2 tls def Declaration(self):
533 1.1.1.1.8.2 tls dcl = ['ev_uint8_t %s_data[%s];' % (self._name, self._length)]
534 1.1.1.1.8.2 tls
535 1.1.1.1.8.2 tls return dcl
536 1.1.1.1.8.2 tls
537 1.1.1.1.8.2 tls def CodeGet(self):
538 1.1.1.1.8.2 tls name = self._name
539 1.1.1.1.8.2 tls code = [ 'int',
540 1.1.1.1.8.2 tls '%s_%s_get(struct %s *msg, %s **value)' % (
541 1.1.1.1.8.2 tls self._struct.Name(), name,
542 1.1.1.1.8.2 tls self._struct.Name(), self._ctype),
543 1.1.1.1.8.2 tls '{',
544 1.1.1.1.8.2 tls ' if (msg->%s_set != 1)' % name,
545 1.1.1.1.8.2 tls ' return (-1);',
546 1.1.1.1.8.2 tls ' *value = msg->%s_data;' % name,
547 1.1.1.1.8.2 tls ' return (0);',
548 1.1.1.1.8.2 tls '}' ]
549 1.1.1.1.8.2 tls return code
550 1.1.1.1.8.2 tls
551 1.1.1.1.8.2 tls def CodeAssign(self):
552 1.1.1.1.8.2 tls name = self._name
553 1.1.1.1.8.2 tls code = [ 'int',
554 1.1.1.1.8.2 tls '%s_%s_assign(struct %s *msg, const %s *value)' % (
555 1.1.1.1.8.2 tls self._struct.Name(), name,
556 1.1.1.1.8.2 tls self._struct.Name(), self._ctype),
557 1.1.1.1.8.2 tls '{',
558 1.1.1.1.8.2 tls ' msg->%s_set = 1;' % name,
559 1.1.1.1.8.2 tls ' memcpy(msg->%s_data, value, %s);' % (
560 1.1.1.1.8.2 tls name, self._length),
561 1.1.1.1.8.2 tls ' return (0);',
562 1.1.1.1.8.2 tls '}' ]
563 1.1.1.1.8.2 tls return code
564 1.1.1.1.8.2 tls
565 1.1.1.1.8.2 tls def CodeUnmarshal(self, buf, tag_name, var_name, var_len):
566 1.1.1.1.8.2 tls code = [ 'if (evtag_unmarshal_fixed(%(buf)s, %(tag)s, '
567 1.1.1.1.8.2 tls '%(var)s, %(varlen)s) == -1) {',
568 1.1.1.1.8.2 tls ' event_warnx("%%s: failed to unmarshal %(name)s", __func__);',
569 1.1.1.1.8.2 tls ' return (-1);',
570 1.1.1.1.8.2 tls '}'
571 1.1.1.1.8.2 tls ]
572 1.1.1.1.8.2 tls return TranslateList(code,
573 1.1.1.1.8.2 tls self.GetTranslation({
574 1.1.1.1.8.2 tls 'var' : var_name,
575 1.1.1.1.8.2 tls 'varlen' : var_len,
576 1.1.1.1.8.2 tls 'buf' : buf,
577 1.1.1.1.8.2 tls 'tag' : tag_name }))
578 1.1.1.1.8.2 tls
579 1.1.1.1.8.2 tls def CodeMarshal(self, buf, tag_name, var_name, var_len):
580 1.1.1.1.8.2 tls code = ['evtag_marshal(%s, %s, %s, %s);' % (
581 1.1.1.1.8.2 tls buf, tag_name, var_name, var_len)]
582 1.1.1.1.8.2 tls return code
583 1.1.1.1.8.2 tls
584 1.1.1.1.8.2 tls def CodeClear(self, structname):
585 1.1.1.1.8.2 tls code = [ '%s->%s_set = 0;' % (structname, self.Name()),
586 1.1.1.1.8.2 tls 'memset(%s->%s_data, 0, sizeof(%s->%s_data));' % (
587 1.1.1.1.8.2 tls structname, self._name, structname, self._name)]
588 1.1.1.1.8.2 tls
589 1.1.1.1.8.2 tls return code
590 1.1.1.1.8.2 tls
591 1.1.1.1.8.2 tls def CodeInitialize(self, name):
592 1.1.1.1.8.2 tls code = ['memset(%s->%s_data, 0, sizeof(%s->%s_data));' % (
593 1.1.1.1.8.2 tls name, self._name, name, self._name)]
594 1.1.1.1.8.2 tls return code
595 1.1.1.1.8.2 tls
596 1.1.1.1.8.2 tls def Verify(self):
597 1.1.1.1.8.2 tls if not self._length:
598 1.1.1.1.8.2 tls raise RpcGenError(
599 1.1.1.1.8.2 tls 'Entry "%s" needs a length '
600 1.1.1.1.8.2 tls 'around line %d' % (self._name, self.LineCount()))
601 1.1.1.1.8.2 tls
602 1.1.1.1.8.2 tls Entry.Verify(self)
603 1.1.1.1.8.2 tls
604 1.1.1.1.8.2 tls class EntryInt(Entry):
605 1.1.1.1.8.2 tls def __init__(self, type, name, tag, bits=32):
606 1.1.1.1.8.2 tls # Init base class
607 1.1.1.1.8.2 tls Entry.__init__(self, type, name, tag)
608 1.1.1.1.8.2 tls
609 1.1.1.1.8.2 tls self._can_be_array = 1
610 1.1.1.1.8.2 tls if bits == 32:
611 1.1.1.1.8.2 tls self._ctype = 'ev_uint32_t'
612 1.1.1.1.8.2 tls self._marshal_type = 'int'
613 1.1.1.1.8.2 tls if bits == 64:
614 1.1.1.1.8.2 tls self._ctype = 'ev_uint64_t'
615 1.1.1.1.8.2 tls self._marshal_type = 'int64'
616 1.1.1.1.8.2 tls
617 1.1.1.1.8.2 tls def GetInitializer(self):
618 1.1.1.1.8.2 tls return "0"
619 1.1.1.1.8.2 tls
620 1.1.1.1.8.2 tls def CodeArrayFree(self, var):
621 1.1.1.1.8.2 tls return []
622 1.1.1.1.8.2 tls
623 1.1.1.1.8.2 tls def CodeArrayAssign(self, varname, srcvar):
624 1.1.1.1.8.2 tls return [ '%(varname)s = %(srcvar)s;' % { 'varname' : varname,
625 1.1.1.1.8.2 tls 'srcvar' : srcvar } ]
626 1.1.1.1.8.2 tls
627 1.1.1.1.8.2 tls def CodeArrayAdd(self, varname, value):
628 1.1.1.1.8.2 tls """Returns a new entry of this type."""
629 1.1.1.1.8.2 tls return [ '%(varname)s = %(value)s;' % { 'varname' : varname,
630 1.1.1.1.8.2 tls 'value' : value } ]
631 1.1.1.1.8.2 tls
632 1.1.1.1.8.2 tls def CodeUnmarshal(self, buf, tag_name, var_name, var_len):
633 1.1.1.1.8.2 tls code = [
634 1.1.1.1.8.2 tls 'if (evtag_unmarshal_%(ma)s(%(buf)s, %(tag)s, &%(var)s) == -1) {',
635 1.1.1.1.8.2 tls ' event_warnx("%%s: failed to unmarshal %(name)s", __func__);',
636 1.1.1.1.8.2 tls ' return (-1);',
637 1.1.1.1.8.2 tls '}' ]
638 1.1.1.1.8.2 tls code = '\n'.join(code) % self.GetTranslation({
639 1.1.1.1.8.2 tls 'ma' : self._marshal_type,
640 1.1.1.1.8.2 tls 'buf' : buf,
641 1.1.1.1.8.2 tls 'tag' : tag_name,
642 1.1.1.1.8.2 tls 'var' : var_name })
643 1.1.1.1.8.2 tls return code.split('\n')
644 1.1.1.1.8.2 tls
645 1.1.1.1.8.2 tls def CodeMarshal(self, buf, tag_name, var_name, var_len):
646 1.1.1.1.8.2 tls code = [
647 1.1.1.1.8.2 tls 'evtag_marshal_%s(%s, %s, %s);' % (
648 1.1.1.1.8.2 tls self._marshal_type, buf, tag_name, var_name)]
649 1.1.1.1.8.2 tls return code
650 1.1.1.1.8.2 tls
651 1.1.1.1.8.2 tls def Declaration(self):
652 1.1.1.1.8.2 tls dcl = ['%s %s_data;' % (self._ctype, self._name)]
653 1.1.1.1.8.2 tls
654 1.1.1.1.8.2 tls return dcl
655 1.1.1.1.8.2 tls
656 1.1.1.1.8.2 tls def CodeInitialize(self, name):
657 1.1.1.1.8.2 tls code = ['%s->%s_data = 0;' % (name, self._name)]
658 1.1.1.1.8.2 tls return code
659 1.1.1.1.8.2 tls
660 1.1.1.1.8.2 tls class EntryString(Entry):
661 1.1.1.1.8.2 tls def __init__(self, type, name, tag):
662 1.1.1.1.8.2 tls # Init base class
663 1.1.1.1.8.2 tls Entry.__init__(self, type, name, tag)
664 1.1.1.1.8.2 tls
665 1.1.1.1.8.2 tls self._can_be_array = 1
666 1.1.1.1.8.2 tls self._ctype = 'char *'
667 1.1.1.1.8.2 tls
668 1.1.1.1.8.2 tls def GetInitializer(self):
669 1.1.1.1.8.2 tls return "NULL"
670 1.1.1.1.8.2 tls
671 1.1.1.1.8.2 tls def CodeArrayFree(self, varname):
672 1.1.1.1.8.2 tls code = [
673 1.1.1.1.8.2 tls 'if (%(var)s != NULL) free(%(var)s);' ]
674 1.1.1.1.8.2 tls
675 1.1.1.1.8.2 tls return TranslateList(code, { 'var' : varname })
676 1.1.1.1.8.2 tls
677 1.1.1.1.8.2 tls def CodeArrayAssign(self, varname, srcvar):
678 1.1.1.1.8.2 tls code = [
679 1.1.1.1.8.2 tls 'if (%(var)s != NULL)',
680 1.1.1.1.8.2 tls ' free(%(var)s);',
681 1.1.1.1.8.2 tls '%(var)s = strdup(%(srcvar)s);',
682 1.1.1.1.8.2 tls 'if (%(var)s == NULL) {',
683 1.1.1.1.8.2 tls ' event_warnx("%%s: strdup", __func__);',
684 1.1.1.1.8.2 tls ' return (-1);',
685 1.1.1.1.8.2 tls '}' ]
686 1.1.1.1.8.2 tls
687 1.1.1.1.8.2 tls return TranslateList(code, { 'var' : varname,
688 1.1.1.1.8.2 tls 'srcvar' : srcvar })
689 1.1.1.1.8.2 tls
690 1.1.1.1.8.2 tls def CodeArrayAdd(self, varname, value):
691 1.1.1.1.8.2 tls code = [
692 1.1.1.1.8.2 tls 'if (%(value)s != NULL) {',
693 1.1.1.1.8.2 tls ' %(var)s = strdup(%(value)s);',
694 1.1.1.1.8.2 tls ' if (%(var)s == NULL) {',
695 1.1.1.1.8.2 tls ' goto error;',
696 1.1.1.1.8.2 tls ' }',
697 1.1.1.1.8.2 tls '} else {',
698 1.1.1.1.8.2 tls ' %(var)s = NULL;',
699 1.1.1.1.8.2 tls '}' ]
700 1.1.1.1.8.2 tls
701 1.1.1.1.8.2 tls return TranslateList(code, { 'var' : varname,
702 1.1.1.1.8.2 tls 'value' : value })
703 1.1.1.1.8.2 tls
704 1.1.1.1.8.2 tls def GetVarLen(self, var):
705 1.1.1.1.8.2 tls return 'strlen(%s)' % self.GetVarName(var)
706 1.1.1.1.8.2 tls
707 1.1.1.1.8.2 tls def CodeMakeInitalize(self, varname):
708 1.1.1.1.8.2 tls return '%(varname)s = NULL;' % { 'varname' : varname }
709 1.1.1.1.8.2 tls
710 1.1.1.1.8.2 tls def CodeAssign(self):
711 1.1.1.1.8.2 tls name = self._name
712 1.1.1.1.8.2 tls code = """int
713 1.1.1.1.8.2 tls %(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg,
714 1.1.1.1.8.2 tls const %(ctype)s value)
715 1.1.1.1.8.2 tls {
716 1.1.1.1.8.2 tls if (msg->%(name)s_data != NULL)
717 1.1.1.1.8.2 tls free(msg->%(name)s_data);
718 1.1.1.1.8.2 tls if ((msg->%(name)s_data = strdup(value)) == NULL)
719 1.1.1.1.8.2 tls return (-1);
720 1.1.1.1.8.2 tls msg->%(name)s_set = 1;
721 1.1.1.1.8.2 tls return (0);
722 1.1.1.1.8.2 tls }""" % self.GetTranslation()
723 1.1.1.1.8.2 tls
724 1.1.1.1.8.2 tls return code.split('\n')
725 1.1.1.1.8.2 tls
726 1.1.1.1.8.2 tls def CodeUnmarshal(self, buf, tag_name, var_name, var_len):
727 1.1.1.1.8.2 tls code = ['if (evtag_unmarshal_string(%(buf)s, %(tag)s, &%(var)s) == -1) {',
728 1.1.1.1.8.2 tls ' event_warnx("%%s: failed to unmarshal %(name)s", __func__);',
729 1.1.1.1.8.2 tls ' return (-1);',
730 1.1.1.1.8.2 tls '}'
731 1.1.1.1.8.2 tls ]
732 1.1.1.1.8.2 tls code = '\n'.join(code) % self.GetTranslation({
733 1.1.1.1.8.2 tls 'buf' : buf,
734 1.1.1.1.8.2 tls 'tag' : tag_name,
735 1.1.1.1.8.2 tls 'var' : var_name })
736 1.1.1.1.8.2 tls return code.split('\n')
737 1.1.1.1.8.2 tls
738 1.1.1.1.8.2 tls def CodeMarshal(self, buf, tag_name, var_name, var_len):
739 1.1.1.1.8.2 tls code = ['evtag_marshal_string(%s, %s, %s);' % (
740 1.1.1.1.8.2 tls buf, tag_name, var_name)]
741 1.1.1.1.8.2 tls return code
742 1.1.1.1.8.2 tls
743 1.1.1.1.8.2 tls def CodeClear(self, structname):
744 1.1.1.1.8.2 tls code = [ 'if (%s->%s_set == 1) {' % (structname, self.Name()),
745 1.1.1.1.8.2 tls ' free(%s->%s_data);' % (structname, self.Name()),
746 1.1.1.1.8.2 tls ' %s->%s_data = NULL;' % (structname, self.Name()),
747 1.1.1.1.8.2 tls ' %s->%s_set = 0;' % (structname, self.Name()),
748 1.1.1.1.8.2 tls '}'
749 1.1.1.1.8.2 tls ]
750 1.1.1.1.8.2 tls
751 1.1.1.1.8.2 tls return code
752 1.1.1.1.8.2 tls
753 1.1.1.1.8.2 tls def CodeInitialize(self, name):
754 1.1.1.1.8.2 tls code = ['%s->%s_data = NULL;' % (name, self._name)]
755 1.1.1.1.8.2 tls return code
756 1.1.1.1.8.2 tls
757 1.1.1.1.8.2 tls def CodeFree(self, name):
758 1.1.1.1.8.2 tls code = ['if (%s->%s_data != NULL)' % (name, self._name),
759 1.1.1.1.8.2 tls ' free (%s->%s_data);' % (name, self._name)]
760 1.1.1.1.8.2 tls
761 1.1.1.1.8.2 tls return code
762 1.1.1.1.8.2 tls
763 1.1.1.1.8.2 tls def Declaration(self):
764 1.1.1.1.8.2 tls dcl = ['char *%s_data;' % self._name]
765 1.1.1.1.8.2 tls
766 1.1.1.1.8.2 tls return dcl
767 1.1.1.1.8.2 tls
768 1.1.1.1.8.2 tls class EntryStruct(Entry):
769 1.1.1.1.8.2 tls def __init__(self, type, name, tag, refname):
770 1.1.1.1.8.2 tls # Init base class
771 1.1.1.1.8.2 tls Entry.__init__(self, type, name, tag)
772 1.1.1.1.8.2 tls
773 1.1.1.1.8.2 tls self._optpointer = False
774 1.1.1.1.8.2 tls self._can_be_array = 1
775 1.1.1.1.8.2 tls self._refname = refname
776 1.1.1.1.8.2 tls self._ctype = 'struct %s*' % refname
777 1.1.1.1.8.2 tls self._optaddarg = False
778 1.1.1.1.8.2 tls
779 1.1.1.1.8.2 tls def GetInitializer(self):
780 1.1.1.1.8.2 tls return "NULL"
781 1.1.1.1.8.2 tls
782 1.1.1.1.8.2 tls def GetVarLen(self, var):
783 1.1.1.1.8.2 tls return '-1'
784 1.1.1.1.8.2 tls
785 1.1.1.1.8.2 tls def CodeArrayAdd(self, varname, value):
786 1.1.1.1.8.2 tls code = [
787 1.1.1.1.8.2 tls '%(varname)s = %(refname)s_new();',
788 1.1.1.1.8.2 tls 'if (%(varname)s == NULL)',
789 1.1.1.1.8.2 tls ' goto error;' ]
790 1.1.1.1.8.2 tls
791 1.1.1.1.8.2 tls return TranslateList(code, self.GetTranslation({ 'varname' : varname }))
792 1.1.1.1.8.2 tls
793 1.1.1.1.8.2 tls def CodeArrayFree(self, var):
794 1.1.1.1.8.2 tls code = [ '%(refname)s_free(%(var)s);' % self.GetTranslation(
795 1.1.1.1.8.2 tls { 'var' : var }) ]
796 1.1.1.1.8.2 tls return code
797 1.1.1.1.8.2 tls
798 1.1.1.1.8.2 tls def CodeArrayAssign(self, var, srcvar):
799 1.1.1.1.8.2 tls code = [
800 1.1.1.1.8.2 tls 'int had_error = 0;',
801 1.1.1.1.8.2 tls 'struct evbuffer *tmp = NULL;',
802 1.1.1.1.8.2 tls '%(refname)s_clear(%(var)s);',
803 1.1.1.1.8.2 tls 'if ((tmp = evbuffer_new()) == NULL) {',
804 1.1.1.1.8.2 tls ' event_warn("%%s: evbuffer_new()", __func__);',
805 1.1.1.1.8.2 tls ' had_error = 1;',
806 1.1.1.1.8.2 tls ' goto done;',
807 1.1.1.1.8.2 tls '}',
808 1.1.1.1.8.2 tls '%(refname)s_marshal(tmp, %(srcvar)s);',
809 1.1.1.1.8.2 tls 'if (%(refname)s_unmarshal(%(var)s, tmp) == -1) {',
810 1.1.1.1.8.2 tls ' event_warnx("%%s: %(refname)s_unmarshal", __func__);',
811 1.1.1.1.8.2 tls ' had_error = 1;',
812 1.1.1.1.8.2 tls ' goto done;',
813 1.1.1.1.8.2 tls '}',
814 1.1.1.1.8.2 tls 'done:'
815 1.1.1.1.8.2 tls 'if (tmp != NULL)',
816 1.1.1.1.8.2 tls ' evbuffer_free(tmp);',
817 1.1.1.1.8.2 tls 'if (had_error) {',
818 1.1.1.1.8.2 tls ' %(refname)s_clear(%(var)s);',
819 1.1.1.1.8.2 tls ' return (-1);',
820 1.1.1.1.8.2 tls '}' ]
821 1.1.1.1.8.2 tls
822 1.1.1.1.8.2 tls return TranslateList(code, self.GetTranslation({
823 1.1.1.1.8.2 tls 'var' : var,
824 1.1.1.1.8.2 tls 'srcvar' : srcvar}))
825 1.1.1.1.8.2 tls
826 1.1.1.1.8.2 tls def CodeGet(self):
827 1.1.1.1.8.2 tls name = self._name
828 1.1.1.1.8.2 tls code = [ 'int',
829 1.1.1.1.8.2 tls '%s_%s_get(struct %s *msg, %s *value)' % (
830 1.1.1.1.8.2 tls self._struct.Name(), name,
831 1.1.1.1.8.2 tls self._struct.Name(), self._ctype),
832 1.1.1.1.8.2 tls '{',
833 1.1.1.1.8.2 tls ' if (msg->%s_set != 1) {' % name,
834 1.1.1.1.8.2 tls ' msg->%s_data = %s_new();' % (name, self._refname),
835 1.1.1.1.8.2 tls ' if (msg->%s_data == NULL)' % name,
836 1.1.1.1.8.2 tls ' return (-1);',
837 1.1.1.1.8.2 tls ' msg->%s_set = 1;' % name,
838 1.1.1.1.8.2 tls ' }',
839 1.1.1.1.8.2 tls ' *value = msg->%s_data;' % name,
840 1.1.1.1.8.2 tls ' return (0);',
841 1.1.1.1.8.2 tls '}' ]
842 1.1.1.1.8.2 tls return code
843 1.1.1.1.8.2 tls
844 1.1.1.1.8.2 tls def CodeAssign(self):
845 1.1.1.1.8.2 tls name = self._name
846 1.1.1.1.8.2 tls code = """int
847 1.1.1.1.8.2 tls %(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg,
848 1.1.1.1.8.2 tls const %(ctype)s value)
849 1.1.1.1.8.2 tls {
850 1.1.1.1.8.2 tls struct evbuffer *tmp = NULL;
851 1.1.1.1.8.2 tls if (msg->%(name)s_set) {
852 1.1.1.1.8.2 tls %(refname)s_clear(msg->%(name)s_data);
853 1.1.1.1.8.2 tls msg->%(name)s_set = 0;
854 1.1.1.1.8.2 tls } else {
855 1.1.1.1.8.2 tls msg->%(name)s_data = %(refname)s_new();
856 1.1.1.1.8.2 tls if (msg->%(name)s_data == NULL) {
857 1.1.1.1.8.2 tls event_warn("%%s: %(refname)s_new()", __func__);
858 1.1.1.1.8.2 tls goto error;
859 1.1.1.1.8.2 tls }
860 1.1.1.1.8.2 tls }
861 1.1.1.1.8.2 tls if ((tmp = evbuffer_new()) == NULL) {
862 1.1.1.1.8.2 tls event_warn("%%s: evbuffer_new()", __func__);
863 1.1.1.1.8.2 tls goto error;
864 1.1.1.1.8.2 tls }
865 1.1.1.1.8.2 tls %(refname)s_marshal(tmp, value);
866 1.1.1.1.8.2 tls if (%(refname)s_unmarshal(msg->%(name)s_data, tmp) == -1) {
867 1.1.1.1.8.2 tls event_warnx("%%s: %(refname)s_unmarshal", __func__);
868 1.1.1.1.8.2 tls goto error;
869 1.1.1.1.8.2 tls }
870 1.1.1.1.8.2 tls msg->%(name)s_set = 1;
871 1.1.1.1.8.2 tls evbuffer_free(tmp);
872 1.1.1.1.8.2 tls return (0);
873 1.1.1.1.8.2 tls error:
874 1.1.1.1.8.2 tls if (tmp != NULL)
875 1.1.1.1.8.2 tls evbuffer_free(tmp);
876 1.1.1.1.8.2 tls if (msg->%(name)s_data != NULL) {
877 1.1.1.1.8.2 tls %(refname)s_free(msg->%(name)s_data);
878 1.1.1.1.8.2 tls msg->%(name)s_data = NULL;
879 1.1.1.1.8.2 tls }
880 1.1.1.1.8.2 tls return (-1);
881 1.1.1.1.8.2 tls }""" % self.GetTranslation()
882 1.1.1.1.8.2 tls return code.split('\n')
883 1.1.1.1.8.2 tls
884 1.1.1.1.8.2 tls def CodeComplete(self, structname, var_name):
885 1.1.1.1.8.2 tls code = [ 'if (%(structname)s->%(name)s_set && '
886 1.1.1.1.8.2 tls '%(refname)s_complete(%(var)s) == -1)',
887 1.1.1.1.8.2 tls ' return (-1);' ]
888 1.1.1.1.8.2 tls
889 1.1.1.1.8.2 tls return TranslateList(code, self.GetTranslation({
890 1.1.1.1.8.2 tls 'structname' : structname,
891 1.1.1.1.8.2 tls 'var' : var_name }))
892 1.1.1.1.8.2 tls
893 1.1.1.1.8.2 tls def CodeUnmarshal(self, buf, tag_name, var_name, var_len):
894 1.1.1.1.8.2 tls code = ['%(var)s = %(refname)s_new();',
895 1.1.1.1.8.2 tls 'if (%(var)s == NULL)',
896 1.1.1.1.8.2 tls ' return (-1);',
897 1.1.1.1.8.2 tls 'if (evtag_unmarshal_%(refname)s(%(buf)s, %(tag)s, '
898 1.1.1.1.8.2 tls '%(var)s) == -1) {',
899 1.1.1.1.8.2 tls ' event_warnx("%%s: failed to unmarshal %(name)s", __func__);',
900 1.1.1.1.8.2 tls ' return (-1);',
901 1.1.1.1.8.2 tls '}'
902 1.1.1.1.8.2 tls ]
903 1.1.1.1.8.2 tls code = '\n'.join(code) % self.GetTranslation({
904 1.1.1.1.8.2 tls 'buf' : buf,
905 1.1.1.1.8.2 tls 'tag' : tag_name,
906 1.1.1.1.8.2 tls 'var' : var_name })
907 1.1.1.1.8.2 tls return code.split('\n')
908 1.1.1.1.8.2 tls
909 1.1.1.1.8.2 tls def CodeMarshal(self, buf, tag_name, var_name, var_len):
910 1.1.1.1.8.2 tls code = ['evtag_marshal_%s(%s, %s, %s);' % (
911 1.1.1.1.8.2 tls self._refname, buf, tag_name, var_name)]
912 1.1.1.1.8.2 tls return code
913 1.1.1.1.8.2 tls
914 1.1.1.1.8.2 tls def CodeClear(self, structname):
915 1.1.1.1.8.2 tls code = [ 'if (%s->%s_set == 1) {' % (structname, self.Name()),
916 1.1.1.1.8.2 tls ' %s_free(%s->%s_data);' % (
917 1.1.1.1.8.2 tls self._refname, structname, self.Name()),
918 1.1.1.1.8.2 tls ' %s->%s_data = NULL;' % (structname, self.Name()),
919 1.1.1.1.8.2 tls ' %s->%s_set = 0;' % (structname, self.Name()),
920 1.1.1.1.8.2 tls '}'
921 1.1.1.1.8.2 tls ]
922 1.1.1.1.8.2 tls
923 1.1.1.1.8.2 tls return code
924 1.1.1.1.8.2 tls
925 1.1.1.1.8.2 tls def CodeInitialize(self, name):
926 1.1.1.1.8.2 tls code = ['%s->%s_data = NULL;' % (name, self._name)]
927 1.1.1.1.8.2 tls return code
928 1.1.1.1.8.2 tls
929 1.1.1.1.8.2 tls def CodeFree(self, name):
930 1.1.1.1.8.2 tls code = ['if (%s->%s_data != NULL)' % (name, self._name),
931 1.1.1.1.8.2 tls ' %s_free(%s->%s_data);' % (
932 1.1.1.1.8.2 tls self._refname, name, self._name)]
933 1.1.1.1.8.2 tls
934 1.1.1.1.8.2 tls return code
935 1.1.1.1.8.2 tls
936 1.1.1.1.8.2 tls def Declaration(self):
937 1.1.1.1.8.2 tls dcl = ['%s %s_data;' % (self._ctype, self._name)]
938 1.1.1.1.8.2 tls
939 1.1.1.1.8.2 tls return dcl
940 1.1.1.1.8.2 tls
941 1.1.1.1.8.2 tls class EntryVarBytes(Entry):
942 1.1.1.1.8.2 tls def __init__(self, type, name, tag):
943 1.1.1.1.8.2 tls # Init base class
944 1.1.1.1.8.2 tls Entry.__init__(self, type, name, tag)
945 1.1.1.1.8.2 tls
946 1.1.1.1.8.2 tls self._ctype = 'ev_uint8_t *'
947 1.1.1.1.8.2 tls
948 1.1.1.1.8.2 tls def GetInitializer(self):
949 1.1.1.1.8.2 tls return "NULL"
950 1.1.1.1.8.2 tls
951 1.1.1.1.8.2 tls def GetVarLen(self, var):
952 1.1.1.1.8.2 tls return '%(var)s->%(name)s_length' % self.GetTranslation({ 'var' : var })
953 1.1.1.1.8.2 tls
954 1.1.1.1.8.2 tls def CodeArrayAdd(self, varname, value):
955 1.1.1.1.8.2 tls # xxx: copy
956 1.1.1.1.8.2 tls return [ '%(varname)s = NULL;' % { 'varname' : varname } ]
957 1.1.1.1.8.2 tls
958 1.1.1.1.8.2 tls def GetDeclaration(self, funcname):
959 1.1.1.1.8.2 tls code = [ 'int %s(struct %s *, %s *, ev_uint32_t *);' % (
960 1.1.1.1.8.2 tls funcname, self._struct.Name(), self._ctype ) ]
961 1.1.1.1.8.2 tls return code
962 1.1.1.1.8.2 tls
963 1.1.1.1.8.2 tls def AssignDeclaration(self, funcname):
964 1.1.1.1.8.2 tls code = [ 'int %s(struct %s *, const %s, ev_uint32_t);' % (
965 1.1.1.1.8.2 tls funcname, self._struct.Name(), self._ctype ) ]
966 1.1.1.1.8.2 tls return code
967 1.1.1.1.8.2 tls
968 1.1.1.1.8.2 tls def CodeAssign(self):
969 1.1.1.1.8.2 tls name = self._name
970 1.1.1.1.8.2 tls code = [ 'int',
971 1.1.1.1.8.2 tls '%s_%s_assign(struct %s *msg, '
972 1.1.1.1.8.2 tls 'const %s value, ev_uint32_t len)' % (
973 1.1.1.1.8.2 tls self._struct.Name(), name,
974 1.1.1.1.8.2 tls self._struct.Name(), self._ctype),
975 1.1.1.1.8.2 tls '{',
976 1.1.1.1.8.2 tls ' if (msg->%s_data != NULL)' % name,
977 1.1.1.1.8.2 tls ' free (msg->%s_data);' % name,
978 1.1.1.1.8.2 tls ' msg->%s_data = malloc(len);' % name,
979 1.1.1.1.8.2 tls ' if (msg->%s_data == NULL)' % name,
980 1.1.1.1.8.2 tls ' return (-1);',
981 1.1.1.1.8.2 tls ' msg->%s_set = 1;' % name,
982 1.1.1.1.8.2 tls ' msg->%s_length = len;' % name,
983 1.1.1.1.8.2 tls ' memcpy(msg->%s_data, value, len);' % name,
984 1.1.1.1.8.2 tls ' return (0);',
985 1.1.1.1.8.2 tls '}' ]
986 1.1.1.1.8.2 tls return code
987 1.1.1.1.8.2 tls
988 1.1.1.1.8.2 tls def CodeGet(self):
989 1.1.1.1.8.2 tls name = self._name
990 1.1.1.1.8.2 tls code = [ 'int',
991 1.1.1.1.8.2 tls '%s_%s_get(struct %s *msg, %s *value, ev_uint32_t *plen)' % (
992 1.1.1.1.8.2 tls self._struct.Name(), name,
993 1.1.1.1.8.2 tls self._struct.Name(), self._ctype),
994 1.1.1.1.8.2 tls '{',
995 1.1.1.1.8.2 tls ' if (msg->%s_set != 1)' % name,
996 1.1.1.1.8.2 tls ' return (-1);',
997 1.1.1.1.8.2 tls ' *value = msg->%s_data;' % name,
998 1.1.1.1.8.2 tls ' *plen = msg->%s_length;' % name,
999 1.1.1.1.8.2 tls ' return (0);',
1000 1.1.1.1.8.2 tls '}' ]
1001 1.1.1.1.8.2 tls return code
1002 1.1.1.1.8.2 tls
1003 1.1.1.1.8.2 tls def CodeUnmarshal(self, buf, tag_name, var_name, var_len):
1004 1.1.1.1.8.2 tls code = ['if (evtag_payload_length(%(buf)s, &%(varlen)s) == -1)',
1005 1.1.1.1.8.2 tls ' return (-1);',
1006 1.1.1.1.8.2 tls # We do not want DoS opportunities
1007 1.1.1.1.8.2 tls 'if (%(varlen)s > evbuffer_get_length(%(buf)s))',
1008 1.1.1.1.8.2 tls ' return (-1);',
1009 1.1.1.1.8.2 tls 'if ((%(var)s = malloc(%(varlen)s)) == NULL)',
1010 1.1.1.1.8.2 tls ' return (-1);',
1011 1.1.1.1.8.2 tls 'if (evtag_unmarshal_fixed(%(buf)s, %(tag)s, %(var)s, '
1012 1.1.1.1.8.2 tls '%(varlen)s) == -1) {',
1013 1.1.1.1.8.2 tls ' event_warnx("%%s: failed to unmarshal %(name)s", __func__);',
1014 1.1.1.1.8.2 tls ' return (-1);',
1015 1.1.1.1.8.2 tls '}'
1016 1.1.1.1.8.2 tls ]
1017 1.1.1.1.8.2 tls code = '\n'.join(code) % self.GetTranslation({
1018 1.1.1.1.8.2 tls 'buf' : buf,
1019 1.1.1.1.8.2 tls 'tag' : tag_name,
1020 1.1.1.1.8.2 tls 'var' : var_name,
1021 1.1.1.1.8.2 tls 'varlen' : var_len })
1022 1.1.1.1.8.2 tls return code.split('\n')
1023 1.1.1.1.8.2 tls
1024 1.1.1.1.8.2 tls def CodeMarshal(self, buf, tag_name, var_name, var_len):
1025 1.1.1.1.8.2 tls code = ['evtag_marshal(%s, %s, %s, %s);' % (
1026 1.1.1.1.8.2 tls buf, tag_name, var_name, var_len)]
1027 1.1.1.1.8.2 tls return code
1028 1.1.1.1.8.2 tls
1029 1.1.1.1.8.2 tls def CodeClear(self, structname):
1030 1.1.1.1.8.2 tls code = [ 'if (%s->%s_set == 1) {' % (structname, self.Name()),
1031 1.1.1.1.8.2 tls ' free (%s->%s_data);' % (structname, self.Name()),
1032 1.1.1.1.8.2 tls ' %s->%s_data = NULL;' % (structname, self.Name()),
1033 1.1.1.1.8.2 tls ' %s->%s_length = 0;' % (structname, self.Name()),
1034 1.1.1.1.8.2 tls ' %s->%s_set = 0;' % (structname, self.Name()),
1035 1.1.1.1.8.2 tls '}'
1036 1.1.1.1.8.2 tls ]
1037 1.1.1.1.8.2 tls
1038 1.1.1.1.8.2 tls return code
1039 1.1.1.1.8.2 tls
1040 1.1.1.1.8.2 tls def CodeInitialize(self, name):
1041 1.1.1.1.8.2 tls code = ['%s->%s_data = NULL;' % (name, self._name),
1042 1.1.1.1.8.2 tls '%s->%s_length = 0;' % (name, self._name) ]
1043 1.1.1.1.8.2 tls return code
1044 1.1.1.1.8.2 tls
1045 1.1.1.1.8.2 tls def CodeFree(self, name):
1046 1.1.1.1.8.2 tls code = ['if (%s->%s_data != NULL)' % (name, self._name),
1047 1.1.1.1.8.2 tls ' free(%s->%s_data);' % (name, self._name)]
1048 1.1.1.1.8.2 tls
1049 1.1.1.1.8.2 tls return code
1050 1.1.1.1.8.2 tls
1051 1.1.1.1.8.2 tls def Declaration(self):
1052 1.1.1.1.8.2 tls dcl = ['ev_uint8_t *%s_data;' % self._name,
1053 1.1.1.1.8.2 tls 'ev_uint32_t %s_length;' % self._name]
1054 1.1.1.1.8.2 tls
1055 1.1.1.1.8.2 tls return dcl
1056 1.1.1.1.8.2 tls
1057 1.1.1.1.8.2 tls class EntryArray(Entry):
1058 1.1.1.1.8.2 tls def __init__(self, entry):
1059 1.1.1.1.8.2 tls # Init base class
1060 1.1.1.1.8.2 tls Entry.__init__(self, entry._type, entry._name, entry._tag)
1061 1.1.1.1.8.2 tls
1062 1.1.1.1.8.2 tls self._entry = entry
1063 1.1.1.1.8.2 tls self._refname = entry._refname
1064 1.1.1.1.8.2 tls self._ctype = self._entry._ctype
1065 1.1.1.1.8.2 tls self._optional = True
1066 1.1.1.1.8.2 tls self._optpointer = self._entry._optpointer
1067 1.1.1.1.8.2 tls self._optaddarg = self._entry._optaddarg
1068 1.1.1.1.8.2 tls
1069 1.1.1.1.8.2 tls # provide a new function for accessing the variable name
1070 1.1.1.1.8.2 tls def GetVarName(var_name):
1071 1.1.1.1.8.2 tls return '%(var)s->%(name)s_data[%(index)s]' % \
1072 1.1.1.1.8.2 tls self._entry.GetTranslation({'var' : var_name,
1073 1.1.1.1.8.2 tls 'index' : self._index})
1074 1.1.1.1.8.2 tls self._entry.GetVarName = GetVarName
1075 1.1.1.1.8.2 tls
1076 1.1.1.1.8.2 tls def GetInitializer(self):
1077 1.1.1.1.8.2 tls return "NULL"
1078 1.1.1.1.8.2 tls
1079 1.1.1.1.8.2 tls def GetVarName(self, var_name):
1080 1.1.1.1.8.2 tls return var_name
1081 1.1.1.1.8.2 tls
1082 1.1.1.1.8.2 tls def GetVarLen(self, var_name):
1083 1.1.1.1.8.2 tls return '-1'
1084 1.1.1.1.8.2 tls
1085 1.1.1.1.8.2 tls def GetDeclaration(self, funcname):
1086 1.1.1.1.8.2 tls """Allows direct access to elements of the array."""
1087 1.1.1.1.8.2 tls code = [
1088 1.1.1.1.8.2 tls 'int %(funcname)s(struct %(parent_name)s *, int, %(ctype)s *);' %
1089 1.1.1.1.8.2 tls self.GetTranslation({ 'funcname' : funcname }) ]
1090 1.1.1.1.8.2 tls return code
1091 1.1.1.1.8.2 tls
1092 1.1.1.1.8.2 tls def AssignDeclaration(self, funcname):
1093 1.1.1.1.8.2 tls code = [ 'int %s(struct %s *, int, const %s);' % (
1094 1.1.1.1.8.2 tls funcname, self._struct.Name(), self._ctype ) ]
1095 1.1.1.1.8.2 tls return code
1096 1.1.1.1.8.2 tls
1097 1.1.1.1.8.2 tls def AddDeclaration(self, funcname):
1098 1.1.1.1.8.2 tls code = [
1099 1.1.1.1.8.2 tls '%(ctype)s %(optpointer)s '
1100 1.1.1.1.8.2 tls '%(funcname)s(struct %(parent_name)s *msg%(optaddarg)s);' % \
1101 1.1.1.1.8.2 tls self.GetTranslation({ 'funcname' : funcname }) ]
1102 1.1.1.1.8.2 tls return code
1103 1.1.1.1.8.2 tls
1104 1.1.1.1.8.2 tls def CodeGet(self):
1105 1.1.1.1.8.2 tls code = """int
1106 1.1.1.1.8.2 tls %(parent_name)s_%(name)s_get(struct %(parent_name)s *msg, int offset,
1107 1.1.1.1.8.2 tls %(ctype)s *value)
1108 1.1.1.1.8.2 tls {
1109 1.1.1.1.8.2 tls if (!msg->%(name)s_set || offset < 0 || offset >= msg->%(name)s_length)
1110 1.1.1.1.8.2 tls return (-1);
1111 1.1.1.1.8.2 tls *value = msg->%(name)s_data[offset];
1112 1.1.1.1.8.2 tls return (0);
1113 1.1.1.1.8.2 tls }""" % self.GetTranslation()
1114 1.1.1.1.8.2 tls
1115 1.1.1.1.8.2 tls return code.split('\n')
1116 1.1.1.1.8.2 tls
1117 1.1.1.1.8.2 tls def CodeAssign(self):
1118 1.1.1.1.8.2 tls code = [
1119 1.1.1.1.8.2 tls 'int',
1120 1.1.1.1.8.2 tls '%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg, int off,',
1121 1.1.1.1.8.2 tls ' const %(ctype)s value)',
1122 1.1.1.1.8.2 tls '{',
1123 1.1.1.1.8.2 tls ' if (!msg->%(name)s_set || off < 0 || off >= msg->%(name)s_length)',
1124 1.1.1.1.8.2 tls ' return (-1);\n',
1125 1.1.1.1.8.2 tls ' {' ]
1126 1.1.1.1.8.2 tls code = TranslateList(code, self.GetTranslation())
1127 1.1.1.1.8.2 tls
1128 1.1.1.1.8.2 tls codearrayassign = self._entry.CodeArrayAssign(
1129 1.1.1.1.8.2 tls 'msg->%(name)s_data[off]' % self.GetTranslation(), 'value')
1130 1.1.1.1.8.2 tls code += map(lambda x: ' ' + x, codearrayassign)
1131 1.1.1.1.8.2 tls
1132 1.1.1.1.8.2 tls code += TranslateList([
1133 1.1.1.1.8.2 tls ' }',
1134 1.1.1.1.8.2 tls ' return (0);',
1135 1.1.1.1.8.2 tls '}' ], self.GetTranslation())
1136 1.1.1.1.8.2 tls
1137 1.1.1.1.8.2 tls return code
1138 1.1.1.1.8.2 tls
1139 1.1.1.1.8.2 tls def CodeAdd(self):
1140 1.1.1.1.8.2 tls codearrayadd = self._entry.CodeArrayAdd(
1141 1.1.1.1.8.2 tls 'msg->%(name)s_data[msg->%(name)s_length - 1]' % self.GetTranslation(),
1142 1.1.1.1.8.2 tls 'value')
1143 1.1.1.1.8.2 tls code = [
1144 1.1.1.1.8.2 tls 'static int',
1145 1.1.1.1.8.2 tls '%(parent_name)s_%(name)s_expand_to_hold_more('
1146 1.1.1.1.8.2 tls 'struct %(parent_name)s *msg)',
1147 1.1.1.1.8.2 tls '{',
1148 1.1.1.1.8.2 tls ' int tobe_allocated = msg->%(name)s_num_allocated;',
1149 1.1.1.1.8.2 tls ' %(ctype)s* new_data = NULL;',
1150 1.1.1.1.8.2 tls ' tobe_allocated = !tobe_allocated ? 1 : tobe_allocated << 1;',
1151 1.1.1.1.8.2 tls ' new_data = (%(ctype)s*) realloc(msg->%(name)s_data,',
1152 1.1.1.1.8.2 tls ' tobe_allocated * sizeof(%(ctype)s));',
1153 1.1.1.1.8.2 tls ' if (new_data == NULL)',
1154 1.1.1.1.8.2 tls ' return -1;',
1155 1.1.1.1.8.2 tls ' msg->%(name)s_data = new_data;',
1156 1.1.1.1.8.2 tls ' msg->%(name)s_num_allocated = tobe_allocated;',
1157 1.1.1.1.8.2 tls ' return 0;'
1158 1.1.1.1.8.2 tls '}',
1159 1.1.1.1.8.2 tls '',
1160 1.1.1.1.8.2 tls '%(ctype)s %(optpointer)s',
1161 1.1.1.1.8.2 tls '%(parent_name)s_%(name)s_add('
1162 1.1.1.1.8.2 tls 'struct %(parent_name)s *msg%(optaddarg)s)',
1163 1.1.1.1.8.2 tls '{',
1164 1.1.1.1.8.2 tls ' if (++msg->%(name)s_length >= msg->%(name)s_num_allocated) {',
1165 1.1.1.1.8.2 tls ' if (%(parent_name)s_%(name)s_expand_to_hold_more(msg)<0)',
1166 1.1.1.1.8.2 tls ' goto error;',
1167 1.1.1.1.8.2 tls ' }' ]
1168 1.1.1.1.8.2 tls
1169 1.1.1.1.8.2 tls code = TranslateList(code, self.GetTranslation())
1170 1.1.1.1.8.2 tls
1171 1.1.1.1.8.2 tls code += map(lambda x: ' ' + x, codearrayadd)
1172 1.1.1.1.8.2 tls
1173 1.1.1.1.8.2 tls code += TranslateList([
1174 1.1.1.1.8.2 tls ' msg->%(name)s_set = 1;',
1175 1.1.1.1.8.2 tls ' return %(optreference)s(msg->%(name)s_data['
1176 1.1.1.1.8.2 tls 'msg->%(name)s_length - 1]);',
1177 1.1.1.1.8.2 tls 'error:',
1178 1.1.1.1.8.2 tls ' --msg->%(name)s_length;',
1179 1.1.1.1.8.2 tls ' return (NULL);',
1180 1.1.1.1.8.2 tls '}' ], self.GetTranslation())
1181 1.1.1.1.8.2 tls
1182 1.1.1.1.8.2 tls return code
1183 1.1.1.1.8.2 tls
1184 1.1.1.1.8.2 tls def CodeComplete(self, structname, var_name):
1185 1.1.1.1.8.2 tls self._index = 'i'
1186 1.1.1.1.8.2 tls tmp = self._entry.CodeComplete(structname, self._entry.GetVarName(var_name))
1187 1.1.1.1.8.2 tls # skip the whole loop if there is nothing to check
1188 1.1.1.1.8.2 tls if not tmp:
1189 1.1.1.1.8.2 tls return []
1190 1.1.1.1.8.2 tls
1191 1.1.1.1.8.2 tls translate = self.GetTranslation({ 'structname' : structname })
1192 1.1.1.1.8.2 tls code = [
1193 1.1.1.1.8.2 tls '{',
1194 1.1.1.1.8.2 tls ' int i;',
1195 1.1.1.1.8.2 tls ' for (i = 0; i < %(structname)s->%(name)s_length; ++i) {' ]
1196 1.1.1.1.8.2 tls
1197 1.1.1.1.8.2 tls code = TranslateList(code, translate)
1198 1.1.1.1.8.2 tls
1199 1.1.1.1.8.2 tls code += map(lambda x: ' ' + x, tmp)
1200 1.1.1.1.8.2 tls
1201 1.1.1.1.8.2 tls code += [
1202 1.1.1.1.8.2 tls ' }',
1203 1.1.1.1.8.2 tls '}' ]
1204 1.1.1.1.8.2 tls
1205 1.1.1.1.8.2 tls return code
1206 1.1.1.1.8.2 tls
1207 1.1.1.1.8.2 tls def CodeUnmarshal(self, buf, tag_name, var_name, var_len):
1208 1.1.1.1.8.2 tls translate = self.GetTranslation({ 'var' : var_name,
1209 1.1.1.1.8.2 tls 'buf' : buf,
1210 1.1.1.1.8.2 tls 'tag' : tag_name,
1211 1.1.1.1.8.2 tls 'init' : self._entry.GetInitializer()})
1212 1.1.1.1.8.2 tls code = [
1213 1.1.1.1.8.2 tls 'if (%(var)s->%(name)s_length >= %(var)s->%(name)s_num_allocated &&',
1214 1.1.1.1.8.2 tls ' %(parent_name)s_%(name)s_expand_to_hold_more(%(var)s) < 0) {',
1215 1.1.1.1.8.2 tls ' puts("HEY NOW");',
1216 1.1.1.1.8.2 tls ' return (-1);',
1217 1.1.1.1.8.2 tls '}']
1218 1.1.1.1.8.2 tls
1219 1.1.1.1.8.2 tls # the unmarshal code directly returns
1220 1.1.1.1.8.2 tls code = TranslateList(code, translate)
1221 1.1.1.1.8.2 tls
1222 1.1.1.1.8.2 tls self._index = '%(var)s->%(name)s_length' % translate
1223 1.1.1.1.8.2 tls code += self._entry.CodeUnmarshal(buf, tag_name,
1224 1.1.1.1.8.2 tls self._entry.GetVarName(var_name),
1225 1.1.1.1.8.2 tls self._entry.GetVarLen(var_name))
1226 1.1.1.1.8.2 tls
1227 1.1.1.1.8.2 tls code += [ '++%(var)s->%(name)s_length;' % translate ]
1228 1.1.1.1.8.2 tls
1229 1.1.1.1.8.2 tls return code
1230 1.1.1.1.8.2 tls
1231 1.1.1.1.8.2 tls def CodeMarshal(self, buf, tag_name, var_name, var_len):
1232 1.1.1.1.8.2 tls code = ['{',
1233 1.1.1.1.8.2 tls ' int i;',
1234 1.1.1.1.8.2 tls ' for (i = 0; i < %(var)s->%(name)s_length; ++i) {' ]
1235 1.1.1.1.8.2 tls
1236 1.1.1.1.8.2 tls self._index = 'i'
1237 1.1.1.1.8.2 tls code += self._entry.CodeMarshal(buf, tag_name,
1238 1.1.1.1.8.2 tls self._entry.GetVarName(var_name),
1239 1.1.1.1.8.2 tls self._entry.GetVarLen(var_name))
1240 1.1.1.1.8.2 tls code += [' }',
1241 1.1.1.1.8.2 tls '}'
1242 1.1.1.1.8.2 tls ]
1243 1.1.1.1.8.2 tls
1244 1.1.1.1.8.2 tls code = "\n".join(code) % self.GetTranslation({ 'var' : var_name })
1245 1.1.1.1.8.2 tls
1246 1.1.1.1.8.2 tls return code.split('\n')
1247 1.1.1.1.8.2 tls
1248 1.1.1.1.8.2 tls def CodeClear(self, structname):
1249 1.1.1.1.8.2 tls translate = self.GetTranslation({ 'structname' : structname })
1250 1.1.1.1.8.2 tls codearrayfree = self._entry.CodeArrayFree(
1251 1.1.1.1.8.2 tls '%(structname)s->%(name)s_data[i]' % self.GetTranslation(
1252 1.1.1.1.8.2 tls { 'structname' : structname } ))
1253 1.1.1.1.8.2 tls
1254 1.1.1.1.8.2 tls code = [ 'if (%(structname)s->%(name)s_set == 1) {' ]
1255 1.1.1.1.8.2 tls
1256 1.1.1.1.8.2 tls if codearrayfree:
1257 1.1.1.1.8.2 tls code += [
1258 1.1.1.1.8.2 tls ' int i;',
1259 1.1.1.1.8.2 tls ' for (i = 0; i < %(structname)s->%(name)s_length; ++i) {' ]
1260 1.1.1.1.8.2 tls
1261 1.1.1.1.8.2 tls code = TranslateList(code, translate)
1262 1.1.1.1.8.2 tls
1263 1.1.1.1.8.2 tls if codearrayfree:
1264 1.1.1.1.8.2 tls code += map(lambda x: ' ' + x, codearrayfree)
1265 1.1.1.1.8.2 tls code += [
1266 1.1.1.1.8.2 tls ' }' ]
1267 1.1.1.1.8.2 tls
1268 1.1.1.1.8.2 tls code += TranslateList([
1269 1.1.1.1.8.2 tls ' free(%(structname)s->%(name)s_data);',
1270 1.1.1.1.8.2 tls ' %(structname)s->%(name)s_data = NULL;',
1271 1.1.1.1.8.2 tls ' %(structname)s->%(name)s_set = 0;',
1272 1.1.1.1.8.2 tls ' %(structname)s->%(name)s_length = 0;',
1273 1.1.1.1.8.2 tls ' %(structname)s->%(name)s_num_allocated = 0;',
1274 1.1.1.1.8.2 tls '}'
1275 1.1.1.1.8.2 tls ], translate)
1276 1.1.1.1.8.2 tls
1277 1.1.1.1.8.2 tls return code
1278 1.1.1.1.8.2 tls
1279 1.1.1.1.8.2 tls def CodeInitialize(self, name):
1280 1.1.1.1.8.2 tls code = ['%s->%s_data = NULL;' % (name, self._name),
1281 1.1.1.1.8.2 tls '%s->%s_length = 0;' % (name, self._name),
1282 1.1.1.1.8.2 tls '%s->%s_num_allocated = 0;' % (name, self._name)]
1283 1.1.1.1.8.2 tls return code
1284 1.1.1.1.8.2 tls
1285 1.1.1.1.8.2 tls def CodeFree(self, structname):
1286 1.1.1.1.8.2 tls code = self.CodeClear(structname);
1287 1.1.1.1.8.2 tls
1288 1.1.1.1.8.2 tls code += TranslateList([
1289 1.1.1.1.8.2 tls 'free(%(structname)s->%(name)s_data);' ],
1290 1.1.1.1.8.2 tls self.GetTranslation({'structname' : structname }))
1291 1.1.1.1.8.2 tls
1292 1.1.1.1.8.2 tls return code
1293 1.1.1.1.8.2 tls
1294 1.1.1.1.8.2 tls def Declaration(self):
1295 1.1.1.1.8.2 tls dcl = ['%s *%s_data;' % (self._ctype, self._name),
1296 1.1.1.1.8.2 tls 'int %s_length;' % self._name,
1297 1.1.1.1.8.2 tls 'int %s_num_allocated;' % self._name ]
1298 1.1.1.1.8.2 tls
1299 1.1.1.1.8.2 tls return dcl
1300 1.1.1.1.8.2 tls
1301 1.1.1.1.8.2 tls def NormalizeLine(line):
1302 1.1.1.1.8.2 tls global white
1303 1.1.1.1.8.2 tls global cppcomment
1304 1.1.1.1.8.2 tls
1305 1.1.1.1.8.2 tls line = cppcomment.sub('', line)
1306 1.1.1.1.8.2 tls line = line.strip()
1307 1.1.1.1.8.2 tls line = white.sub(' ', line)
1308 1.1.1.1.8.2 tls
1309 1.1.1.1.8.2 tls return line
1310 1.1.1.1.8.2 tls
1311 1.1.1.1.8.2 tls def ProcessOneEntry(factory, newstruct, entry):
1312 1.1.1.1.8.2 tls optional = 0
1313 1.1.1.1.8.2 tls array = 0
1314 1.1.1.1.8.2 tls entry_type = ''
1315 1.1.1.1.8.2 tls name = ''
1316 1.1.1.1.8.2 tls tag = ''
1317 1.1.1.1.8.2 tls tag_set = None
1318 1.1.1.1.8.2 tls separator = ''
1319 1.1.1.1.8.2 tls fixed_length = ''
1320 1.1.1.1.8.2 tls
1321 1.1.1.1.8.2 tls tokens = entry.split(' ')
1322 1.1.1.1.8.2 tls while tokens:
1323 1.1.1.1.8.2 tls token = tokens[0]
1324 1.1.1.1.8.2 tls tokens = tokens[1:]
1325 1.1.1.1.8.2 tls
1326 1.1.1.1.8.2 tls if not entry_type:
1327 1.1.1.1.8.2 tls if not optional and token == 'optional':
1328 1.1.1.1.8.2 tls optional = 1
1329 1.1.1.1.8.2 tls continue
1330 1.1.1.1.8.2 tls
1331 1.1.1.1.8.2 tls if not array and token == 'array':
1332 1.1.1.1.8.2 tls array = 1
1333 1.1.1.1.8.2 tls continue
1334 1.1.1.1.8.2 tls
1335 1.1.1.1.8.2 tls if not entry_type:
1336 1.1.1.1.8.2 tls entry_type = token
1337 1.1.1.1.8.2 tls continue
1338 1.1.1.1.8.2 tls
1339 1.1.1.1.8.2 tls if not name:
1340 1.1.1.1.8.2 tls res = re.match(r'^([^\[\]]+)(\[.*\])?$', token)
1341 1.1.1.1.8.2 tls if not res:
1342 1.1.1.1.8.2 tls raise RpcGenError(
1343 1.1.1.1.8.2 tls 'Cannot parse name: \"%s\" '
1344 1.1.1.1.8.2 tls 'around line %d' % (entry, line_count))
1345 1.1.1.1.8.2 tls name = res.group(1)
1346 1.1.1.1.8.2 tls fixed_length = res.group(2)
1347 1.1.1.1.8.2 tls if fixed_length:
1348 1.1.1.1.8.2 tls fixed_length = fixed_length[1:-1]
1349 1.1.1.1.8.2 tls continue
1350 1.1.1.1.8.2 tls
1351 1.1.1.1.8.2 tls if not separator:
1352 1.1.1.1.8.2 tls separator = token
1353 1.1.1.1.8.2 tls if separator != '=':
1354 1.1.1.1.8.2 tls raise RpcGenError('Expected "=" after name \"%s\" got %s'
1355 1.1.1.1.8.2 tls % (name, token))
1356 1.1.1.1.8.2 tls continue
1357 1.1.1.1.8.2 tls
1358 1.1.1.1.8.2 tls if not tag_set:
1359 1.1.1.1.8.2 tls tag_set = 1
1360 1.1.1.1.8.2 tls if not re.match(r'^(0x)?[0-9]+$', token):
1361 1.1.1.1.8.2 tls raise RpcGenError('Expected tag number: \"%s\"' % entry)
1362 1.1.1.1.8.2 tls tag = int(token, 0)
1363 1.1.1.1.8.2 tls continue
1364 1.1.1.1.8.2 tls
1365 1.1.1.1.8.2 tls raise RpcGenError('Cannot parse \"%s\"' % entry)
1366 1.1.1.1.8.2 tls
1367 1.1.1.1.8.2 tls if not tag_set:
1368 1.1.1.1.8.2 tls raise RpcGenError('Need tag number: \"%s\"' % entry)
1369 1.1.1.1.8.2 tls
1370 1.1.1.1.8.2 tls # Create the right entry
1371 1.1.1.1.8.2 tls if entry_type == 'bytes':
1372 1.1.1.1.8.2 tls if fixed_length:
1373 1.1.1.1.8.2 tls newentry = factory.EntryBytes(entry_type, name, tag, fixed_length)
1374 1.1.1.1.8.2 tls else:
1375 1.1.1.1.8.2 tls newentry = factory.EntryVarBytes(entry_type, name, tag)
1376 1.1.1.1.8.2 tls elif entry_type == 'int' and not fixed_length:
1377 1.1.1.1.8.2 tls newentry = factory.EntryInt(entry_type, name, tag)
1378 1.1.1.1.8.2 tls elif entry_type == 'int64' and not fixed_length:
1379 1.1.1.1.8.2 tls newentry = factory.EntryInt(entry_type, name, tag, bits=64)
1380 1.1.1.1.8.2 tls elif entry_type == 'string' and not fixed_length:
1381 1.1.1.1.8.2 tls newentry = factory.EntryString(entry_type, name, tag)
1382 1.1.1.1.8.2 tls else:
1383 1.1.1.1.8.2 tls res = structref.match(entry_type)
1384 1.1.1.1.8.2 tls if res:
1385 1.1.1.1.8.2 tls # References another struct defined in our file
1386 1.1.1.1.8.2 tls newentry = factory.EntryStruct(entry_type, name, tag, res.group(1))
1387 1.1.1.1.8.2 tls else:
1388 1.1.1.1.8.2 tls raise RpcGenError('Bad type: "%s" in "%s"' % (entry_type, entry))
1389 1.1.1.1.8.2 tls
1390 1.1.1.1.8.2 tls structs = []
1391 1.1.1.1.8.2 tls
1392 1.1.1.1.8.2 tls if optional:
1393 1.1.1.1.8.2 tls newentry.MakeOptional()
1394 1.1.1.1.8.2 tls if array:
1395 1.1.1.1.8.2 tls newentry.MakeArray()
1396 1.1.1.1.8.2 tls
1397 1.1.1.1.8.2 tls newentry.SetStruct(newstruct)
1398 1.1.1.1.8.2 tls newentry.SetLineCount(line_count)
1399 1.1.1.1.8.2 tls newentry.Verify()
1400 1.1.1.1.8.2 tls
1401 1.1.1.1.8.2 tls if array:
1402 1.1.1.1.8.2 tls # We need to encapsulate this entry into a struct
1403 1.1.1.1.8.2 tls newname = newentry.Name()+ '_array'
1404 1.1.1.1.8.2 tls
1405 1.1.1.1.8.2 tls # Now borgify the new entry.
1406 1.1.1.1.8.2 tls newentry = factory.EntryArray(newentry)
1407 1.1.1.1.8.2 tls newentry.SetStruct(newstruct)
1408 1.1.1.1.8.2 tls newentry.SetLineCount(line_count)
1409 1.1.1.1.8.2 tls newentry.MakeArray()
1410 1.1.1.1.8.2 tls
1411 1.1.1.1.8.2 tls newstruct.AddEntry(newentry)
1412 1.1.1.1.8.2 tls
1413 1.1.1.1.8.2 tls return structs
1414 1.1.1.1.8.2 tls
1415 1.1.1.1.8.2 tls def ProcessStruct(factory, data):
1416 1.1.1.1.8.2 tls tokens = data.split(' ')
1417 1.1.1.1.8.2 tls
1418 1.1.1.1.8.2 tls # First three tokens are: 'struct' 'name' '{'
1419 1.1.1.1.8.2 tls newstruct = factory.Struct(tokens[1])
1420 1.1.1.1.8.2 tls
1421 1.1.1.1.8.2 tls inside = ' '.join(tokens[3:-1])
1422 1.1.1.1.8.2 tls
1423 1.1.1.1.8.2 tls tokens = inside.split(';')
1424 1.1.1.1.8.2 tls
1425 1.1.1.1.8.2 tls structs = []
1426 1.1.1.1.8.2 tls
1427 1.1.1.1.8.2 tls for entry in tokens:
1428 1.1.1.1.8.2 tls entry = NormalizeLine(entry)
1429 1.1.1.1.8.2 tls if not entry:
1430 1.1.1.1.8.2 tls continue
1431 1.1.1.1.8.2 tls
1432 1.1.1.1.8.2 tls # It's possible that new structs get defined in here
1433 1.1.1.1.8.2 tls structs.extend(ProcessOneEntry(factory, newstruct, entry))
1434 1.1.1.1.8.2 tls
1435 1.1.1.1.8.2 tls structs.append(newstruct)
1436 1.1.1.1.8.2 tls return structs
1437 1.1.1.1.8.2 tls
1438 1.1.1.1.8.2 tls def GetNextStruct(file):
1439 1.1.1.1.8.2 tls global line_count
1440 1.1.1.1.8.2 tls global cppdirect
1441 1.1.1.1.8.2 tls
1442 1.1.1.1.8.2 tls got_struct = 0
1443 1.1.1.1.8.2 tls
1444 1.1.1.1.8.2 tls processed_lines = []
1445 1.1.1.1.8.2 tls
1446 1.1.1.1.8.2 tls have_c_comment = 0
1447 1.1.1.1.8.2 tls data = ''
1448 1.1.1.1.8.2 tls while 1:
1449 1.1.1.1.8.2 tls line = file.readline()
1450 1.1.1.1.8.2 tls if not line:
1451 1.1.1.1.8.2 tls break
1452 1.1.1.1.8.2 tls
1453 1.1.1.1.8.2 tls line_count += 1
1454 1.1.1.1.8.2 tls line = line[:-1]
1455 1.1.1.1.8.2 tls
1456 1.1.1.1.8.2 tls if not have_c_comment and re.search(r'/\*', line):
1457 1.1.1.1.8.2 tls if re.search(r'/\*.*?\*/', line):
1458 1.1.1.1.8.2 tls line = re.sub(r'/\*.*?\*/', '', line)
1459 1.1.1.1.8.2 tls else:
1460 1.1.1.1.8.2 tls line = re.sub(r'/\*.*$', '', line)
1461 1.1.1.1.8.2 tls have_c_comment = 1
1462 1.1.1.1.8.2 tls
1463 1.1.1.1.8.2 tls if have_c_comment:
1464 1.1.1.1.8.2 tls if not re.search(r'\*/', line):
1465 1.1.1.1.8.2 tls continue
1466 1.1.1.1.8.2 tls have_c_comment = 0
1467 1.1.1.1.8.2 tls line = re.sub(r'^.*\*/', '', line)
1468 1.1.1.1.8.2 tls
1469 1.1.1.1.8.2 tls line = NormalizeLine(line)
1470 1.1.1.1.8.2 tls
1471 1.1.1.1.8.2 tls if not line:
1472 1.1.1.1.8.2 tls continue
1473 1.1.1.1.8.2 tls
1474 1.1.1.1.8.2 tls if not got_struct:
1475 1.1.1.1.8.2 tls if re.match(r'#include ["<].*[>"]', line):
1476 1.1.1.1.8.2 tls cppdirect.append(line)
1477 1.1.1.1.8.2 tls continue
1478 1.1.1.1.8.2 tls
1479 1.1.1.1.8.2 tls if re.match(r'^#(if( |def)|endif)', line):
1480 1.1.1.1.8.2 tls cppdirect.append(line)
1481 1.1.1.1.8.2 tls continue
1482 1.1.1.1.8.2 tls
1483 1.1.1.1.8.2 tls if re.match(r'^#define', line):
1484 1.1.1.1.8.2 tls headerdirect.append(line)
1485 1.1.1.1.8.2 tls continue
1486 1.1.1.1.8.2 tls
1487 1.1.1.1.8.2 tls if not structdef.match(line):
1488 1.1.1.1.8.2 tls raise RpcGenError('Missing struct on line %d: %s'
1489 1.1.1.1.8.2 tls % (line_count, line))
1490 1.1.1.1.8.2 tls else:
1491 1.1.1.1.8.2 tls got_struct = 1
1492 1.1.1.1.8.2 tls data += line
1493 1.1.1.1.8.2 tls continue
1494 1.1.1.1.8.2 tls
1495 1.1.1.1.8.2 tls # We are inside the struct
1496 1.1.1.1.8.2 tls tokens = line.split('}')
1497 1.1.1.1.8.2 tls if len(tokens) == 1:
1498 1.1.1.1.8.2 tls data += ' ' + line
1499 1.1.1.1.8.2 tls continue
1500 1.1.1.1.8.2 tls
1501 1.1.1.1.8.2 tls if len(tokens[1]):
1502 1.1.1.1.8.2 tls raise RpcGenError('Trailing garbage after struct on line %d'
1503 1.1.1.1.8.2 tls % line_count)
1504 1.1.1.1.8.2 tls
1505 1.1.1.1.8.2 tls # We found the end of the struct
1506 1.1.1.1.8.2 tls data += ' %s}' % tokens[0]
1507 1.1.1.1.8.2 tls break
1508 1.1.1.1.8.2 tls
1509 1.1.1.1.8.2 tls # Remove any comments, that might be in there
1510 1.1.1.1.8.2 tls data = re.sub(r'/\*.*\*/', '', data)
1511 1.1.1.1.8.2 tls
1512 1.1.1.1.8.2 tls return data
1513 1.1.1.1.8.2 tls
1514 1.1.1.1.8.2 tls
1515 1.1.1.1.8.2 tls def Parse(factory, file):
1516 1.1.1.1.8.2 tls """
1517 1.1.1.1.8.2 tls Parses the input file and returns C code and corresponding header file.
1518 1.1.1.1.8.2 tls """
1519 1.1.1.1.8.2 tls
1520 1.1.1.1.8.2 tls entities = []
1521 1.1.1.1.8.2 tls
1522 1.1.1.1.8.2 tls while 1:
1523 1.1.1.1.8.2 tls # Just gets the whole struct nicely formatted
1524 1.1.1.1.8.2 tls data = GetNextStruct(file)
1525 1.1.1.1.8.2 tls
1526 1.1.1.1.8.2 tls if not data:
1527 1.1.1.1.8.2 tls break
1528 1.1.1.1.8.2 tls
1529 1.1.1.1.8.2 tls entities.extend(ProcessStruct(factory, data))
1530 1.1.1.1.8.2 tls
1531 1.1.1.1.8.2 tls return entities
1532 1.1.1.1.8.2 tls
1533 1.1.1.1.8.2 tls class CCodeGenerator:
1534 1.1.1.1.8.2 tls def __init__(self):
1535 1.1.1.1.8.2 tls pass
1536 1.1.1.1.8.2 tls
1537 1.1.1.1.8.2 tls def GuardName(self, name):
1538 1.1.1.1.8.2 tls # Use the complete provided path to the input file, with all
1539 1.1.1.1.8.2 tls # non-identifier characters replaced with underscores, to
1540 1.1.1.1.8.2 tls # reduce the chance of a collision between guard macros.
1541 1.1.1.1.8.2 tls return 'EVENT_RPCOUT_' + nonident.sub('_', name).upper() + '_'
1542 1.1.1.1.8.2 tls
1543 1.1.1.1.8.2 tls def HeaderPreamble(self, name):
1544 1.1.1.1.8.2 tls guard = self.GuardName(name)
1545 1.1.1.1.8.2 tls pre = (
1546 1.1.1.1.8.2 tls '/*\n'
1547 1.1.1.1.8.2 tls ' * Automatically generated from %s\n'
1548 1.1.1.1.8.2 tls ' */\n\n'
1549 1.1.1.1.8.2 tls '#ifndef %s\n'
1550 1.1.1.1.8.2 tls '#define %s\n\n' ) % (
1551 1.1.1.1.8.2 tls name, guard, guard)
1552 1.1.1.1.8.2 tls
1553 1.1.1.1.8.2 tls for statement in headerdirect:
1554 1.1.1.1.8.2 tls pre += '%s\n' % statement
1555 1.1.1.1.8.2 tls if headerdirect:
1556 1.1.1.1.8.2 tls pre += '\n'
1557 1.1.1.1.8.2 tls
1558 1.1.1.1.8.2 tls pre += (
1559 1.1.1.1.8.2 tls '#include <event2/util.h> /* for ev_uint*_t */\n'
1560 1.1.1.1.8.2 tls '#include <event2/rpc.h>\n'
1561 1.1.1.1.8.2 tls )
1562 1.1.1.1.8.2 tls
1563 1.1.1.1.8.2 tls return pre
1564 1.1.1.1.8.2 tls
1565 1.1.1.1.8.2 tls def HeaderPostamble(self, name):
1566 1.1.1.1.8.2 tls guard = self.GuardName(name)
1567 1.1.1.1.8.2 tls return '#endif /* %s */' % guard
1568 1.1.1.1.8.2 tls
1569 1.1.1.1.8.2 tls def BodyPreamble(self, name, header_file):
1570 1.1.1.1.8.2 tls global _NAME
1571 1.1.1.1.8.2 tls global _VERSION
1572 1.1.1.1.8.2 tls
1573 1.1.1.1.8.2 tls slash = header_file.rfind('/')
1574 1.1.1.1.8.2 tls if slash != -1:
1575 1.1.1.1.8.2 tls header_file = header_file[slash+1:]
1576 1.1.1.1.8.2 tls
1577 1.1.1.1.8.2 tls pre = ( '/*\n'
1578 1.1.1.1.8.2 tls ' * Automatically generated from %s\n'
1579 1.1.1.1.8.2 tls ' * by %s/%s. DO NOT EDIT THIS FILE.\n'
1580 1.1.1.1.8.2 tls ' */\n\n' ) % (name, _NAME, _VERSION)
1581 1.1.1.1.8.2 tls pre += ( '#include <stdlib.h>\n'
1582 1.1.1.1.8.2 tls '#include <string.h>\n'
1583 1.1.1.1.8.2 tls '#include <assert.h>\n'
1584 1.1.1.1.8.2 tls '#include <event2/event-config.h>\n'
1585 1.1.1.1.8.2 tls '#include <event2/event.h>\n'
1586 1.1.1.1.8.2 tls '#include <event2/buffer.h>\n'
1587 1.1.1.1.8.2 tls '#include <event2/tag.h>\n\n'
1588 1.1.1.1.8.2 tls '#ifdef EVENT____func__\n'
1589 1.1.1.1.8.2 tls '#define __func__ EVENT____func__\n'
1590 1.1.1.1.8.2 tls '#endif\n\n'
1591 1.1.1.1.8.2 tls )
1592 1.1.1.1.8.2 tls
1593 1.1.1.1.8.2 tls for statement in cppdirect:
1594 1.1.1.1.8.2 tls pre += '%s\n' % statement
1595 1.1.1.1.8.2 tls
1596 1.1.1.1.8.2 tls pre += '\n#include "%s"\n\n' % header_file
1597 1.1.1.1.8.2 tls
1598 1.1.1.1.8.2 tls pre += 'void event_warn(const char *fmt, ...);\n'
1599 1.1.1.1.8.2 tls pre += 'void event_warnx(const char *fmt, ...);\n\n'
1600 1.1.1.1.8.2 tls
1601 1.1.1.1.8.2 tls return pre
1602 1.1.1.1.8.2 tls
1603 1.1.1.1.8.2 tls def HeaderFilename(self, filename):
1604 1.1.1.1.8.2 tls return '.'.join(filename.split('.')[:-1]) + '.h'
1605 1.1.1.1.8.2 tls
1606 1.1.1.1.8.2 tls def CodeFilename(self, filename):
1607 1.1.1.1.8.2 tls return '.'.join(filename.split('.')[:-1]) + '.gen.c'
1608 1.1.1.1.8.2 tls
1609 1.1.1.1.8.2 tls def Struct(self, name):
1610 1.1.1.1.8.2 tls return StructCCode(name)
1611 1.1.1.1.8.2 tls
1612 1.1.1.1.8.2 tls def EntryBytes(self, entry_type, name, tag, fixed_length):
1613 1.1.1.1.8.2 tls return EntryBytes(entry_type, name, tag, fixed_length)
1614 1.1.1.1.8.2 tls
1615 1.1.1.1.8.2 tls def EntryVarBytes(self, entry_type, name, tag):
1616 1.1.1.1.8.2 tls return EntryVarBytes(entry_type, name, tag)
1617 1.1.1.1.8.2 tls
1618 1.1.1.1.8.2 tls def EntryInt(self, entry_type, name, tag, bits=32):
1619 1.1.1.1.8.2 tls return EntryInt(entry_type, name, tag, bits)
1620 1.1.1.1.8.2 tls
1621 1.1.1.1.8.2 tls def EntryString(self, entry_type, name, tag):
1622 1.1.1.1.8.2 tls return EntryString(entry_type, name, tag)
1623 1.1.1.1.8.2 tls
1624 1.1.1.1.8.2 tls def EntryStruct(self, entry_type, name, tag, struct_name):
1625 1.1.1.1.8.2 tls return EntryStruct(entry_type, name, tag, struct_name)
1626 1.1.1.1.8.2 tls
1627 1.1.1.1.8.2 tls def EntryArray(self, entry):
1628 1.1.1.1.8.2 tls return EntryArray(entry)
1629 1.1.1.1.8.2 tls
1630 1.1.1.1.8.2 tls class Usage(RpcGenError):
1631 1.1.1.1.8.2 tls def __init__(self, argv0):
1632 1.1.1.1.8.2 tls RpcGenError.__init__("usage: %s input.rpc [[output.h] output.c]"
1633 1.1.1.1.8.2 tls % argv0)
1634 1.1.1.1.8.2 tls
1635 1.1.1.1.8.2 tls class CommandLine:
1636 1.1.1.1.8.2 tls def __init__(self, argv):
1637 1.1.1.1.8.2 tls """Initialize a command-line to launch event_rpcgen, as if
1638 1.1.1.1.8.2 tls from a command-line with CommandLine(sys.argv). If you're
1639 1.1.1.1.8.2 tls calling this directly, remember to provide a dummy value
1640 1.1.1.1.8.2 tls for sys.argv[0]
1641 1.1.1.1.8.2 tls """
1642 1.1.1.1.8.2 tls self.filename = None
1643 1.1.1.1.8.2 tls self.header_file = None
1644 1.1.1.1.8.2 tls self.impl_file = None
1645 1.1.1.1.8.2 tls self.factory = CCodeGenerator()
1646 1.1.1.1.8.2 tls
1647 1.1.1.1.8.2 tls if len(argv) >= 2 and argv[1] == '--quiet':
1648 1.1.1.1.8.2 tls global QUIETLY
1649 1.1.1.1.8.2 tls QUIETLY = 1
1650 1.1.1.1.8.2 tls del argv[1]
1651 1.1.1.1.8.2 tls
1652 1.1.1.1.8.2 tls if len(argv) < 2 or len(argv) > 4:
1653 1.1.1.1.8.2 tls raise Usage(argv[0])
1654 1.1.1.1.8.2 tls
1655 1.1.1.1.8.2 tls self.filename = argv[1].replace('\\', '/')
1656 1.1.1.1.8.2 tls if len(argv) == 3:
1657 1.1.1.1.8.2 tls self.impl_file = argv[2].replace('\\', '/')
1658 1.1.1.1.8.2 tls if len(argv) == 4:
1659 1.1.1.1.8.2 tls self.header_file = argv[2].replace('\\', '/')
1660 1.1.1.1.8.2 tls self.impl_file = argv[3].replace('\\', '/')
1661 1.1.1.1.8.2 tls
1662 1.1.1.1.8.2 tls if not self.filename:
1663 1.1.1.1.8.2 tls raise Usage(argv[0])
1664 1.1.1.1.8.2 tls
1665 1.1.1.1.8.2 tls if not self.impl_file:
1666 1.1.1.1.8.2 tls self.impl_file = self.factory.CodeFilename(self.filename)
1667 1.1.1.1.8.2 tls
1668 1.1.1.1.8.2 tls if not self.header_file:
1669 1.1.1.1.8.2 tls self.header_file = self.factory.HeaderFilename(self.impl_file)
1670 1.1.1.1.8.2 tls
1671 1.1.1.1.8.2 tls if not self.impl_file.endswith('.c'):
1672 1.1.1.1.8.2 tls raise RpcGenError("can only generate C implementation files")
1673 1.1.1.1.8.2 tls if not self.header_file.endswith('.h'):
1674 1.1.1.1.8.2 tls raise RpcGenError("can only generate C header files")
1675 1.1.1.1.8.2 tls
1676 1.1.1.1.8.2 tls def run(self):
1677 1.1.1.1.8.2 tls filename = self.filename
1678 1.1.1.1.8.2 tls header_file = self.header_file
1679 1.1.1.1.8.2 tls impl_file = self.impl_file
1680 1.1.1.1.8.2 tls factory = self.factory
1681 1.1.1.1.8.2 tls
1682 1.1.1.1.8.2 tls declare('Reading \"%s\"' % filename)
1683 1.1.1.1.8.2 tls
1684 1.1.1.1.8.2 tls fp = open(filename, 'r')
1685 1.1.1.1.8.2 tls entities = Parse(factory, fp)
1686 1.1.1.1.8.2 tls fp.close()
1687 1.1.1.1.8.2 tls
1688 1.1.1.1.8.2 tls declare('... creating "%s"' % header_file)
1689 1.1.1.1.8.2 tls header_fp = open(header_file, 'w')
1690 1.1.1.1.8.2 tls print >>header_fp, factory.HeaderPreamble(filename)
1691 1.1.1.1.8.2 tls
1692 1.1.1.1.8.2 tls # Create forward declarations: allows other structs to reference
1693 1.1.1.1.8.2 tls # each other
1694 1.1.1.1.8.2 tls for entry in entities:
1695 1.1.1.1.8.2 tls entry.PrintForwardDeclaration(header_fp)
1696 1.1.1.1.8.2 tls print >>header_fp, ''
1697 1.1.1.1.8.2 tls
1698 1.1.1.1.8.2 tls for entry in entities:
1699 1.1.1.1.8.2 tls entry.PrintTags(header_fp)
1700 1.1.1.1.8.2 tls entry.PrintDeclaration(header_fp)
1701 1.1.1.1.8.2 tls print >>header_fp, factory.HeaderPostamble(filename)
1702 1.1.1.1.8.2 tls header_fp.close()
1703 1.1.1.1.8.2 tls
1704 1.1.1.1.8.2 tls declare('... creating "%s"' % impl_file)
1705 1.1.1.1.8.2 tls impl_fp = open(impl_file, 'w')
1706 1.1.1.1.8.2 tls print >>impl_fp, factory.BodyPreamble(filename, header_file)
1707 1.1.1.1.8.2 tls for entry in entities:
1708 1.1.1.1.8.2 tls entry.PrintCode(impl_fp)
1709 1.1.1.1.8.2 tls impl_fp.close()
1710 1.1.1.1.8.2 tls
1711 1.1.1.1.8.2 tls if __name__ == '__main__':
1712 1.1.1.1.8.2 tls try:
1713 1.1.1.1.8.2 tls CommandLine(sys.argv).run()
1714 1.1.1.1.8.2 tls sys.exit(0)
1715 1.1.1.1.8.2 tls
1716 1.1.1.1.8.2 tls except RpcGenError, e:
1717 1.1.1.1.8.2 tls print >>sys.stderr, e
1718 1.1.1.1.8.2 tls sys.exit(1)
1719 1.1.1.1.8.2 tls
1720 1.1.1.1.8.2 tls except EnvironmentError, e:
1721 1.1.1.1.8.2 tls if e.filename and e.strerror:
1722 1.1.1.1.8.2 tls print >>sys.stderr, "%s: %s" % (e.filename, e.strerror)
1723 1.1.1.1.8.2 tls sys.exit(1)
1724 1.1.1.1.8.2 tls elif e.strerror:
1725 1.1.1.1.8.2 tls print >> sys.stderr, e.strerror
1726 1.1.1.1.8.2 tls sys.exit(1)
1727 1.1.1.1.8.2 tls else:
1728 1.1.1.1.8.2 tls raise
1729