blob: 0bae3b0fe662ad934a8c968c78c52e6cffd0eafc [file] [log] [blame]
Haibo Huangb2279672019-05-31 16:12:39 -07001#!/usr/bin/env python
Christopher Wileye8679812015-07-01 13:36:18 -07002#
3# Copyright (c) 2005-2007 Niels Provos <provos@citi.umich.edu>
4# Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
5# All rights reserved.
6#
7# Generates marshaling code based on libevent.
8
Haibo Huangf0077b82020-07-10 20:21:19 -07009# pylint: disable=too-many-lines
10# pylint: disable=too-many-branches
11# pylint: disable=too-many-public-methods
12# pylint: disable=too-many-statements
13# pylint: disable=global-statement
Christopher Wileye8679812015-07-01 13:36:18 -070014
Haibo Huangf0077b82020-07-10 20:21:19 -070015# TODO:
16# 1) propagate the arguments/options parsed by argparse down to the
17# instantiated factory objects.
18# 2) move the globals into a class that manages execution, including the
19# progress outputs that go to stderr at the moment.
20# 3) emit other languages.
21
22import argparse
Christopher Wileye8679812015-07-01 13:36:18 -070023import re
Haibo Huangf0077b82020-07-10 20:21:19 -070024import sys
Christopher Wileye8679812015-07-01 13:36:18 -070025
26_NAME = "event_rpcgen.py"
27_VERSION = "0.1"
28
29# Globals
Haibo Huangf0077b82020-07-10 20:21:19 -070030LINE_COUNT = 0
Christopher Wileye8679812015-07-01 13:36:18 -070031
Haibo Huangf0077b82020-07-10 20:21:19 -070032CPPCOMMENT_RE = re.compile(r"\/\/.*$")
33NONIDENT_RE = re.compile(r"\W")
34PREPROCESSOR_DEF_RE = re.compile(r"^#define")
35STRUCT_REF_RE = re.compile(r"^struct\[(?P<name>[a-zA-Z_][a-zA-Z0-9_]*)\]$")
36STRUCT_DEF_RE = re.compile(r"^struct +[a-zA-Z_][a-zA-Z0-9_]* *{$")
37WHITESPACE_RE = re.compile(r"\s+")
Christopher Wileye8679812015-07-01 13:36:18 -070038
Haibo Huangf0077b82020-07-10 20:21:19 -070039HEADER_DIRECT = []
40CPP_DIRECT = []
Christopher Wileye8679812015-07-01 13:36:18 -070041
Haibo Huangf0077b82020-07-10 20:21:19 -070042QUIETLY = False
43
Narayan Kamathfc74cb42017-09-13 12:53:52 +010044
45def declare(s):
46 if not QUIETLY:
Haibo Huangb2279672019-05-31 16:12:39 -070047 print(s)
Narayan Kamathfc74cb42017-09-13 12:53:52 +010048
Haibo Huangf0077b82020-07-10 20:21:19 -070049
Christopher Wileye8679812015-07-01 13:36:18 -070050def TranslateList(mylist, mydict):
Haibo Huangb2279672019-05-31 16:12:39 -070051 return [x % mydict for x in mylist]
Christopher Wileye8679812015-07-01 13:36:18 -070052
Haibo Huangf0077b82020-07-10 20:21:19 -070053
Christopher Wileye8679812015-07-01 13:36:18 -070054class RpcGenError(Exception):
Haibo Huangf0077b82020-07-10 20:21:19 -070055 """An Exception class for parse errors."""
56
57 def __init__(self, why): # pylint: disable=super-init-not-called
58 self.why = why
59
60 def __str__(self):
61 return str(self.why)
62
Christopher Wileye8679812015-07-01 13:36:18 -070063
64# Holds everything that makes a struct
Haibo Huangf0077b82020-07-10 20:21:19 -070065class Struct(object):
Christopher Wileye8679812015-07-01 13:36:18 -070066 def __init__(self, name):
67 self._name = name
68 self._entries = []
69 self._tags = {}
Haibo Huangf0077b82020-07-10 20:21:19 -070070 declare(" Created struct: %s" % name)
Christopher Wileye8679812015-07-01 13:36:18 -070071
72 def AddEntry(self, entry):
Haibo Huangb2279672019-05-31 16:12:39 -070073 if entry.Tag() in self._tags:
Christopher Wileye8679812015-07-01 13:36:18 -070074 raise RpcGenError(
75 'Entry "%s" duplicates tag number %d from "%s" '
Haibo Huangf0077b82020-07-10 20:21:19 -070076 "around line %d"
77 % (entry.Name(), entry.Tag(), self._tags[entry.Tag()], LINE_COUNT)
78 )
Christopher Wileye8679812015-07-01 13:36:18 -070079 self._entries.append(entry)
80 self._tags[entry.Tag()] = entry.Name()
Haibo Huangf0077b82020-07-10 20:21:19 -070081 declare(" Added entry: %s" % entry.Name())
Christopher Wileye8679812015-07-01 13:36:18 -070082
83 def Name(self):
84 return self._name
85
86 def EntryTagName(self, entry):
87 """Creates the name inside an enumeration for distinguishing data
88 types."""
89 name = "%s_%s" % (self._name, entry.Name())
90 return name.upper()
91
Haibo Huangf0077b82020-07-10 20:21:19 -070092 @staticmethod
93 def PrintIndented(filep, ident, code):
Christopher Wileye8679812015-07-01 13:36:18 -070094 """Takes an array, add indentation to each entry and prints it."""
95 for entry in code:
Haibo Huangf0077b82020-07-10 20:21:19 -070096 filep.write("%s%s\n" % (ident, entry))
97
Christopher Wileye8679812015-07-01 13:36:18 -070098
99class StructCCode(Struct):
100 """ Knows how to generate C code for a struct """
101
102 def __init__(self, name):
103 Struct.__init__(self, name)
104
Haibo Huangf0077b82020-07-10 20:21:19 -0700105 def PrintTags(self, filep):
Christopher Wileye8679812015-07-01 13:36:18 -0700106 """Prints the tag definitions for a structure."""
Haibo Huangf0077b82020-07-10 20:21:19 -0700107 filep.write("/* Tag definition for %s */\n" % self._name)
108 filep.write("enum %s_ {\n" % self._name.lower())
Christopher Wileye8679812015-07-01 13:36:18 -0700109 for entry in self._entries:
Haibo Huangf0077b82020-07-10 20:21:19 -0700110 filep.write(" %s=%d,\n" % (self.EntryTagName(entry), entry.Tag()))
111 filep.write(" %s_MAX_TAGS\n" % (self._name.upper()))
112 filep.write("};\n\n")
Christopher Wileye8679812015-07-01 13:36:18 -0700113
Haibo Huangf0077b82020-07-10 20:21:19 -0700114 def PrintForwardDeclaration(self, filep):
115 filep.write("struct %s;\n" % self._name)
Christopher Wileye8679812015-07-01 13:36:18 -0700116
Haibo Huangf0077b82020-07-10 20:21:19 -0700117 def PrintDeclaration(self, filep):
118 filep.write("/* Structure declaration for %s */\n" % self._name)
119 filep.write("struct %s_access_ {\n" % self._name)
Christopher Wileye8679812015-07-01 13:36:18 -0700120 for entry in self._entries:
Haibo Huangf0077b82020-07-10 20:21:19 -0700121 dcl = entry.AssignDeclaration("(*%s_assign)" % entry.Name())
122 dcl.extend(entry.GetDeclaration("(*%s_get)" % entry.Name()))
Christopher Wileye8679812015-07-01 13:36:18 -0700123 if entry.Array():
Haibo Huangf0077b82020-07-10 20:21:19 -0700124 dcl.extend(entry.AddDeclaration("(*%s_add)" % entry.Name()))
125 self.PrintIndented(filep, " ", dcl)
126 filep.write("};\n\n")
Christopher Wileye8679812015-07-01 13:36:18 -0700127
Haibo Huangf0077b82020-07-10 20:21:19 -0700128 filep.write("struct %s {\n" % self._name)
129 filep.write(" struct %s_access_ *base;\n\n" % self._name)
Christopher Wileye8679812015-07-01 13:36:18 -0700130 for entry in self._entries:
131 dcl = entry.Declaration()
Haibo Huangf0077b82020-07-10 20:21:19 -0700132 self.PrintIndented(filep, " ", dcl)
133 filep.write("\n")
Christopher Wileye8679812015-07-01 13:36:18 -0700134 for entry in self._entries:
Haibo Huangf0077b82020-07-10 20:21:19 -0700135 filep.write(" ev_uint8_t %s_set;\n" % entry.Name())
136 filep.write("};\n\n")
Christopher Wileye8679812015-07-01 13:36:18 -0700137
Haibo Huangf0077b82020-07-10 20:21:19 -0700138 filep.write(
139 """struct %(name)s *%(name)s_new(void);
Christopher Wileye8679812015-07-01 13:36:18 -0700140struct %(name)s *%(name)s_new_with_arg(void *);
141void %(name)s_free(struct %(name)s *);
142void %(name)s_clear(struct %(name)s *);
143void %(name)s_marshal(struct evbuffer *, const struct %(name)s *);
144int %(name)s_unmarshal(struct %(name)s *, struct evbuffer *);
145int %(name)s_complete(struct %(name)s *);
146void evtag_marshal_%(name)s(struct evbuffer *, ev_uint32_t,
147 const struct %(name)s *);
148int evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t,
Haibo Huangf0077b82020-07-10 20:21:19 -0700149 struct %(name)s *);\n"""
150 % {"name": self._name}
151 )
Christopher Wileye8679812015-07-01 13:36:18 -0700152
153 # Write a setting function of every variable
154 for entry in self._entries:
Haibo Huangf0077b82020-07-10 20:21:19 -0700155 self.PrintIndented(
156 filep, "", entry.AssignDeclaration(entry.AssignFuncName())
157 )
158 self.PrintIndented(filep, "", entry.GetDeclaration(entry.GetFuncName()))
Christopher Wileye8679812015-07-01 13:36:18 -0700159 if entry.Array():
Haibo Huangf0077b82020-07-10 20:21:19 -0700160 self.PrintIndented(filep, "", entry.AddDeclaration(entry.AddFuncName()))
Christopher Wileye8679812015-07-01 13:36:18 -0700161
Haibo Huangf0077b82020-07-10 20:21:19 -0700162 filep.write("/* --- %s done --- */\n\n" % self._name)
Christopher Wileye8679812015-07-01 13:36:18 -0700163
Haibo Huangf0077b82020-07-10 20:21:19 -0700164 def PrintCode(self, filep):
165 filep.write(
166 """/*
167 * Implementation of %s
168 */
169"""
170 % (self._name)
171 )
Christopher Wileye8679812015-07-01 13:36:18 -0700172
Haibo Huangf0077b82020-07-10 20:21:19 -0700173 filep.write(
174 """
175static struct %(name)s_access_ %(name)s_base__ = {
176"""
177 % {"name": self._name}
178 )
Christopher Wileye8679812015-07-01 13:36:18 -0700179 for entry in self._entries:
Haibo Huangf0077b82020-07-10 20:21:19 -0700180 self.PrintIndented(filep, " ", entry.CodeBase())
181 filep.write("};\n\n")
Christopher Wileye8679812015-07-01 13:36:18 -0700182
183 # Creation
Haibo Huangf0077b82020-07-10 20:21:19 -0700184 filep.write(
185 """struct %(name)s *
186%(name)s_new(void)
187{
188 return %(name)s_new_with_arg(NULL);
189}
190
191struct %(name)s *
192%(name)s_new_with_arg(void *unused)
193{
194 struct %(name)s *tmp;
195 if ((tmp = malloc(sizeof(struct %(name)s))) == NULL) {
196 event_warn("%%s: malloc", __func__);
197 return (NULL);
198 }
199 tmp->base = &%(name)s_base__;
200
201"""
202 % {"name": self._name}
203 )
Christopher Wileye8679812015-07-01 13:36:18 -0700204
205 for entry in self._entries:
Haibo Huangf0077b82020-07-10 20:21:19 -0700206 self.PrintIndented(filep, " ", entry.CodeInitialize("tmp"))
207 filep.write(" tmp->%s_set = 0;\n\n" % entry.Name())
Christopher Wileye8679812015-07-01 13:36:18 -0700208
Haibo Huangf0077b82020-07-10 20:21:19 -0700209 filep.write(
210 """ return (tmp);
211}
212
213"""
214 )
Christopher Wileye8679812015-07-01 13:36:18 -0700215
216 # Adding
217 for entry in self._entries:
218 if entry.Array():
Haibo Huangf0077b82020-07-10 20:21:19 -0700219 self.PrintIndented(filep, "", entry.CodeAdd())
220 filep.write("\n")
Christopher Wileye8679812015-07-01 13:36:18 -0700221
222 # Assigning
223 for entry in self._entries:
Haibo Huangf0077b82020-07-10 20:21:19 -0700224 self.PrintIndented(filep, "", entry.CodeAssign())
225 filep.write("\n")
Christopher Wileye8679812015-07-01 13:36:18 -0700226
227 # Getting
228 for entry in self._entries:
Haibo Huangf0077b82020-07-10 20:21:19 -0700229 self.PrintIndented(filep, "", entry.CodeGet())
230 filep.write("\n")
Christopher Wileye8679812015-07-01 13:36:18 -0700231
232 # Clearing
Haibo Huangf0077b82020-07-10 20:21:19 -0700233 filep.write(
234 """void
235%(name)s_clear(struct %(name)s *tmp)
236{
237"""
238 % {"name": self._name}
239 )
Christopher Wileye8679812015-07-01 13:36:18 -0700240 for entry in self._entries:
Haibo Huangf0077b82020-07-10 20:21:19 -0700241 self.PrintIndented(filep, " ", entry.CodeClear("tmp"))
Christopher Wileye8679812015-07-01 13:36:18 -0700242
Haibo Huangf0077b82020-07-10 20:21:19 -0700243 filep.write("}\n\n")
Christopher Wileye8679812015-07-01 13:36:18 -0700244
245 # Freeing
Haibo Huangf0077b82020-07-10 20:21:19 -0700246 filep.write(
247 """void
248%(name)s_free(struct %(name)s *tmp)
249{
250"""
251 % {"name": self._name}
252 )
Christopher Wileye8679812015-07-01 13:36:18 -0700253
254 for entry in self._entries:
Haibo Huangf0077b82020-07-10 20:21:19 -0700255 self.PrintIndented(filep, " ", entry.CodeFree("tmp"))
Christopher Wileye8679812015-07-01 13:36:18 -0700256
Haibo Huangf0077b82020-07-10 20:21:19 -0700257 filep.write(
258 """ free(tmp);
259}
260
261"""
262 )
Christopher Wileye8679812015-07-01 13:36:18 -0700263
264 # Marshaling
Haibo Huangf0077b82020-07-10 20:21:19 -0700265 filep.write(
266 """void
267%(name)s_marshal(struct evbuffer *evbuf, const struct %(name)s *tmp) {
268"""
269 % {"name": self._name}
270 )
Christopher Wileye8679812015-07-01 13:36:18 -0700271 for entry in self._entries:
Haibo Huangf0077b82020-07-10 20:21:19 -0700272 indent = " "
Christopher Wileye8679812015-07-01 13:36:18 -0700273 # Optional entries do not have to be set
274 if entry.Optional():
Haibo Huangf0077b82020-07-10 20:21:19 -0700275 indent += " "
276 filep.write(" if (tmp->%s_set) {\n" % entry.Name())
Christopher Wileye8679812015-07-01 13:36:18 -0700277 self.PrintIndented(
Haibo Huangf0077b82020-07-10 20:21:19 -0700278 filep,
279 indent,
280 entry.CodeMarshal(
281 "evbuf",
282 self.EntryTagName(entry),
283 entry.GetVarName("tmp"),
284 entry.GetVarLen("tmp"),
285 ),
286 )
Christopher Wileye8679812015-07-01 13:36:18 -0700287 if entry.Optional():
Haibo Huangf0077b82020-07-10 20:21:19 -0700288 filep.write(" }\n")
Christopher Wileye8679812015-07-01 13:36:18 -0700289
Haibo Huangf0077b82020-07-10 20:21:19 -0700290 filep.write("}\n\n")
Christopher Wileye8679812015-07-01 13:36:18 -0700291
292 # Unmarshaling
Haibo Huangf0077b82020-07-10 20:21:19 -0700293 filep.write(
294 """int
295%(name)s_unmarshal(struct %(name)s *tmp, struct evbuffer *evbuf)
296{
297 ev_uint32_t tag;
298 while (evbuffer_get_length(evbuf) > 0) {
299 if (evtag_peek(evbuf, &tag) == -1)
300 return (-1);
301 switch (tag) {
302
303"""
304 % {"name": self._name}
305 )
Christopher Wileye8679812015-07-01 13:36:18 -0700306 for entry in self._entries:
Haibo Huangf0077b82020-07-10 20:21:19 -0700307 filep.write(" case %s:\n" % (self.EntryTagName(entry)))
Christopher Wileye8679812015-07-01 13:36:18 -0700308 if not entry.Array():
Haibo Huangf0077b82020-07-10 20:21:19 -0700309 filep.write(
310 """ if (tmp->%s_set)
311 return (-1);
312"""
313 % (entry.Name())
314 )
Christopher Wileye8679812015-07-01 13:36:18 -0700315
316 self.PrintIndented(
Haibo Huangf0077b82020-07-10 20:21:19 -0700317 filep,
318 " ",
319 entry.CodeUnmarshal(
320 "evbuf",
321 self.EntryTagName(entry),
322 entry.GetVarName("tmp"),
323 entry.GetVarLen("tmp"),
324 ),
325 )
Christopher Wileye8679812015-07-01 13:36:18 -0700326
Haibo Huangf0077b82020-07-10 20:21:19 -0700327 filep.write(
328 """ tmp->%s_set = 1;
329 break;
330"""
331 % (entry.Name())
332 )
333 filep.write(
334 """ default:
335 return -1;
336 }
337 }
338
339"""
340 )
Christopher Wileye8679812015-07-01 13:36:18 -0700341 # Check if it was decoded completely
Haibo Huangf0077b82020-07-10 20:21:19 -0700342 filep.write(
343 """ if (%(name)s_complete(tmp) == -1)
344 return (-1);
345 return (0);
346}
347"""
348 % {"name": self._name}
349 )
Christopher Wileye8679812015-07-01 13:36:18 -0700350
351 # Checking if a structure has all the required data
Haibo Huangf0077b82020-07-10 20:21:19 -0700352 filep.write(
353 """
354int
355%(name)s_complete(struct %(name)s *msg)
356{
357"""
358 % {"name": self._name}
359 )
Christopher Wileye8679812015-07-01 13:36:18 -0700360 for entry in self._entries:
361 if not entry.Optional():
362 code = [
Haibo Huangf0077b82020-07-10 20:21:19 -0700363 """if (!msg->%(name)s_set)
364 return (-1);"""
365 ]
Christopher Wileye8679812015-07-01 13:36:18 -0700366 code = TranslateList(code, entry.GetTranslation())
Haibo Huangf0077b82020-07-10 20:21:19 -0700367 self.PrintIndented(filep, " ", code)
Christopher Wileye8679812015-07-01 13:36:18 -0700368
369 self.PrintIndented(
Haibo Huangf0077b82020-07-10 20:21:19 -0700370 filep, " ", entry.CodeComplete("msg", entry.GetVarName("msg"))
371 )
372 filep.write(
373 """ return (0);
374}
375"""
376 )
Christopher Wileye8679812015-07-01 13:36:18 -0700377
378 # Complete message unmarshaling
Haibo Huangf0077b82020-07-10 20:21:19 -0700379 filep.write(
380 """
381int
382evtag_unmarshal_%(name)s(struct evbuffer *evbuf, ev_uint32_t need_tag,
383 struct %(name)s *msg)
384{
385 ev_uint32_t tag;
386 int res = -1;
387
388 struct evbuffer *tmp = evbuffer_new();
389
390 if (evtag_unmarshal(evbuf, &tag, tmp) == -1 || tag != need_tag)
391 goto error;
392
393 if (%(name)s_unmarshal(msg, tmp) == -1)
394 goto error;
395
396 res = 0;
397
398 error:
399 evbuffer_free(tmp);
400 return (res);
401}
402"""
403 % {"name": self._name}
404 )
Christopher Wileye8679812015-07-01 13:36:18 -0700405
406 # Complete message marshaling
Haibo Huangf0077b82020-07-10 20:21:19 -0700407 filep.write(
408 """
409void
410evtag_marshal_%(name)s(struct evbuffer *evbuf, ev_uint32_t tag,
411 const struct %(name)s *msg)
412{
413 struct evbuffer *buf_ = evbuffer_new();
414 assert(buf_ != NULL);
415 %(name)s_marshal(buf_, msg);
416 evtag_marshal_buffer(evbuf, tag, buf_);
417 evbuffer_free(buf_);
418}
Christopher Wileye8679812015-07-01 13:36:18 -0700419
Haibo Huangf0077b82020-07-10 20:21:19 -0700420"""
421 % {"name": self._name}
422 )
423
424
425class Entry(object):
426 def __init__(self, ent_type, name, tag):
427 self._type = ent_type
Christopher Wileye8679812015-07-01 13:36:18 -0700428 self._name = name
429 self._tag = int(tag)
Haibo Huangf0077b82020-07-10 20:21:19 -0700430 self._ctype = ent_type
431 self._optional = False
432 self._can_be_array = False
433 self._array = False
Christopher Wileye8679812015-07-01 13:36:18 -0700434 self._line_count = -1
435 self._struct = None
436 self._refname = None
437
438 self._optpointer = True
439 self._optaddarg = True
440
Haibo Huangf0077b82020-07-10 20:21:19 -0700441 @staticmethod
442 def GetInitializer():
443 raise NotImplementedError("Entry does not provide an initializer")
Christopher Wileye8679812015-07-01 13:36:18 -0700444
445 def SetStruct(self, struct):
446 self._struct = struct
447
448 def LineCount(self):
449 assert self._line_count != -1
450 return self._line_count
451
452 def SetLineCount(self, number):
453 self._line_count = number
454
455 def Array(self):
456 return self._array
457
458 def Optional(self):
459 return self._optional
460
461 def Tag(self):
462 return self._tag
463
464 def Name(self):
465 return self._name
466
467 def Type(self):
468 return self._type
469
Haibo Huangf0077b82020-07-10 20:21:19 -0700470 def MakeArray(self):
471 self._array = True
Christopher Wileye8679812015-07-01 13:36:18 -0700472
473 def MakeOptional(self):
Haibo Huangf0077b82020-07-10 20:21:19 -0700474 self._optional = True
Christopher Wileye8679812015-07-01 13:36:18 -0700475
476 def Verify(self):
477 if self.Array() and not self._can_be_array:
478 raise RpcGenError(
479 'Entry "%s" cannot be created as an array '
Haibo Huangf0077b82020-07-10 20:21:19 -0700480 "around line %d" % (self._name, self.LineCount())
481 )
Christopher Wileye8679812015-07-01 13:36:18 -0700482 if not self._struct:
483 raise RpcGenError(
484 'Entry "%s" does not know which struct it belongs to '
Haibo Huangf0077b82020-07-10 20:21:19 -0700485 "around line %d" % (self._name, self.LineCount())
486 )
Christopher Wileye8679812015-07-01 13:36:18 -0700487 if self._optional and self._array:
488 raise RpcGenError(
489 'Entry "%s" has illegal combination of optional and array '
Haibo Huangf0077b82020-07-10 20:21:19 -0700490 "around line %d" % (self._name, self.LineCount())
491 )
Christopher Wileye8679812015-07-01 13:36:18 -0700492
Haibo Huangf0077b82020-07-10 20:21:19 -0700493 def GetTranslation(self, extradict=None):
494 if extradict is None:
495 extradict = {}
Christopher Wileye8679812015-07-01 13:36:18 -0700496 mapping = {
Haibo Huangf0077b82020-07-10 20:21:19 -0700497 "parent_name": self._struct.Name(),
498 "name": self._name,
499 "ctype": self._ctype,
500 "refname": self._refname,
501 "optpointer": self._optpointer and "*" or "",
502 "optreference": self._optpointer and "&" or "",
503 "optaddarg": self._optaddarg and ", const %s value" % self._ctype or "",
504 }
Haibo Huangb2279672019-05-31 16:12:39 -0700505 for (k, v) in list(extradict.items()):
Christopher Wileye8679812015-07-01 13:36:18 -0700506 mapping[k] = v
507
508 return mapping
509
510 def GetVarName(self, var):
Haibo Huangf0077b82020-07-10 20:21:19 -0700511 return "%(var)s->%(name)s_data" % self.GetTranslation({"var": var})
Christopher Wileye8679812015-07-01 13:36:18 -0700512
Haibo Huangf0077b82020-07-10 20:21:19 -0700513 def GetVarLen(self, _var):
514 return "sizeof(%s)" % self._ctype
Christopher Wileye8679812015-07-01 13:36:18 -0700515
516 def GetFuncName(self):
Haibo Huangf0077b82020-07-10 20:21:19 -0700517 return "%s_%s_get" % (self._struct.Name(), self._name)
Christopher Wileye8679812015-07-01 13:36:18 -0700518
519 def GetDeclaration(self, funcname):
Haibo Huangf0077b82020-07-10 20:21:19 -0700520 code = [
521 "int %s(struct %s *, %s *);" % (funcname, self._struct.Name(), self._ctype)
522 ]
Christopher Wileye8679812015-07-01 13:36:18 -0700523 return code
524
525 def CodeGet(self):
Haibo Huangf0077b82020-07-10 20:21:19 -0700526 code = """int
527%(parent_name)s_%(name)s_get(struct %(parent_name)s *msg, %(ctype)s *value)
528{
529 if (msg->%(name)s_set != 1)
530 return (-1);
531 *value = msg->%(name)s_data;
532 return (0);
533}"""
Christopher Wileye8679812015-07-01 13:36:18 -0700534 code = code % self.GetTranslation()
Haibo Huangf0077b82020-07-10 20:21:19 -0700535 return code.split("\n")
Christopher Wileye8679812015-07-01 13:36:18 -0700536
537 def AssignFuncName(self):
Haibo Huangf0077b82020-07-10 20:21:19 -0700538 return "%s_%s_assign" % (self._struct.Name(), self._name)
Christopher Wileye8679812015-07-01 13:36:18 -0700539
540 def AddFuncName(self):
Haibo Huangf0077b82020-07-10 20:21:19 -0700541 return "%s_%s_add" % (self._struct.Name(), self._name)
Christopher Wileye8679812015-07-01 13:36:18 -0700542
543 def AssignDeclaration(self, funcname):
Haibo Huangf0077b82020-07-10 20:21:19 -0700544 code = [
545 "int %s(struct %s *, const %s);"
546 % (funcname, self._struct.Name(), self._ctype)
547 ]
Christopher Wileye8679812015-07-01 13:36:18 -0700548 return code
549
550 def CodeAssign(self):
Haibo Huangf0077b82020-07-10 20:21:19 -0700551 code = [
552 "int",
553 "%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg,"
554 " const %(ctype)s value)",
555 "{",
556 " msg->%(name)s_set = 1;",
557 " msg->%(name)s_data = value;",
558 " return (0);",
559 "}",
560 ]
561 code = "\n".join(code)
Christopher Wileye8679812015-07-01 13:36:18 -0700562 code = code % self.GetTranslation()
Haibo Huangf0077b82020-07-10 20:21:19 -0700563 return code.split("\n")
Christopher Wileye8679812015-07-01 13:36:18 -0700564
565 def CodeClear(self, structname):
Haibo Huangf0077b82020-07-10 20:21:19 -0700566 code = ["%s->%s_set = 0;" % (structname, self.Name())]
Christopher Wileye8679812015-07-01 13:36:18 -0700567
568 return code
569
Haibo Huangf0077b82020-07-10 20:21:19 -0700570 @staticmethod
571 def CodeComplete(_structname, _var_name):
Christopher Wileye8679812015-07-01 13:36:18 -0700572 return []
573
Haibo Huangf0077b82020-07-10 20:21:19 -0700574 @staticmethod
575 def CodeFree(_name):
Christopher Wileye8679812015-07-01 13:36:18 -0700576 return []
577
578 def CodeBase(self):
Haibo Huangf0077b82020-07-10 20:21:19 -0700579 code = ["%(parent_name)s_%(name)s_assign,", "%(parent_name)s_%(name)s_get,"]
Christopher Wileye8679812015-07-01 13:36:18 -0700580 if self.Array():
Haibo Huangf0077b82020-07-10 20:21:19 -0700581 code.append("%(parent_name)s_%(name)s_add,")
Christopher Wileye8679812015-07-01 13:36:18 -0700582
Haibo Huangf0077b82020-07-10 20:21:19 -0700583 code = "\n".join(code)
Christopher Wileye8679812015-07-01 13:36:18 -0700584 code = code % self.GetTranslation()
Haibo Huangf0077b82020-07-10 20:21:19 -0700585 return code.split("\n")
586
Christopher Wileye8679812015-07-01 13:36:18 -0700587
588class EntryBytes(Entry):
Haibo Huangf0077b82020-07-10 20:21:19 -0700589 def __init__(self, ent_type, name, tag, length):
Christopher Wileye8679812015-07-01 13:36:18 -0700590 # Init base class
Haibo Huangf0077b82020-07-10 20:21:19 -0700591 super(EntryBytes, self).__init__(ent_type, name, tag)
Christopher Wileye8679812015-07-01 13:36:18 -0700592
593 self._length = length
Haibo Huangf0077b82020-07-10 20:21:19 -0700594 self._ctype = "ev_uint8_t"
Christopher Wileye8679812015-07-01 13:36:18 -0700595
Haibo Huangf0077b82020-07-10 20:21:19 -0700596 @staticmethod
597 def GetInitializer():
Christopher Wileye8679812015-07-01 13:36:18 -0700598 return "NULL"
599
Haibo Huangf0077b82020-07-10 20:21:19 -0700600 def GetVarLen(self, _var):
601 return "(%s)" % self._length
Christopher Wileye8679812015-07-01 13:36:18 -0700602
Haibo Huangf0077b82020-07-10 20:21:19 -0700603 @staticmethod
604 def CodeArrayAdd(varname, _value):
Christopher Wileye8679812015-07-01 13:36:18 -0700605 # XXX: copy here
Haibo Huangf0077b82020-07-10 20:21:19 -0700606 return ["%(varname)s = NULL;" % {"varname": varname}]
Christopher Wileye8679812015-07-01 13:36:18 -0700607
608 def GetDeclaration(self, funcname):
Haibo Huangf0077b82020-07-10 20:21:19 -0700609 code = [
610 "int %s(struct %s *, %s **);" % (funcname, self._struct.Name(), self._ctype)
611 ]
Christopher Wileye8679812015-07-01 13:36:18 -0700612 return code
613
614 def AssignDeclaration(self, funcname):
Haibo Huangf0077b82020-07-10 20:21:19 -0700615 code = [
616 "int %s(struct %s *, const %s *);"
617 % (funcname, self._struct.Name(), self._ctype)
618 ]
Christopher Wileye8679812015-07-01 13:36:18 -0700619 return code
620
621 def Declaration(self):
Haibo Huangf0077b82020-07-10 20:21:19 -0700622 dcl = ["ev_uint8_t %s_data[%s];" % (self._name, self._length)]
Christopher Wileye8679812015-07-01 13:36:18 -0700623
624 return dcl
625
626 def CodeGet(self):
627 name = self._name
Haibo Huangf0077b82020-07-10 20:21:19 -0700628 code = [
629 "int",
630 "%s_%s_get(struct %s *msg, %s **value)"
631 % (self._struct.Name(), name, self._struct.Name(), self._ctype),
632 "{",
633 " if (msg->%s_set != 1)" % name,
634 " return (-1);",
635 " *value = msg->%s_data;" % name,
636 " return (0);",
637 "}",
638 ]
Christopher Wileye8679812015-07-01 13:36:18 -0700639 return code
640
641 def CodeAssign(self):
642 name = self._name
Haibo Huangf0077b82020-07-10 20:21:19 -0700643 code = [
644 "int",
645 "%s_%s_assign(struct %s *msg, const %s *value)"
646 % (self._struct.Name(), name, self._struct.Name(), self._ctype),
647 "{",
648 " msg->%s_set = 1;" % name,
649 " memcpy(msg->%s_data, value, %s);" % (name, self._length),
650 " return (0);",
651 "}",
652 ]
Christopher Wileye8679812015-07-01 13:36:18 -0700653 return code
654
655 def CodeUnmarshal(self, buf, tag_name, var_name, var_len):
Haibo Huangf0077b82020-07-10 20:21:19 -0700656 code = [
657 "if (evtag_unmarshal_fixed(%(buf)s, %(tag)s, "
658 "%(var)s, %(varlen)s) == -1) {",
659 ' event_warnx("%%s: failed to unmarshal %(name)s", __func__);',
660 " return (-1);",
661 "}",
662 ]
663 return TranslateList(
664 code,
665 self.GetTranslation(
666 {"var": var_name, "varlen": var_len, "buf": buf, "tag": tag_name}
667 ),
668 )
Christopher Wileye8679812015-07-01 13:36:18 -0700669
Haibo Huangf0077b82020-07-10 20:21:19 -0700670 @staticmethod
671 def CodeMarshal(buf, tag_name, var_name, var_len):
672 code = ["evtag_marshal(%s, %s, %s, %s);" % (buf, tag_name, var_name, var_len)]
Christopher Wileye8679812015-07-01 13:36:18 -0700673 return code
674
675 def CodeClear(self, structname):
Haibo Huangf0077b82020-07-10 20:21:19 -0700676 code = [
677 "%s->%s_set = 0;" % (structname, self.Name()),
678 "memset(%s->%s_data, 0, sizeof(%s->%s_data));"
679 % (structname, self._name, structname, self._name),
680 ]
Christopher Wileye8679812015-07-01 13:36:18 -0700681
682 return code
683
684 def CodeInitialize(self, name):
Haibo Huangf0077b82020-07-10 20:21:19 -0700685 code = [
686 "memset(%s->%s_data, 0, sizeof(%s->%s_data));"
687 % (name, self._name, name, self._name)
688 ]
Christopher Wileye8679812015-07-01 13:36:18 -0700689 return code
690
691 def Verify(self):
692 if not self._length:
693 raise RpcGenError(
694 'Entry "%s" needs a length '
Haibo Huangf0077b82020-07-10 20:21:19 -0700695 "around line %d" % (self._name, self.LineCount())
696 )
Christopher Wileye8679812015-07-01 13:36:18 -0700697
Haibo Huangf0077b82020-07-10 20:21:19 -0700698 super(EntryBytes, self).Verify()
699
Christopher Wileye8679812015-07-01 13:36:18 -0700700
701class EntryInt(Entry):
Haibo Huangf0077b82020-07-10 20:21:19 -0700702 def __init__(self, ent_type, name, tag, bits=32):
Christopher Wileye8679812015-07-01 13:36:18 -0700703 # Init base class
Haibo Huangf0077b82020-07-10 20:21:19 -0700704 super(EntryInt, self).__init__(ent_type, name, tag)
Christopher Wileye8679812015-07-01 13:36:18 -0700705
Haibo Huangf0077b82020-07-10 20:21:19 -0700706 self._can_be_array = True
Christopher Wileye8679812015-07-01 13:36:18 -0700707 if bits == 32:
Haibo Huangf0077b82020-07-10 20:21:19 -0700708 self._ctype = "ev_uint32_t"
709 self._marshal_type = "int"
Christopher Wileye8679812015-07-01 13:36:18 -0700710 if bits == 64:
Haibo Huangf0077b82020-07-10 20:21:19 -0700711 self._ctype = "ev_uint64_t"
712 self._marshal_type = "int64"
Christopher Wileye8679812015-07-01 13:36:18 -0700713
Haibo Huangf0077b82020-07-10 20:21:19 -0700714 @staticmethod
715 def GetInitializer():
Christopher Wileye8679812015-07-01 13:36:18 -0700716 return "0"
717
Haibo Huangf0077b82020-07-10 20:21:19 -0700718 @staticmethod
719 def CodeArrayFree(_var):
Christopher Wileye8679812015-07-01 13:36:18 -0700720 return []
721
Haibo Huangf0077b82020-07-10 20:21:19 -0700722 @staticmethod
723 def CodeArrayAssign(varname, srcvar):
724 return ["%(varname)s = %(srcvar)s;" % {"varname": varname, "srcvar": srcvar}]
Christopher Wileye8679812015-07-01 13:36:18 -0700725
Haibo Huangf0077b82020-07-10 20:21:19 -0700726 @staticmethod
727 def CodeArrayAdd(varname, value):
Christopher Wileye8679812015-07-01 13:36:18 -0700728 """Returns a new entry of this type."""
Haibo Huangf0077b82020-07-10 20:21:19 -0700729 return ["%(varname)s = %(value)s;" % {"varname": varname, "value": value}]
Christopher Wileye8679812015-07-01 13:36:18 -0700730
Haibo Huangf0077b82020-07-10 20:21:19 -0700731 def CodeUnmarshal(self, buf, tag_name, var_name, _var_len):
Christopher Wileye8679812015-07-01 13:36:18 -0700732 code = [
Haibo Huangf0077b82020-07-10 20:21:19 -0700733 "if (evtag_unmarshal_%(ma)s(%(buf)s, %(tag)s, &%(var)s) == -1) {",
Christopher Wileye8679812015-07-01 13:36:18 -0700734 ' event_warnx("%%s: failed to unmarshal %(name)s", __func__);',
Haibo Huangf0077b82020-07-10 20:21:19 -0700735 " return (-1);",
736 "}",
737 ]
738 code = "\n".join(code) % self.GetTranslation(
739 {"ma": self._marshal_type, "buf": buf, "tag": tag_name, "var": var_name}
740 )
741 return code.split("\n")
Christopher Wileye8679812015-07-01 13:36:18 -0700742
Haibo Huangf0077b82020-07-10 20:21:19 -0700743 def CodeMarshal(self, buf, tag_name, var_name, _var_len):
Christopher Wileye8679812015-07-01 13:36:18 -0700744 code = [
Haibo Huangf0077b82020-07-10 20:21:19 -0700745 "evtag_marshal_%s(%s, %s, %s);"
746 % (self._marshal_type, buf, tag_name, var_name)
747 ]
Christopher Wileye8679812015-07-01 13:36:18 -0700748 return code
749
750 def Declaration(self):
Haibo Huangf0077b82020-07-10 20:21:19 -0700751 dcl = ["%s %s_data;" % (self._ctype, self._name)]
Christopher Wileye8679812015-07-01 13:36:18 -0700752
753 return dcl
754
755 def CodeInitialize(self, name):
Haibo Huangf0077b82020-07-10 20:21:19 -0700756 code = ["%s->%s_data = 0;" % (name, self._name)]
Christopher Wileye8679812015-07-01 13:36:18 -0700757 return code
758
Haibo Huangf0077b82020-07-10 20:21:19 -0700759
Christopher Wileye8679812015-07-01 13:36:18 -0700760class EntryString(Entry):
Haibo Huangf0077b82020-07-10 20:21:19 -0700761 def __init__(self, ent_type, name, tag):
Christopher Wileye8679812015-07-01 13:36:18 -0700762 # Init base class
Haibo Huangf0077b82020-07-10 20:21:19 -0700763 super(EntryString, self).__init__(ent_type, name, tag)
Christopher Wileye8679812015-07-01 13:36:18 -0700764
Haibo Huangf0077b82020-07-10 20:21:19 -0700765 self._can_be_array = True
766 self._ctype = "char *"
Christopher Wileye8679812015-07-01 13:36:18 -0700767
Haibo Huangf0077b82020-07-10 20:21:19 -0700768 @staticmethod
769 def GetInitializer():
Christopher Wileye8679812015-07-01 13:36:18 -0700770 return "NULL"
771
Haibo Huangf0077b82020-07-10 20:21:19 -0700772 @staticmethod
773 def CodeArrayFree(varname):
774 code = ["if (%(var)s != NULL) free(%(var)s);"]
Christopher Wileye8679812015-07-01 13:36:18 -0700775
Haibo Huangf0077b82020-07-10 20:21:19 -0700776 return TranslateList(code, {"var": varname})
Christopher Wileye8679812015-07-01 13:36:18 -0700777
Haibo Huangf0077b82020-07-10 20:21:19 -0700778 @staticmethod
779 def CodeArrayAssign(varname, srcvar):
Christopher Wileye8679812015-07-01 13:36:18 -0700780 code = [
Haibo Huangf0077b82020-07-10 20:21:19 -0700781 "if (%(var)s != NULL)",
782 " free(%(var)s);",
783 "%(var)s = strdup(%(srcvar)s);",
784 "if (%(var)s == NULL) {",
Christopher Wileye8679812015-07-01 13:36:18 -0700785 ' event_warnx("%%s: strdup", __func__);',
Haibo Huangf0077b82020-07-10 20:21:19 -0700786 " return (-1);",
787 "}",
788 ]
Christopher Wileye8679812015-07-01 13:36:18 -0700789
Haibo Huangf0077b82020-07-10 20:21:19 -0700790 return TranslateList(code, {"var": varname, "srcvar": srcvar})
Christopher Wileye8679812015-07-01 13:36:18 -0700791
Haibo Huangf0077b82020-07-10 20:21:19 -0700792 @staticmethod
793 def CodeArrayAdd(varname, value):
Christopher Wileye8679812015-07-01 13:36:18 -0700794 code = [
Haibo Huangf0077b82020-07-10 20:21:19 -0700795 "if (%(value)s != NULL) {",
796 " %(var)s = strdup(%(value)s);",
797 " if (%(var)s == NULL) {",
798 " goto error;",
799 " }",
800 "} else {",
801 " %(var)s = NULL;",
802 "}",
803 ]
Christopher Wileye8679812015-07-01 13:36:18 -0700804
Haibo Huangf0077b82020-07-10 20:21:19 -0700805 return TranslateList(code, {"var": varname, "value": value})
Christopher Wileye8679812015-07-01 13:36:18 -0700806
807 def GetVarLen(self, var):
Haibo Huangf0077b82020-07-10 20:21:19 -0700808 return "strlen(%s)" % self.GetVarName(var)
Christopher Wileye8679812015-07-01 13:36:18 -0700809
Haibo Huangf0077b82020-07-10 20:21:19 -0700810 @staticmethod
811 def CodeMakeInitalize(varname):
812 return "%(varname)s = NULL;" % {"varname": varname}
Christopher Wileye8679812015-07-01 13:36:18 -0700813
814 def CodeAssign(self):
Christopher Wileye8679812015-07-01 13:36:18 -0700815 code = """int
816%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg,
817 const %(ctype)s value)
818{
819 if (msg->%(name)s_data != NULL)
820 free(msg->%(name)s_data);
821 if ((msg->%(name)s_data = strdup(value)) == NULL)
822 return (-1);
823 msg->%(name)s_set = 1;
824 return (0);
Haibo Huangf0077b82020-07-10 20:21:19 -0700825}""" % (
826 self.GetTranslation()
827 )
Christopher Wileye8679812015-07-01 13:36:18 -0700828
Haibo Huangf0077b82020-07-10 20:21:19 -0700829 return code.split("\n")
Christopher Wileye8679812015-07-01 13:36:18 -0700830
Haibo Huangf0077b82020-07-10 20:21:19 -0700831 def CodeUnmarshal(self, buf, tag_name, var_name, _var_len):
832 code = [
833 "if (evtag_unmarshal_string(%(buf)s, %(tag)s, &%(var)s) == -1) {",
834 ' event_warnx("%%s: failed to unmarshal %(name)s", __func__);',
835 " return (-1);",
836 "}",
837 ]
838 code = "\n".join(code) % self.GetTranslation(
839 {"buf": buf, "tag": tag_name, "var": var_name}
840 )
841 return code.split("\n")
Christopher Wileye8679812015-07-01 13:36:18 -0700842
Haibo Huangf0077b82020-07-10 20:21:19 -0700843 @staticmethod
844 def CodeMarshal(buf, tag_name, var_name, _var_len):
845 code = ["evtag_marshal_string(%s, %s, %s);" % (buf, tag_name, var_name)]
Christopher Wileye8679812015-07-01 13:36:18 -0700846 return code
847
848 def CodeClear(self, structname):
Haibo Huangf0077b82020-07-10 20:21:19 -0700849 code = [
850 "if (%s->%s_set == 1) {" % (structname, self.Name()),
851 " free(%s->%s_data);" % (structname, self.Name()),
852 " %s->%s_data = NULL;" % (structname, self.Name()),
853 " %s->%s_set = 0;" % (structname, self.Name()),
854 "}",
855 ]
Christopher Wileye8679812015-07-01 13:36:18 -0700856
857 return code
858
859 def CodeInitialize(self, name):
Haibo Huangf0077b82020-07-10 20:21:19 -0700860 code = ["%s->%s_data = NULL;" % (name, self._name)]
Christopher Wileye8679812015-07-01 13:36:18 -0700861 return code
862
863 def CodeFree(self, name):
Haibo Huangf0077b82020-07-10 20:21:19 -0700864 code = [
865 "if (%s->%s_data != NULL)" % (name, self._name),
866 " free (%s->%s_data);" % (name, self._name),
867 ]
Christopher Wileye8679812015-07-01 13:36:18 -0700868
869 return code
870
871 def Declaration(self):
Haibo Huangf0077b82020-07-10 20:21:19 -0700872 dcl = ["char *%s_data;" % self._name]
Christopher Wileye8679812015-07-01 13:36:18 -0700873
874 return dcl
875
Haibo Huangf0077b82020-07-10 20:21:19 -0700876
Christopher Wileye8679812015-07-01 13:36:18 -0700877class EntryStruct(Entry):
Haibo Huangf0077b82020-07-10 20:21:19 -0700878 def __init__(self, ent_type, name, tag, refname):
Christopher Wileye8679812015-07-01 13:36:18 -0700879 # Init base class
Haibo Huangf0077b82020-07-10 20:21:19 -0700880 super(EntryStruct, self).__init__(ent_type, name, tag)
Christopher Wileye8679812015-07-01 13:36:18 -0700881
882 self._optpointer = False
Haibo Huangf0077b82020-07-10 20:21:19 -0700883 self._can_be_array = True
Christopher Wileye8679812015-07-01 13:36:18 -0700884 self._refname = refname
Haibo Huangf0077b82020-07-10 20:21:19 -0700885 self._ctype = "struct %s*" % refname
Christopher Wileye8679812015-07-01 13:36:18 -0700886 self._optaddarg = False
887
888 def GetInitializer(self):
889 return "NULL"
890
Haibo Huangf0077b82020-07-10 20:21:19 -0700891 def GetVarLen(self, _var):
892 return "-1"
Christopher Wileye8679812015-07-01 13:36:18 -0700893
Haibo Huangf0077b82020-07-10 20:21:19 -0700894 def CodeArrayAdd(self, varname, _value):
Christopher Wileye8679812015-07-01 13:36:18 -0700895 code = [
Haibo Huangf0077b82020-07-10 20:21:19 -0700896 "%(varname)s = %(refname)s_new();",
897 "if (%(varname)s == NULL)",
898 " goto error;",
899 ]
Christopher Wileye8679812015-07-01 13:36:18 -0700900
Haibo Huangf0077b82020-07-10 20:21:19 -0700901 return TranslateList(code, self.GetTranslation({"varname": varname}))
Christopher Wileye8679812015-07-01 13:36:18 -0700902
903 def CodeArrayFree(self, var):
Haibo Huangf0077b82020-07-10 20:21:19 -0700904 code = ["%(refname)s_free(%(var)s);" % self.GetTranslation({"var": var})]
Christopher Wileye8679812015-07-01 13:36:18 -0700905 return code
906
907 def CodeArrayAssign(self, var, srcvar):
908 code = [
Haibo Huangf0077b82020-07-10 20:21:19 -0700909 "int had_error = 0;",
910 "struct evbuffer *tmp = NULL;",
911 "%(refname)s_clear(%(var)s);",
912 "if ((tmp = evbuffer_new()) == NULL) {",
Christopher Wileye8679812015-07-01 13:36:18 -0700913 ' event_warn("%%s: evbuffer_new()", __func__);',
Haibo Huangf0077b82020-07-10 20:21:19 -0700914 " had_error = 1;",
915 " goto done;",
916 "}",
917 "%(refname)s_marshal(tmp, %(srcvar)s);",
918 "if (%(refname)s_unmarshal(%(var)s, tmp) == -1) {",
Christopher Wileye8679812015-07-01 13:36:18 -0700919 ' event_warnx("%%s: %(refname)s_unmarshal", __func__);',
Haibo Huangf0077b82020-07-10 20:21:19 -0700920 " had_error = 1;",
921 " goto done;",
922 "}",
923 "done:",
924 "if (tmp != NULL)",
925 " evbuffer_free(tmp);",
926 "if (had_error) {",
927 " %(refname)s_clear(%(var)s);",
928 " return (-1);",
929 "}",
930 ]
Christopher Wileye8679812015-07-01 13:36:18 -0700931
Haibo Huangf0077b82020-07-10 20:21:19 -0700932 return TranslateList(code, self.GetTranslation({"var": var, "srcvar": srcvar}))
Christopher Wileye8679812015-07-01 13:36:18 -0700933
934 def CodeGet(self):
935 name = self._name
Haibo Huangf0077b82020-07-10 20:21:19 -0700936 code = [
937 "int",
938 "%s_%s_get(struct %s *msg, %s *value)"
939 % (self._struct.Name(), name, self._struct.Name(), self._ctype),
940 "{",
941 " if (msg->%s_set != 1) {" % name,
942 " msg->%s_data = %s_new();" % (name, self._refname),
943 " if (msg->%s_data == NULL)" % name,
944 " return (-1);",
945 " msg->%s_set = 1;" % name,
946 " }",
947 " *value = msg->%s_data;" % name,
948 " return (0);",
949 "}",
950 ]
Christopher Wileye8679812015-07-01 13:36:18 -0700951 return code
952
953 def CodeAssign(self):
Haibo Huangf0077b82020-07-10 20:21:19 -0700954 code = (
955 """int
Christopher Wileye8679812015-07-01 13:36:18 -0700956%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg,
957 const %(ctype)s value)
958{
959 struct evbuffer *tmp = NULL;
960 if (msg->%(name)s_set) {
961 %(refname)s_clear(msg->%(name)s_data);
962 msg->%(name)s_set = 0;
963 } else {
964 msg->%(name)s_data = %(refname)s_new();
965 if (msg->%(name)s_data == NULL) {
966 event_warn("%%s: %(refname)s_new()", __func__);
967 goto error;
968 }
969 }
970 if ((tmp = evbuffer_new()) == NULL) {
971 event_warn("%%s: evbuffer_new()", __func__);
972 goto error;
973 }
974 %(refname)s_marshal(tmp, value);
975 if (%(refname)s_unmarshal(msg->%(name)s_data, tmp) == -1) {
976 event_warnx("%%s: %(refname)s_unmarshal", __func__);
977 goto error;
978 }
979 msg->%(name)s_set = 1;
980 evbuffer_free(tmp);
981 return (0);
982 error:
983 if (tmp != NULL)
984 evbuffer_free(tmp);
985 if (msg->%(name)s_data != NULL) {
986 %(refname)s_free(msg->%(name)s_data);
987 msg->%(name)s_data = NULL;
988 }
989 return (-1);
Haibo Huangf0077b82020-07-10 20:21:19 -0700990}"""
991 % self.GetTranslation()
992 )
993 return code.split("\n")
Christopher Wileye8679812015-07-01 13:36:18 -0700994
995 def CodeComplete(self, structname, var_name):
Haibo Huangf0077b82020-07-10 20:21:19 -0700996 code = [
997 "if (%(structname)s->%(name)s_set && "
998 "%(refname)s_complete(%(var)s) == -1)",
999 " return (-1);",
1000 ]
Christopher Wileye8679812015-07-01 13:36:18 -07001001
Haibo Huangf0077b82020-07-10 20:21:19 -07001002 return TranslateList(
1003 code, self.GetTranslation({"structname": structname, "var": var_name})
1004 )
Christopher Wileye8679812015-07-01 13:36:18 -07001005
Haibo Huangf0077b82020-07-10 20:21:19 -07001006 def CodeUnmarshal(self, buf, tag_name, var_name, _var_len):
1007 code = [
1008 "%(var)s = %(refname)s_new();",
1009 "if (%(var)s == NULL)",
1010 " return (-1);",
1011 "if (evtag_unmarshal_%(refname)s(%(buf)s, %(tag)s, ",
1012 " %(var)s) == -1) {",
1013 ' event_warnx("%%s: failed to unmarshal %(name)s", __func__);',
1014 " return (-1);",
1015 "}",
1016 ]
1017 code = "\n".join(code) % self.GetTranslation(
1018 {"buf": buf, "tag": tag_name, "var": var_name}
1019 )
1020 return code.split("\n")
Christopher Wileye8679812015-07-01 13:36:18 -07001021
Haibo Huangf0077b82020-07-10 20:21:19 -07001022 def CodeMarshal(self, buf, tag_name, var_name, _var_len):
1023 code = [
1024 "evtag_marshal_%s(%s, %s, %s);" % (self._refname, buf, tag_name, var_name)
1025 ]
Christopher Wileye8679812015-07-01 13:36:18 -07001026 return code
1027
1028 def CodeClear(self, structname):
Haibo Huangf0077b82020-07-10 20:21:19 -07001029 code = [
1030 "if (%s->%s_set == 1) {" % (structname, self.Name()),
1031 " %s_free(%s->%s_data);" % (self._refname, structname, self.Name()),
1032 " %s->%s_data = NULL;" % (structname, self.Name()),
1033 " %s->%s_set = 0;" % (structname, self.Name()),
1034 "}",
1035 ]
Christopher Wileye8679812015-07-01 13:36:18 -07001036
1037 return code
1038
1039 def CodeInitialize(self, name):
Haibo Huangf0077b82020-07-10 20:21:19 -07001040 code = ["%s->%s_data = NULL;" % (name, self._name)]
Christopher Wileye8679812015-07-01 13:36:18 -07001041 return code
1042
1043 def CodeFree(self, name):
Haibo Huangf0077b82020-07-10 20:21:19 -07001044 code = [
1045 "if (%s->%s_data != NULL)" % (name, self._name),
1046 " %s_free(%s->%s_data);" % (self._refname, name, self._name),
1047 ]
Christopher Wileye8679812015-07-01 13:36:18 -07001048
1049 return code
1050
1051 def Declaration(self):
Haibo Huangf0077b82020-07-10 20:21:19 -07001052 dcl = ["%s %s_data;" % (self._ctype, self._name)]
Christopher Wileye8679812015-07-01 13:36:18 -07001053
1054 return dcl
1055
Haibo Huangf0077b82020-07-10 20:21:19 -07001056
Christopher Wileye8679812015-07-01 13:36:18 -07001057class EntryVarBytes(Entry):
Haibo Huangf0077b82020-07-10 20:21:19 -07001058 def __init__(self, ent_type, name, tag):
Christopher Wileye8679812015-07-01 13:36:18 -07001059 # Init base class
Haibo Huangf0077b82020-07-10 20:21:19 -07001060 super(EntryVarBytes, self).__init__(ent_type, name, tag)
Christopher Wileye8679812015-07-01 13:36:18 -07001061
Haibo Huangf0077b82020-07-10 20:21:19 -07001062 self._ctype = "ev_uint8_t *"
Christopher Wileye8679812015-07-01 13:36:18 -07001063
Haibo Huangf0077b82020-07-10 20:21:19 -07001064 @staticmethod
1065 def GetInitializer():
Christopher Wileye8679812015-07-01 13:36:18 -07001066 return "NULL"
1067
1068 def GetVarLen(self, var):
Haibo Huangf0077b82020-07-10 20:21:19 -07001069 return "%(var)s->%(name)s_length" % self.GetTranslation({"var": var})
Christopher Wileye8679812015-07-01 13:36:18 -07001070
Haibo Huangf0077b82020-07-10 20:21:19 -07001071 @staticmethod
1072 def CodeArrayAdd(varname, _value):
Christopher Wileye8679812015-07-01 13:36:18 -07001073 # xxx: copy
Haibo Huangf0077b82020-07-10 20:21:19 -07001074 return ["%(varname)s = NULL;" % {"varname": varname}]
Christopher Wileye8679812015-07-01 13:36:18 -07001075
1076 def GetDeclaration(self, funcname):
Haibo Huangf0077b82020-07-10 20:21:19 -07001077 code = [
1078 "int %s(struct %s *, %s *, ev_uint32_t *);"
1079 % (funcname, self._struct.Name(), self._ctype)
1080 ]
Christopher Wileye8679812015-07-01 13:36:18 -07001081 return code
1082
1083 def AssignDeclaration(self, funcname):
Haibo Huangf0077b82020-07-10 20:21:19 -07001084 code = [
1085 "int %s(struct %s *, const %s, ev_uint32_t);"
1086 % (funcname, self._struct.Name(), self._ctype)
1087 ]
Christopher Wileye8679812015-07-01 13:36:18 -07001088 return code
1089
1090 def CodeAssign(self):
1091 name = self._name
Haibo Huangf0077b82020-07-10 20:21:19 -07001092 code = [
1093 "int",
1094 "%s_%s_assign(struct %s *msg, "
1095 "const %s value, ev_uint32_t len)"
1096 % (self._struct.Name(), name, self._struct.Name(), self._ctype),
1097 "{",
1098 " if (msg->%s_data != NULL)" % name,
1099 " free (msg->%s_data);" % name,
1100 " msg->%s_data = malloc(len);" % name,
1101 " if (msg->%s_data == NULL)" % name,
1102 " return (-1);",
1103 " msg->%s_set = 1;" % name,
1104 " msg->%s_length = len;" % name,
1105 " memcpy(msg->%s_data, value, len);" % name,
1106 " return (0);",
1107 "}",
1108 ]
Christopher Wileye8679812015-07-01 13:36:18 -07001109 return code
1110
1111 def CodeGet(self):
1112 name = self._name
Haibo Huangf0077b82020-07-10 20:21:19 -07001113 code = [
1114 "int",
1115 "%s_%s_get(struct %s *msg, %s *value, ev_uint32_t *plen)"
1116 % (self._struct.Name(), name, self._struct.Name(), self._ctype),
1117 "{",
1118 " if (msg->%s_set != 1)" % name,
1119 " return (-1);",
1120 " *value = msg->%s_data;" % name,
1121 " *plen = msg->%s_length;" % name,
1122 " return (0);",
1123 "}",
1124 ]
Christopher Wileye8679812015-07-01 13:36:18 -07001125 return code
1126
1127 def CodeUnmarshal(self, buf, tag_name, var_name, var_len):
Haibo Huangf0077b82020-07-10 20:21:19 -07001128 code = [
1129 "if (evtag_payload_length(%(buf)s, &%(varlen)s) == -1)",
1130 " return (-1);",
1131 # We do not want DoS opportunities
1132 "if (%(varlen)s > evbuffer_get_length(%(buf)s))",
1133 " return (-1);",
1134 "if ((%(var)s = malloc(%(varlen)s)) == NULL)",
1135 " return (-1);",
1136 "if (evtag_unmarshal_fixed(%(buf)s, %(tag)s, %(var)s, "
1137 "%(varlen)s) == -1) {",
1138 ' event_warnx("%%s: failed to unmarshal %(name)s", __func__);',
1139 " return (-1);",
1140 "}",
1141 ]
1142 code = "\n".join(code) % self.GetTranslation(
1143 {"buf": buf, "tag": tag_name, "var": var_name, "varlen": var_len}
1144 )
1145 return code.split("\n")
Christopher Wileye8679812015-07-01 13:36:18 -07001146
Haibo Huangf0077b82020-07-10 20:21:19 -07001147 @staticmethod
1148 def CodeMarshal(buf, tag_name, var_name, var_len):
1149 code = ["evtag_marshal(%s, %s, %s, %s);" % (buf, tag_name, var_name, var_len)]
Christopher Wileye8679812015-07-01 13:36:18 -07001150 return code
1151
1152 def CodeClear(self, structname):
Haibo Huangf0077b82020-07-10 20:21:19 -07001153 code = [
1154 "if (%s->%s_set == 1) {" % (structname, self.Name()),
1155 " free (%s->%s_data);" % (structname, self.Name()),
1156 " %s->%s_data = NULL;" % (structname, self.Name()),
1157 " %s->%s_length = 0;" % (structname, self.Name()),
1158 " %s->%s_set = 0;" % (structname, self.Name()),
1159 "}",
1160 ]
Christopher Wileye8679812015-07-01 13:36:18 -07001161
1162 return code
1163
1164 def CodeInitialize(self, name):
Haibo Huangf0077b82020-07-10 20:21:19 -07001165 code = [
1166 "%s->%s_data = NULL;" % (name, self._name),
1167 "%s->%s_length = 0;" % (name, self._name),
1168 ]
Christopher Wileye8679812015-07-01 13:36:18 -07001169 return code
1170
1171 def CodeFree(self, name):
Haibo Huangf0077b82020-07-10 20:21:19 -07001172 code = [
1173 "if (%s->%s_data != NULL)" % (name, self._name),
1174 " free(%s->%s_data);" % (name, self._name),
1175 ]
Christopher Wileye8679812015-07-01 13:36:18 -07001176
1177 return code
1178
1179 def Declaration(self):
Haibo Huangf0077b82020-07-10 20:21:19 -07001180 dcl = [
1181 "ev_uint8_t *%s_data;" % self._name,
1182 "ev_uint32_t %s_length;" % self._name,
1183 ]
Christopher Wileye8679812015-07-01 13:36:18 -07001184
1185 return dcl
1186
Haibo Huangf0077b82020-07-10 20:21:19 -07001187
Christopher Wileye8679812015-07-01 13:36:18 -07001188class EntryArray(Entry):
Haibo Huangf0077b82020-07-10 20:21:19 -07001189 _index = None
1190
Christopher Wileye8679812015-07-01 13:36:18 -07001191 def __init__(self, entry):
1192 # Init base class
Haibo Huangf0077b82020-07-10 20:21:19 -07001193 super(EntryArray, self).__init__(entry._type, entry._name, entry._tag)
Christopher Wileye8679812015-07-01 13:36:18 -07001194
1195 self._entry = entry
1196 self._refname = entry._refname
1197 self._ctype = self._entry._ctype
1198 self._optional = True
1199 self._optpointer = self._entry._optpointer
1200 self._optaddarg = self._entry._optaddarg
1201
1202 # provide a new function for accessing the variable name
1203 def GetVarName(var_name):
Haibo Huangf0077b82020-07-10 20:21:19 -07001204 return "%(var)s->%(name)s_data[%(index)s]" % self._entry.GetTranslation(
1205 {"var": var_name, "index": self._index}
1206 )
1207
Christopher Wileye8679812015-07-01 13:36:18 -07001208 self._entry.GetVarName = GetVarName
1209
1210 def GetInitializer(self):
1211 return "NULL"
1212
Haibo Huangf0077b82020-07-10 20:21:19 -07001213 def GetVarName(self, var):
1214 return var
Christopher Wileye8679812015-07-01 13:36:18 -07001215
Haibo Huangf0077b82020-07-10 20:21:19 -07001216 def GetVarLen(self, _var_name):
1217 return "-1"
Christopher Wileye8679812015-07-01 13:36:18 -07001218
1219 def GetDeclaration(self, funcname):
1220 """Allows direct access to elements of the array."""
1221 code = [
Haibo Huangf0077b82020-07-10 20:21:19 -07001222 "int %(funcname)s(struct %(parent_name)s *, int, %(ctype)s *);"
1223 % self.GetTranslation({"funcname": funcname})
1224 ]
Christopher Wileye8679812015-07-01 13:36:18 -07001225 return code
1226
1227 def AssignDeclaration(self, funcname):
Haibo Huangf0077b82020-07-10 20:21:19 -07001228 code = [
1229 "int %s(struct %s *, int, const %s);"
1230 % (funcname, self._struct.Name(), self._ctype)
1231 ]
Christopher Wileye8679812015-07-01 13:36:18 -07001232 return code
1233
1234 def AddDeclaration(self, funcname):
1235 code = [
Haibo Huangf0077b82020-07-10 20:21:19 -07001236 "%(ctype)s %(optpointer)s "
1237 "%(funcname)s(struct %(parent_name)s *msg%(optaddarg)s);"
1238 % self.GetTranslation({"funcname": funcname})
1239 ]
Christopher Wileye8679812015-07-01 13:36:18 -07001240 return code
1241
1242 def CodeGet(self):
1243 code = """int
1244%(parent_name)s_%(name)s_get(struct %(parent_name)s *msg, int offset,
1245 %(ctype)s *value)
1246{
1247 if (!msg->%(name)s_set || offset < 0 || offset >= msg->%(name)s_length)
1248 return (-1);
1249 *value = msg->%(name)s_data[offset];
1250 return (0);
Haibo Huangf0077b82020-07-10 20:21:19 -07001251}
1252""" % (
1253 self.GetTranslation()
1254 )
Christopher Wileye8679812015-07-01 13:36:18 -07001255
Haibo Huangf0077b82020-07-10 20:21:19 -07001256 return code.splitlines()
Christopher Wileye8679812015-07-01 13:36:18 -07001257
1258 def CodeAssign(self):
1259 code = [
Haibo Huangf0077b82020-07-10 20:21:19 -07001260 "int",
1261 "%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg, int off,",
1262 " const %(ctype)s value)",
1263 "{",
1264 " if (!msg->%(name)s_set || off < 0 || off >= msg->%(name)s_length)",
1265 " return (-1);",
1266 "",
1267 " {",
1268 ]
Christopher Wileye8679812015-07-01 13:36:18 -07001269 code = TranslateList(code, self.GetTranslation())
1270
1271 codearrayassign = self._entry.CodeArrayAssign(
Haibo Huangf0077b82020-07-10 20:21:19 -07001272 "msg->%(name)s_data[off]" % self.GetTranslation(), "value"
1273 )
1274 code += [" " + x for x in codearrayassign]
Christopher Wileye8679812015-07-01 13:36:18 -07001275
Haibo Huangf0077b82020-07-10 20:21:19 -07001276 code += TranslateList([" }", " return (0);", "}"], self.GetTranslation())
Christopher Wileye8679812015-07-01 13:36:18 -07001277
1278 return code
1279
1280 def CodeAdd(self):
1281 codearrayadd = self._entry.CodeArrayAdd(
Haibo Huangf0077b82020-07-10 20:21:19 -07001282 "msg->%(name)s_data[msg->%(name)s_length - 1]" % self.GetTranslation(),
1283 "value",
1284 )
Christopher Wileye8679812015-07-01 13:36:18 -07001285 code = [
Haibo Huangf0077b82020-07-10 20:21:19 -07001286 "static int",
1287 "%(parent_name)s_%(name)s_expand_to_hold_more("
1288 "struct %(parent_name)s *msg)",
1289 "{",
1290 " int tobe_allocated = msg->%(name)s_num_allocated;",
1291 " %(ctype)s* new_data = NULL;",
1292 " tobe_allocated = !tobe_allocated ? 1 : tobe_allocated << 1;",
1293 " new_data = (%(ctype)s*) realloc(msg->%(name)s_data,",
1294 " tobe_allocated * sizeof(%(ctype)s));",
1295 " if (new_data == NULL)",
1296 " return -1;",
1297 " msg->%(name)s_data = new_data;",
1298 " msg->%(name)s_num_allocated = tobe_allocated;",
1299 " return 0;",
1300 "}",
1301 "",
1302 "%(ctype)s %(optpointer)s",
1303 "%(parent_name)s_%(name)s_add(struct %(parent_name)s *msg%(optaddarg)s)",
1304 "{",
1305 " if (++msg->%(name)s_length >= msg->%(name)s_num_allocated) {",
1306 " if (%(parent_name)s_%(name)s_expand_to_hold_more(msg)<0)",
1307 " goto error;",
1308 " }",
1309 ]
Christopher Wileye8679812015-07-01 13:36:18 -07001310
1311 code = TranslateList(code, self.GetTranslation())
1312
Haibo Huangf0077b82020-07-10 20:21:19 -07001313 code += [" " + x for x in codearrayadd]
Christopher Wileye8679812015-07-01 13:36:18 -07001314
Haibo Huangf0077b82020-07-10 20:21:19 -07001315 code += TranslateList(
1316 [
1317 " msg->%(name)s_set = 1;",
1318 " return %(optreference)s(msg->%(name)s_data["
1319 "msg->%(name)s_length - 1]);",
1320 "error:",
1321 " --msg->%(name)s_length;",
1322 " return (NULL);",
1323 "}",
1324 ],
1325 self.GetTranslation(),
1326 )
Christopher Wileye8679812015-07-01 13:36:18 -07001327
1328 return code
1329
1330 def CodeComplete(self, structname, var_name):
Haibo Huangf0077b82020-07-10 20:21:19 -07001331 self._index = "i"
Christopher Wileye8679812015-07-01 13:36:18 -07001332 tmp = self._entry.CodeComplete(structname, self._entry.GetVarName(var_name))
1333 # skip the whole loop if there is nothing to check
1334 if not tmp:
1335 return []
1336
Haibo Huangf0077b82020-07-10 20:21:19 -07001337 translate = self.GetTranslation({"structname": structname})
Christopher Wileye8679812015-07-01 13:36:18 -07001338 code = [
Haibo Huangf0077b82020-07-10 20:21:19 -07001339 "{",
1340 " int i;",
1341 " for (i = 0; i < %(structname)s->%(name)s_length; ++i) {",
1342 ]
Christopher Wileye8679812015-07-01 13:36:18 -07001343
1344 code = TranslateList(code, translate)
1345
Haibo Huangf0077b82020-07-10 20:21:19 -07001346 code += [" " + x for x in tmp]
Christopher Wileye8679812015-07-01 13:36:18 -07001347
Haibo Huangf0077b82020-07-10 20:21:19 -07001348 code += [" }", "}"]
Christopher Wileye8679812015-07-01 13:36:18 -07001349
1350 return code
1351
Haibo Huangf0077b82020-07-10 20:21:19 -07001352 def CodeUnmarshal(self, buf, tag_name, var_name, _var_len):
1353 translate = self.GetTranslation(
1354 {
1355 "var": var_name,
1356 "buf": buf,
1357 "tag": tag_name,
1358 "init": self._entry.GetInitializer(),
1359 }
1360 )
Christopher Wileye8679812015-07-01 13:36:18 -07001361 code = [
Haibo Huangf0077b82020-07-10 20:21:19 -07001362 "if (%(var)s->%(name)s_length >= %(var)s->%(name)s_num_allocated &&",
1363 " %(parent_name)s_%(name)s_expand_to_hold_more(%(var)s) < 0) {",
Christopher Wileye8679812015-07-01 13:36:18 -07001364 ' puts("HEY NOW");',
Haibo Huangf0077b82020-07-10 20:21:19 -07001365 " return (-1);",
1366 "}",
1367 ]
Christopher Wileye8679812015-07-01 13:36:18 -07001368
1369 # the unmarshal code directly returns
1370 code = TranslateList(code, translate)
1371
Haibo Huangf0077b82020-07-10 20:21:19 -07001372 self._index = "%(var)s->%(name)s_length" % translate
1373 code += self._entry.CodeUnmarshal(
1374 buf,
1375 tag_name,
1376 self._entry.GetVarName(var_name),
1377 self._entry.GetVarLen(var_name),
1378 )
Christopher Wileye8679812015-07-01 13:36:18 -07001379
Haibo Huangf0077b82020-07-10 20:21:19 -07001380 code += ["++%(var)s->%(name)s_length;" % translate]
Christopher Wileye8679812015-07-01 13:36:18 -07001381
1382 return code
1383
Haibo Huangf0077b82020-07-10 20:21:19 -07001384 def CodeMarshal(self, buf, tag_name, var_name, _var_len):
1385 code = ["{", " int i;", " for (i = 0; i < %(var)s->%(name)s_length; ++i) {"]
Christopher Wileye8679812015-07-01 13:36:18 -07001386
Haibo Huangf0077b82020-07-10 20:21:19 -07001387 self._index = "i"
1388 code += self._entry.CodeMarshal(
1389 buf,
1390 tag_name,
1391 self._entry.GetVarName(var_name),
1392 self._entry.GetVarLen(var_name),
1393 )
1394 code += [" }", "}"]
Christopher Wileye8679812015-07-01 13:36:18 -07001395
Haibo Huangf0077b82020-07-10 20:21:19 -07001396 code = "\n".join(code) % self.GetTranslation({"var": var_name})
Christopher Wileye8679812015-07-01 13:36:18 -07001397
Haibo Huangf0077b82020-07-10 20:21:19 -07001398 return code.split("\n")
Christopher Wileye8679812015-07-01 13:36:18 -07001399
1400 def CodeClear(self, structname):
Haibo Huangf0077b82020-07-10 20:21:19 -07001401 translate = self.GetTranslation({"structname": structname})
Christopher Wileye8679812015-07-01 13:36:18 -07001402 codearrayfree = self._entry.CodeArrayFree(
Haibo Huangf0077b82020-07-10 20:21:19 -07001403 "%(structname)s->%(name)s_data[i]"
1404 % self.GetTranslation({"structname": structname})
1405 )
Christopher Wileye8679812015-07-01 13:36:18 -07001406
Haibo Huangf0077b82020-07-10 20:21:19 -07001407 code = ["if (%(structname)s->%(name)s_set == 1) {"]
Christopher Wileye8679812015-07-01 13:36:18 -07001408
1409 if codearrayfree:
1410 code += [
Haibo Huangf0077b82020-07-10 20:21:19 -07001411 " int i;",
1412 " for (i = 0; i < %(structname)s->%(name)s_length; ++i) {",
1413 ]
Christopher Wileye8679812015-07-01 13:36:18 -07001414
1415 code = TranslateList(code, translate)
1416
1417 if codearrayfree:
Haibo Huangf0077b82020-07-10 20:21:19 -07001418 code += [" " + x for x in codearrayfree]
1419 code += [" }"]
Christopher Wileye8679812015-07-01 13:36:18 -07001420
Haibo Huangf0077b82020-07-10 20:21:19 -07001421 code += TranslateList(
1422 [
1423 " free(%(structname)s->%(name)s_data);",
1424 " %(structname)s->%(name)s_data = NULL;",
1425 " %(structname)s->%(name)s_set = 0;",
1426 " %(structname)s->%(name)s_length = 0;",
1427 " %(structname)s->%(name)s_num_allocated = 0;",
1428 "}",
1429 ],
1430 translate,
1431 )
Christopher Wileye8679812015-07-01 13:36:18 -07001432
1433 return code
1434
1435 def CodeInitialize(self, name):
Haibo Huangf0077b82020-07-10 20:21:19 -07001436 code = [
1437 "%s->%s_data = NULL;" % (name, self._name),
1438 "%s->%s_length = 0;" % (name, self._name),
1439 "%s->%s_num_allocated = 0;" % (name, self._name),
1440 ]
Christopher Wileye8679812015-07-01 13:36:18 -07001441 return code
1442
1443 def CodeFree(self, structname):
Haibo Huangf0077b82020-07-10 20:21:19 -07001444 code = self.CodeClear(structname)
Christopher Wileye8679812015-07-01 13:36:18 -07001445
Haibo Huangf0077b82020-07-10 20:21:19 -07001446 code += TranslateList(
1447 ["free(%(structname)s->%(name)s_data);"],
1448 self.GetTranslation({"structname": structname}),
1449 )
Christopher Wileye8679812015-07-01 13:36:18 -07001450
1451 return code
1452
1453 def Declaration(self):
Haibo Huangf0077b82020-07-10 20:21:19 -07001454 dcl = [
1455 "%s *%s_data;" % (self._ctype, self._name),
1456 "int %s_length;" % self._name,
1457 "int %s_num_allocated;" % self._name,
1458 ]
Christopher Wileye8679812015-07-01 13:36:18 -07001459
1460 return dcl
1461
Christopher Wileye8679812015-07-01 13:36:18 -07001462
Haibo Huangf0077b82020-07-10 20:21:19 -07001463def NormalizeLine(line):
1464
1465 line = CPPCOMMENT_RE.sub("", line)
Christopher Wileye8679812015-07-01 13:36:18 -07001466 line = line.strip()
Haibo Huangf0077b82020-07-10 20:21:19 -07001467 line = WHITESPACE_RE.sub(" ", line)
Christopher Wileye8679812015-07-01 13:36:18 -07001468
1469 return line
1470
Haibo Huangf0077b82020-07-10 20:21:19 -07001471
1472ENTRY_NAME_RE = re.compile(r"(?P<name>[^\[\]]+)(\[(?P<fixed_length>.*)\])?")
1473ENTRY_TAG_NUMBER_RE = re.compile(r"(0x)?\d+", re.I)
1474
1475
Christopher Wileye8679812015-07-01 13:36:18 -07001476def ProcessOneEntry(factory, newstruct, entry):
Haibo Huangf0077b82020-07-10 20:21:19 -07001477 optional = False
1478 array = False
1479 entry_type = ""
1480 name = ""
1481 tag = ""
Christopher Wileye8679812015-07-01 13:36:18 -07001482 tag_set = None
Haibo Huangf0077b82020-07-10 20:21:19 -07001483 separator = ""
1484 fixed_length = ""
Christopher Wileye8679812015-07-01 13:36:18 -07001485
Haibo Huangf0077b82020-07-10 20:21:19 -07001486 for token in entry.split(" "):
Christopher Wileye8679812015-07-01 13:36:18 -07001487 if not entry_type:
Haibo Huangf0077b82020-07-10 20:21:19 -07001488 if not optional and token == "optional":
1489 optional = True
Christopher Wileye8679812015-07-01 13:36:18 -07001490 continue
1491
Haibo Huangf0077b82020-07-10 20:21:19 -07001492 if not array and token == "array":
1493 array = True
Christopher Wileye8679812015-07-01 13:36:18 -07001494 continue
1495
1496 if not entry_type:
1497 entry_type = token
1498 continue
1499
1500 if not name:
Haibo Huangf0077b82020-07-10 20:21:19 -07001501 res = ENTRY_NAME_RE.match(token)
Christopher Wileye8679812015-07-01 13:36:18 -07001502 if not res:
Haibo Huangf0077b82020-07-10 20:21:19 -07001503 raise RpcGenError(
1504 r"""Cannot parse name: "%s" around line %d""" % (entry, LINE_COUNT)
1505 )
1506 name = res.group("name")
1507 fixed_length = res.group("fixed_length")
Christopher Wileye8679812015-07-01 13:36:18 -07001508 continue
1509
1510 if not separator:
1511 separator = token
Haibo Huangf0077b82020-07-10 20:21:19 -07001512 if separator != "=":
1513 raise RpcGenError(
1514 r'''Expected "=" after name "%s" got "%s"''' % (name, token)
1515 )
Christopher Wileye8679812015-07-01 13:36:18 -07001516 continue
1517
1518 if not tag_set:
1519 tag_set = 1
Haibo Huangf0077b82020-07-10 20:21:19 -07001520 if not ENTRY_TAG_NUMBER_RE.match(token):
1521 raise RpcGenError(r'''Expected tag number: "%s"''' % (entry))
Christopher Wileye8679812015-07-01 13:36:18 -07001522 tag = int(token, 0)
1523 continue
1524
Haibo Huangf0077b82020-07-10 20:21:19 -07001525 raise RpcGenError(r'''Cannot parse "%s"''' % (entry))
Christopher Wileye8679812015-07-01 13:36:18 -07001526
1527 if not tag_set:
Haibo Huangf0077b82020-07-10 20:21:19 -07001528 raise RpcGenError(r'''Need tag number: "%s"''' % (entry))
Christopher Wileye8679812015-07-01 13:36:18 -07001529
1530 # Create the right entry
Haibo Huangf0077b82020-07-10 20:21:19 -07001531 if entry_type == "bytes":
Christopher Wileye8679812015-07-01 13:36:18 -07001532 if fixed_length:
1533 newentry = factory.EntryBytes(entry_type, name, tag, fixed_length)
1534 else:
1535 newentry = factory.EntryVarBytes(entry_type, name, tag)
Haibo Huangf0077b82020-07-10 20:21:19 -07001536 elif entry_type == "int" and not fixed_length:
Christopher Wileye8679812015-07-01 13:36:18 -07001537 newentry = factory.EntryInt(entry_type, name, tag)
Haibo Huangf0077b82020-07-10 20:21:19 -07001538 elif entry_type == "int64" and not fixed_length:
Christopher Wileye8679812015-07-01 13:36:18 -07001539 newentry = factory.EntryInt(entry_type, name, tag, bits=64)
Haibo Huangf0077b82020-07-10 20:21:19 -07001540 elif entry_type == "string" and not fixed_length:
Christopher Wileye8679812015-07-01 13:36:18 -07001541 newentry = factory.EntryString(entry_type, name, tag)
1542 else:
Haibo Huangf0077b82020-07-10 20:21:19 -07001543 res = STRUCT_REF_RE.match(entry_type)
Christopher Wileye8679812015-07-01 13:36:18 -07001544 if res:
1545 # References another struct defined in our file
Haibo Huangf0077b82020-07-10 20:21:19 -07001546 newentry = factory.EntryStruct(entry_type, name, tag, res.group("name"))
Christopher Wileye8679812015-07-01 13:36:18 -07001547 else:
1548 raise RpcGenError('Bad type: "%s" in "%s"' % (entry_type, entry))
1549
1550 structs = []
1551
1552 if optional:
1553 newentry.MakeOptional()
1554 if array:
1555 newentry.MakeArray()
1556
1557 newentry.SetStruct(newstruct)
Haibo Huangf0077b82020-07-10 20:21:19 -07001558 newentry.SetLineCount(LINE_COUNT)
Christopher Wileye8679812015-07-01 13:36:18 -07001559 newentry.Verify()
1560
1561 if array:
1562 # We need to encapsulate this entry into a struct
Christopher Wileye8679812015-07-01 13:36:18 -07001563 newentry = factory.EntryArray(newentry)
1564 newentry.SetStruct(newstruct)
Haibo Huangf0077b82020-07-10 20:21:19 -07001565 newentry.SetLineCount(LINE_COUNT)
Christopher Wileye8679812015-07-01 13:36:18 -07001566 newentry.MakeArray()
1567
1568 newstruct.AddEntry(newentry)
1569
1570 return structs
1571
Haibo Huangf0077b82020-07-10 20:21:19 -07001572
Christopher Wileye8679812015-07-01 13:36:18 -07001573def ProcessStruct(factory, data):
Haibo Huangf0077b82020-07-10 20:21:19 -07001574 tokens = data.split(" ")
Christopher Wileye8679812015-07-01 13:36:18 -07001575
1576 # First three tokens are: 'struct' 'name' '{'
1577 newstruct = factory.Struct(tokens[1])
1578
Haibo Huangf0077b82020-07-10 20:21:19 -07001579 inside = " ".join(tokens[3:-1])
Christopher Wileye8679812015-07-01 13:36:18 -07001580
Haibo Huangf0077b82020-07-10 20:21:19 -07001581 tokens = inside.split(";")
Christopher Wileye8679812015-07-01 13:36:18 -07001582
1583 structs = []
1584
1585 for entry in tokens:
1586 entry = NormalizeLine(entry)
1587 if not entry:
1588 continue
1589
1590 # It's possible that new structs get defined in here
1591 structs.extend(ProcessOneEntry(factory, newstruct, entry))
1592
1593 structs.append(newstruct)
1594 return structs
1595
Christopher Wileye8679812015-07-01 13:36:18 -07001596
Haibo Huangf0077b82020-07-10 20:21:19 -07001597C_COMMENT_START = "/*"
1598C_COMMENT_END = "*/"
Christopher Wileye8679812015-07-01 13:36:18 -07001599
Haibo Huangf0077b82020-07-10 20:21:19 -07001600C_COMMENT_START_RE = re.compile(re.escape(C_COMMENT_START))
1601C_COMMENT_END_RE = re.compile(re.escape(C_COMMENT_END))
Christopher Wileye8679812015-07-01 13:36:18 -07001602
Haibo Huangf0077b82020-07-10 20:21:19 -07001603C_COMMENT_START_SUB_RE = re.compile(r"%s.*$" % (re.escape(C_COMMENT_START)))
1604C_COMMENT_END_SUB_RE = re.compile(r"%s.*$" % (re.escape(C_COMMENT_END)))
1605
1606C_MULTILINE_COMMENT_SUB_RE = re.compile(
1607 r"%s.*?%s" % (re.escape(C_COMMENT_START), re.escape(C_COMMENT_END))
1608)
1609CPP_CONDITIONAL_BLOCK_RE = re.compile(r"#(if( |def)|endif)")
1610INCLUDE_RE = re.compile(r'#include (".+"|<.+>)')
1611
1612
1613def GetNextStruct(filep):
1614 global CPP_DIRECT
1615 global LINE_COUNT
1616
1617 got_struct = False
1618 have_c_comment = False
1619
1620 data = ""
1621
1622 while True:
1623 line = filep.readline()
Christopher Wileye8679812015-07-01 13:36:18 -07001624 if not line:
1625 break
1626
Haibo Huangf0077b82020-07-10 20:21:19 -07001627 LINE_COUNT += 1
Christopher Wileye8679812015-07-01 13:36:18 -07001628 line = line[:-1]
1629
Haibo Huangf0077b82020-07-10 20:21:19 -07001630 if not have_c_comment and C_COMMENT_START_RE.search(line):
1631 if C_MULTILINE_COMMENT_SUB_RE.search(line):
1632 line = C_MULTILINE_COMMENT_SUB_RE.sub("", line)
Christopher Wileye8679812015-07-01 13:36:18 -07001633 else:
Haibo Huangf0077b82020-07-10 20:21:19 -07001634 line = C_COMMENT_START_SUB_RE.sub("", line)
1635 have_c_comment = True
Christopher Wileye8679812015-07-01 13:36:18 -07001636
1637 if have_c_comment:
Haibo Huangf0077b82020-07-10 20:21:19 -07001638 if not C_COMMENT_END_RE.search(line):
Christopher Wileye8679812015-07-01 13:36:18 -07001639 continue
Haibo Huangf0077b82020-07-10 20:21:19 -07001640 have_c_comment = False
1641 line = C_COMMENT_END_SUB_RE.sub("", line)
Christopher Wileye8679812015-07-01 13:36:18 -07001642
1643 line = NormalizeLine(line)
1644
1645 if not line:
1646 continue
1647
1648 if not got_struct:
Haibo Huangf0077b82020-07-10 20:21:19 -07001649 if INCLUDE_RE.match(line):
1650 CPP_DIRECT.append(line)
1651 elif CPP_CONDITIONAL_BLOCK_RE.match(line):
1652 CPP_DIRECT.append(line)
1653 elif PREPROCESSOR_DEF_RE.match(line):
1654 HEADER_DIRECT.append(line)
1655 elif not STRUCT_DEF_RE.match(line):
1656 raise RpcGenError("Missing struct on line %d: %s" % (LINE_COUNT, line))
Christopher Wileye8679812015-07-01 13:36:18 -07001657 else:
Haibo Huangf0077b82020-07-10 20:21:19 -07001658 got_struct = True
Christopher Wileye8679812015-07-01 13:36:18 -07001659 data += line
1660 continue
1661
1662 # We are inside the struct
Haibo Huangf0077b82020-07-10 20:21:19 -07001663 tokens = line.split("}")
Christopher Wileye8679812015-07-01 13:36:18 -07001664 if len(tokens) == 1:
Haibo Huangf0077b82020-07-10 20:21:19 -07001665 data += " " + line
Christopher Wileye8679812015-07-01 13:36:18 -07001666 continue
1667
Haibo Huangf0077b82020-07-10 20:21:19 -07001668 if tokens[1]:
1669 raise RpcGenError("Trailing garbage after struct on line %d" % LINE_COUNT)
Christopher Wileye8679812015-07-01 13:36:18 -07001670
1671 # We found the end of the struct
Haibo Huangf0077b82020-07-10 20:21:19 -07001672 data += " %s}" % tokens[0]
Christopher Wileye8679812015-07-01 13:36:18 -07001673 break
1674
1675 # Remove any comments, that might be in there
Haibo Huangf0077b82020-07-10 20:21:19 -07001676 data = re.sub(r"/\*.*\*/", "", data)
Christopher Wileye8679812015-07-01 13:36:18 -07001677
1678 return data
1679
1680
Haibo Huangf0077b82020-07-10 20:21:19 -07001681def Parse(factory, filep):
Christopher Wileye8679812015-07-01 13:36:18 -07001682 """
1683 Parses the input file and returns C code and corresponding header file.
1684 """
1685
1686 entities = []
1687
1688 while 1:
1689 # Just gets the whole struct nicely formatted
Haibo Huangf0077b82020-07-10 20:21:19 -07001690 data = GetNextStruct(filep)
Christopher Wileye8679812015-07-01 13:36:18 -07001691
1692 if not data:
1693 break
1694
1695 entities.extend(ProcessStruct(factory, data))
1696
1697 return entities
1698
Haibo Huangf0077b82020-07-10 20:21:19 -07001699
1700class CCodeGenerator(object):
Christopher Wileye8679812015-07-01 13:36:18 -07001701 def __init__(self):
1702 pass
1703
Haibo Huangf0077b82020-07-10 20:21:19 -07001704 @staticmethod
1705 def GuardName(name):
Christopher Wileye8679812015-07-01 13:36:18 -07001706 # Use the complete provided path to the input file, with all
1707 # non-identifier characters replaced with underscores, to
1708 # reduce the chance of a collision between guard macros.
Haibo Huangf0077b82020-07-10 20:21:19 -07001709 return "EVENT_RPCOUT_%s_" % (NONIDENT_RE.sub("_", name).upper())
Christopher Wileye8679812015-07-01 13:36:18 -07001710
1711 def HeaderPreamble(self, name):
1712 guard = self.GuardName(name)
Haibo Huangf0077b82020-07-10 20:21:19 -07001713 pre = """
1714/*
1715 * Automatically generated from %s
1716 */
Christopher Wileye8679812015-07-01 13:36:18 -07001717
Haibo Huangf0077b82020-07-10 20:21:19 -07001718#ifndef %s
1719#define %s
Christopher Wileye8679812015-07-01 13:36:18 -07001720
Haibo Huangf0077b82020-07-10 20:21:19 -07001721""" % (
1722 name,
1723 guard,
1724 guard,
Christopher Wileye8679812015-07-01 13:36:18 -07001725 )
1726
Haibo Huangf0077b82020-07-10 20:21:19 -07001727 if HEADER_DIRECT:
1728 for statement in HEADER_DIRECT:
1729 pre += "%s\n" % statement
1730 pre += "\n"
1731
1732 pre += """
1733#include <event2/util.h> /* for ev_uint*_t */
1734#include <event2/rpc.h>
1735"""
1736
Christopher Wileye8679812015-07-01 13:36:18 -07001737 return pre
1738
1739 def HeaderPostamble(self, name):
1740 guard = self.GuardName(name)
Haibo Huangf0077b82020-07-10 20:21:19 -07001741 return "#endif /* %s */" % (guard)
Christopher Wileye8679812015-07-01 13:36:18 -07001742
Haibo Huangf0077b82020-07-10 20:21:19 -07001743 @staticmethod
1744 def BodyPreamble(name, header_file):
Christopher Wileye8679812015-07-01 13:36:18 -07001745 global _NAME
1746 global _VERSION
1747
Haibo Huangf0077b82020-07-10 20:21:19 -07001748 slash = header_file.rfind("/")
Christopher Wileye8679812015-07-01 13:36:18 -07001749 if slash != -1:
Haibo Huangf0077b82020-07-10 20:21:19 -07001750 header_file = header_file[slash + 1 :]
Christopher Wileye8679812015-07-01 13:36:18 -07001751
Haibo Huangf0077b82020-07-10 20:21:19 -07001752 pre = """
1753/*
1754 * Automatically generated from %(name)s
1755 * by %(script_name)s/%(script_version)s. DO NOT EDIT THIS FILE.
1756 */
Christopher Wileye8679812015-07-01 13:36:18 -07001757
Haibo Huangf0077b82020-07-10 20:21:19 -07001758#include <stdlib.h>
1759#include <string.h>
1760#include <assert.h>
1761#include <event2/event-config.h>
1762#include <event2/event.h>
1763#include <event2/buffer.h>
1764#include <event2/tag.h>
1765
1766#if defined(EVENT__HAVE___func__)
1767# ifndef __func__
1768# define __func__ __func__
1769# endif
1770#elif defined(EVENT__HAVE___FUNCTION__)
1771# define __func__ __FUNCTION__
1772#else
1773# define __func__ __FILE__
1774#endif
1775
1776""" % {
1777 "name": name,
1778 "script_name": _NAME,
1779 "script_version": _VERSION,
1780 }
1781
1782 for statement in CPP_DIRECT:
1783 pre += "%s\n" % statement
Christopher Wileye8679812015-07-01 13:36:18 -07001784
1785 pre += '\n#include "%s"\n\n' % header_file
1786
Haibo Huangf0077b82020-07-10 20:21:19 -07001787 pre += "void event_warn(const char *fmt, ...);\n"
1788 pre += "void event_warnx(const char *fmt, ...);\n\n"
Christopher Wileye8679812015-07-01 13:36:18 -07001789
1790 return pre
1791
Haibo Huangf0077b82020-07-10 20:21:19 -07001792 @staticmethod
1793 def HeaderFilename(filename):
1794 return ".".join(filename.split(".")[:-1]) + ".h"
Christopher Wileye8679812015-07-01 13:36:18 -07001795
Haibo Huangf0077b82020-07-10 20:21:19 -07001796 @staticmethod
1797 def CodeFilename(filename):
1798 return ".".join(filename.split(".")[:-1]) + ".gen.c"
Christopher Wileye8679812015-07-01 13:36:18 -07001799
Haibo Huangf0077b82020-07-10 20:21:19 -07001800 @staticmethod
1801 def Struct(name):
Christopher Wileye8679812015-07-01 13:36:18 -07001802 return StructCCode(name)
1803
Haibo Huangf0077b82020-07-10 20:21:19 -07001804 @staticmethod
1805 def EntryBytes(entry_type, name, tag, fixed_length):
Christopher Wileye8679812015-07-01 13:36:18 -07001806 return EntryBytes(entry_type, name, tag, fixed_length)
1807
Haibo Huangf0077b82020-07-10 20:21:19 -07001808 @staticmethod
1809 def EntryVarBytes(entry_type, name, tag):
Christopher Wileye8679812015-07-01 13:36:18 -07001810 return EntryVarBytes(entry_type, name, tag)
1811
Haibo Huangf0077b82020-07-10 20:21:19 -07001812 @staticmethod
1813 def EntryInt(entry_type, name, tag, bits=32):
Christopher Wileye8679812015-07-01 13:36:18 -07001814 return EntryInt(entry_type, name, tag, bits)
1815
Haibo Huangf0077b82020-07-10 20:21:19 -07001816 @staticmethod
1817 def EntryString(entry_type, name, tag):
Christopher Wileye8679812015-07-01 13:36:18 -07001818 return EntryString(entry_type, name, tag)
1819
Haibo Huangf0077b82020-07-10 20:21:19 -07001820 @staticmethod
1821 def EntryStruct(entry_type, name, tag, struct_name):
Christopher Wileye8679812015-07-01 13:36:18 -07001822 return EntryStruct(entry_type, name, tag, struct_name)
1823
Haibo Huangf0077b82020-07-10 20:21:19 -07001824 @staticmethod
1825 def EntryArray(entry):
Christopher Wileye8679812015-07-01 13:36:18 -07001826 return EntryArray(entry)
1827
Christopher Wileye8679812015-07-01 13:36:18 -07001828
Haibo Huangf0077b82020-07-10 20:21:19 -07001829class CommandLine(object):
1830 def __init__(self, argv=None):
Christopher Wileye8679812015-07-01 13:36:18 -07001831 """Initialize a command-line to launch event_rpcgen, as if
1832 from a command-line with CommandLine(sys.argv). If you're
1833 calling this directly, remember to provide a dummy value
1834 for sys.argv[0]
1835 """
Haibo Huangf0077b82020-07-10 20:21:19 -07001836 global QUIETLY
1837
Christopher Wileye8679812015-07-01 13:36:18 -07001838 self.filename = None
1839 self.header_file = None
1840 self.impl_file = None
1841 self.factory = CCodeGenerator()
1842
Haibo Huangf0077b82020-07-10 20:21:19 -07001843 parser = argparse.ArgumentParser(
1844 usage="%(prog)s [options] rpc-file [[h-file] c-file]"
1845 )
1846 parser.add_argument("--quiet", action="store_true", default=False)
1847 parser.add_argument("rpc_file", type=argparse.FileType("r"))
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001848
Haibo Huangf0077b82020-07-10 20:21:19 -07001849 args, extra_args = parser.parse_known_args(args=argv)
Christopher Wileye8679812015-07-01 13:36:18 -07001850
Haibo Huangf0077b82020-07-10 20:21:19 -07001851 QUIETLY = args.quiet
Christopher Wileye8679812015-07-01 13:36:18 -07001852
Haibo Huangf0077b82020-07-10 20:21:19 -07001853 if extra_args:
1854 if len(extra_args) == 1:
1855 self.impl_file = extra_args[0].replace("\\", "/")
1856 elif len(extra_args) == 2:
1857 self.header_file = extra_args[0].replace("\\", "/")
1858 self.impl_file = extra_args[1].replace("\\", "/")
1859 else:
1860 parser.error("Spurious arguments provided")
1861
1862 self.rpc_file = args.rpc_file
Christopher Wileye8679812015-07-01 13:36:18 -07001863
1864 if not self.impl_file:
Haibo Huangf0077b82020-07-10 20:21:19 -07001865 self.impl_file = self.factory.CodeFilename(self.rpc_file.name)
Christopher Wileye8679812015-07-01 13:36:18 -07001866
1867 if not self.header_file:
1868 self.header_file = self.factory.HeaderFilename(self.impl_file)
1869
Haibo Huangf0077b82020-07-10 20:21:19 -07001870 if not self.impl_file.endswith(".c"):
1871 parser.error("can only generate C implementation files")
1872 if not self.header_file.endswith(".h"):
1873 parser.error("can only generate C header files")
Christopher Wileye8679812015-07-01 13:36:18 -07001874
1875 def run(self):
Haibo Huangf0077b82020-07-10 20:21:19 -07001876 filename = self.rpc_file.name
Christopher Wileye8679812015-07-01 13:36:18 -07001877 header_file = self.header_file
1878 impl_file = self.impl_file
1879 factory = self.factory
1880
Haibo Huangf0077b82020-07-10 20:21:19 -07001881 declare('Reading "%s"' % filename)
Christopher Wileye8679812015-07-01 13:36:18 -07001882
Haibo Huangf0077b82020-07-10 20:21:19 -07001883 with self.rpc_file:
1884 entities = Parse(factory, self.rpc_file)
Christopher Wileye8679812015-07-01 13:36:18 -07001885
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001886 declare('... creating "%s"' % header_file)
Haibo Huangf0077b82020-07-10 20:21:19 -07001887 with open(header_file, "w") as header_fp:
1888 header_fp.write(factory.HeaderPreamble(filename))
Christopher Wileye8679812015-07-01 13:36:18 -07001889
Haibo Huangf0077b82020-07-10 20:21:19 -07001890 # Create forward declarations: allows other structs to reference
1891 # each other
1892 for entry in entities:
1893 entry.PrintForwardDeclaration(header_fp)
1894 header_fp.write("\n")
Christopher Wileye8679812015-07-01 13:36:18 -07001895
Haibo Huangf0077b82020-07-10 20:21:19 -07001896 for entry in entities:
1897 entry.PrintTags(header_fp)
1898 entry.PrintDeclaration(header_fp)
1899 header_fp.write(factory.HeaderPostamble(filename))
Christopher Wileye8679812015-07-01 13:36:18 -07001900
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001901 declare('... creating "%s"' % impl_file)
Haibo Huangf0077b82020-07-10 20:21:19 -07001902 with open(impl_file, "w") as impl_fp:
1903 impl_fp.write(factory.BodyPreamble(filename, header_file))
1904 for entry in entities:
1905 entry.PrintCode(impl_fp)
Christopher Wileye8679812015-07-01 13:36:18 -07001906
Haibo Huangf0077b82020-07-10 20:21:19 -07001907
1908def main(argv=None):
Christopher Wileye8679812015-07-01 13:36:18 -07001909 try:
Haibo Huangf0077b82020-07-10 20:21:19 -07001910 CommandLine(argv=argv).run()
1911 return 0
Haibo Huangb2279672019-05-31 16:12:39 -07001912 except RpcGenError as e:
1913 sys.stderr.write(e)
Haibo Huangb2279672019-05-31 16:12:39 -07001914 except EnvironmentError as e:
Christopher Wileye8679812015-07-01 13:36:18 -07001915 if e.filename and e.strerror:
Haibo Huangb2279672019-05-31 16:12:39 -07001916 sys.stderr.write("%s: %s" % (e.filename, e.strerror))
Christopher Wileye8679812015-07-01 13:36:18 -07001917 elif e.strerror:
Haibo Huangb2279672019-05-31 16:12:39 -07001918 sys.stderr.write(e.strerror)
Christopher Wileye8679812015-07-01 13:36:18 -07001919 else:
1920 raise
Haibo Huangf0077b82020-07-10 20:21:19 -07001921 return 1
1922
1923
1924if __name__ == "__main__":
1925 sys.exit(main(argv=sys.argv[1:]))