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