xref: /aosp_15_r20/external/cronet/third_party/libevent/event_rpcgen.py (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker#!/usr/bin/env python
2*6777b538SAndroid Build Coastguard Worker#
3*6777b538SAndroid Build Coastguard Worker# Copyright (c) 2005 Niels Provos <[email protected]>
4*6777b538SAndroid Build Coastguard Worker# All rights reserved.
5*6777b538SAndroid Build Coastguard Worker#
6*6777b538SAndroid Build Coastguard Worker# Generates marshaling code based on libevent.
7*6777b538SAndroid Build Coastguard Worker
8*6777b538SAndroid Build Coastguard Workerimport sys
9*6777b538SAndroid Build Coastguard Workerimport re
10*6777b538SAndroid Build Coastguard Worker
11*6777b538SAndroid Build Coastguard Worker#
12*6777b538SAndroid Build Coastguard Worker_NAME = "event_rpcgen.py"
13*6777b538SAndroid Build Coastguard Worker_VERSION = "0.1"
14*6777b538SAndroid Build Coastguard Worker_STRUCT_RE = '[a-z][a-z_0-9]*'
15*6777b538SAndroid Build Coastguard Worker
16*6777b538SAndroid Build Coastguard Worker# Globals
17*6777b538SAndroid Build Coastguard Workerline_count = 0
18*6777b538SAndroid Build Coastguard Worker
19*6777b538SAndroid Build Coastguard Workerwhite = re.compile(r'^\s+')
20*6777b538SAndroid Build Coastguard Workercppcomment = re.compile(r'\/\/.*$')
21*6777b538SAndroid Build Coastguard Workerheaderdirect = []
22*6777b538SAndroid Build Coastguard Workercppdirect = []
23*6777b538SAndroid Build Coastguard Worker
24*6777b538SAndroid Build Coastguard Worker# Holds everything that makes a struct
25*6777b538SAndroid Build Coastguard Workerclass Struct:
26*6777b538SAndroid Build Coastguard Worker    def __init__(self, name):
27*6777b538SAndroid Build Coastguard Worker        self._name = name
28*6777b538SAndroid Build Coastguard Worker        self._entries = []
29*6777b538SAndroid Build Coastguard Worker        self._tags = {}
30*6777b538SAndroid Build Coastguard Worker        print >>sys.stderr, '  Created struct: %s' % name
31*6777b538SAndroid Build Coastguard Worker
32*6777b538SAndroid Build Coastguard Worker    def AddEntry(self, entry):
33*6777b538SAndroid Build Coastguard Worker        if self._tags.has_key(entry.Tag()):
34*6777b538SAndroid Build Coastguard Worker            print >>sys.stderr, ( 'Entry "%s" duplicates tag number '
35*6777b538SAndroid Build Coastguard Worker                                  '%d from "%s" around line %d' ) % (
36*6777b538SAndroid Build Coastguard Worker                entry.Name(), entry.Tag(),
37*6777b538SAndroid Build Coastguard Worker                self._tags[entry.Tag()], line_count)
38*6777b538SAndroid Build Coastguard Worker            sys.exit(1)
39*6777b538SAndroid Build Coastguard Worker        self._entries.append(entry)
40*6777b538SAndroid Build Coastguard Worker        self._tags[entry.Tag()] = entry.Name()
41*6777b538SAndroid Build Coastguard Worker        print >>sys.stderr, '    Added entry: %s' % entry.Name()
42*6777b538SAndroid Build Coastguard Worker
43*6777b538SAndroid Build Coastguard Worker    def Name(self):
44*6777b538SAndroid Build Coastguard Worker        return self._name
45*6777b538SAndroid Build Coastguard Worker
46*6777b538SAndroid Build Coastguard Worker    def EntryTagName(self, entry):
47*6777b538SAndroid Build Coastguard Worker        """Creates the name inside an enumeration for distinguishing data
48*6777b538SAndroid Build Coastguard Worker        types."""
49*6777b538SAndroid Build Coastguard Worker        name = "%s_%s" % (self._name, entry.Name())
50*6777b538SAndroid Build Coastguard Worker        return name.upper()
51*6777b538SAndroid Build Coastguard Worker
52*6777b538SAndroid Build Coastguard Worker    def PrintIdented(self, file, ident, code):
53*6777b538SAndroid Build Coastguard Worker        """Takes an array, add indentation to each entry and prints it."""
54*6777b538SAndroid Build Coastguard Worker        for entry in code:
55*6777b538SAndroid Build Coastguard Worker            print >>file, '%s%s' % (ident, entry)
56*6777b538SAndroid Build Coastguard Worker
57*6777b538SAndroid Build Coastguard Worker    def PrintTags(self, file):
58*6777b538SAndroid Build Coastguard Worker        """Prints the tag definitions for a structure."""
59*6777b538SAndroid Build Coastguard Worker        print >>file, '/* Tag definition for %s */' % self._name
60*6777b538SAndroid Build Coastguard Worker        print >>file, 'enum %s_ {' % self._name.lower()
61*6777b538SAndroid Build Coastguard Worker        for entry in self._entries:
62*6777b538SAndroid Build Coastguard Worker            print >>file, '  %s=%d,' % (self.EntryTagName(entry),
63*6777b538SAndroid Build Coastguard Worker                                        entry.Tag())
64*6777b538SAndroid Build Coastguard Worker        print >>file, '  %s_MAX_TAGS' % (self._name.upper())
65*6777b538SAndroid Build Coastguard Worker        print >>file, '};\n'
66*6777b538SAndroid Build Coastguard Worker
67*6777b538SAndroid Build Coastguard Worker    def PrintForwardDeclaration(self, file):
68*6777b538SAndroid Build Coastguard Worker        print >>file, 'struct %s;' % self._name
69*6777b538SAndroid Build Coastguard Worker
70*6777b538SAndroid Build Coastguard Worker    def PrintDeclaration(self, file):
71*6777b538SAndroid Build Coastguard Worker        print >>file, '/* Structure declaration for %s */' % self._name
72*6777b538SAndroid Build Coastguard Worker        print >>file, 'struct %s_access_ {' % self._name
73*6777b538SAndroid Build Coastguard Worker        for entry in self._entries:
74*6777b538SAndroid Build Coastguard Worker            dcl = entry.AssignDeclaration('(*%s_assign)' % entry.Name())
75*6777b538SAndroid Build Coastguard Worker            dcl.extend(
76*6777b538SAndroid Build Coastguard Worker                entry.GetDeclaration('(*%s_get)' % entry.Name()))
77*6777b538SAndroid Build Coastguard Worker            if entry.Array():
78*6777b538SAndroid Build Coastguard Worker                dcl.extend(
79*6777b538SAndroid Build Coastguard Worker                    entry.AddDeclaration('(*%s_add)' % entry.Name()))
80*6777b538SAndroid Build Coastguard Worker            self.PrintIdented(file, '  ', dcl)
81*6777b538SAndroid Build Coastguard Worker        print >>file, '};\n'
82*6777b538SAndroid Build Coastguard Worker
83*6777b538SAndroid Build Coastguard Worker        print >>file, 'struct %s {' % self._name
84*6777b538SAndroid Build Coastguard Worker        print >>file, '  struct %s_access_ *base;\n' % self._name
85*6777b538SAndroid Build Coastguard Worker        for entry in self._entries:
86*6777b538SAndroid Build Coastguard Worker            dcl = entry.Declaration()
87*6777b538SAndroid Build Coastguard Worker            self.PrintIdented(file, '  ', dcl)
88*6777b538SAndroid Build Coastguard Worker        print >>file, ''
89*6777b538SAndroid Build Coastguard Worker        for entry in self._entries:
90*6777b538SAndroid Build Coastguard Worker            print >>file, '  ev_uint8_t %s_set;' % entry.Name()
91*6777b538SAndroid Build Coastguard Worker        print >>file, '};\n'
92*6777b538SAndroid Build Coastguard Worker
93*6777b538SAndroid Build Coastguard Worker        print >>file, \
94*6777b538SAndroid Build Coastguard Worker"""struct %(name)s *%(name)s_new(void);
95*6777b538SAndroid Build Coastguard Workervoid %(name)s_free(struct %(name)s *);
96*6777b538SAndroid Build Coastguard Workervoid %(name)s_clear(struct %(name)s *);
97*6777b538SAndroid Build Coastguard Workervoid %(name)s_marshal(struct evbuffer *, const struct %(name)s *);
98*6777b538SAndroid Build Coastguard Workerint %(name)s_unmarshal(struct %(name)s *, struct evbuffer *);
99*6777b538SAndroid Build Coastguard Workerint %(name)s_complete(struct %(name)s *);
100*6777b538SAndroid Build Coastguard Workervoid evtag_marshal_%(name)s(struct evbuffer *, ev_uint32_t,
101*6777b538SAndroid Build Coastguard Worker    const struct %(name)s *);
102*6777b538SAndroid Build Coastguard Workerint evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t,
103*6777b538SAndroid Build Coastguard Worker    struct %(name)s *);""" % { 'name' : self._name }
104*6777b538SAndroid Build Coastguard Worker
105*6777b538SAndroid Build Coastguard Worker
106*6777b538SAndroid Build Coastguard Worker        # Write a setting function of every variable
107*6777b538SAndroid Build Coastguard Worker        for entry in self._entries:
108*6777b538SAndroid Build Coastguard Worker            self.PrintIdented(file, '', entry.AssignDeclaration(
109*6777b538SAndroid Build Coastguard Worker                entry.AssignFuncName()))
110*6777b538SAndroid Build Coastguard Worker            self.PrintIdented(file, '', entry.GetDeclaration(
111*6777b538SAndroid Build Coastguard Worker                entry.GetFuncName()))
112*6777b538SAndroid Build Coastguard Worker            if entry.Array():
113*6777b538SAndroid Build Coastguard Worker                self.PrintIdented(file, '', entry.AddDeclaration(
114*6777b538SAndroid Build Coastguard Worker                    entry.AddFuncName()))
115*6777b538SAndroid Build Coastguard Worker
116*6777b538SAndroid Build Coastguard Worker        print >>file, '/* --- %s done --- */\n' % self._name
117*6777b538SAndroid Build Coastguard Worker
118*6777b538SAndroid Build Coastguard Worker    def PrintCode(self, file):
119*6777b538SAndroid Build Coastguard Worker        print >>file, ('/*\n'
120*6777b538SAndroid Build Coastguard Worker                       ' * Implementation of %s\n'
121*6777b538SAndroid Build Coastguard Worker                       ' */\n') % self._name
122*6777b538SAndroid Build Coastguard Worker
123*6777b538SAndroid Build Coastguard Worker        print >>file, \
124*6777b538SAndroid Build Coastguard Worker              'static struct %(name)s_access_ __%(name)s_base = {' % \
125*6777b538SAndroid Build Coastguard Worker              { 'name' : self._name }
126*6777b538SAndroid Build Coastguard Worker        for entry in self._entries:
127*6777b538SAndroid Build Coastguard Worker            self.PrintIdented(file, '  ', entry.CodeBase())
128*6777b538SAndroid Build Coastguard Worker        print >>file, '};\n'
129*6777b538SAndroid Build Coastguard Worker
130*6777b538SAndroid Build Coastguard Worker        # Creation
131*6777b538SAndroid Build Coastguard Worker        print >>file, (
132*6777b538SAndroid Build Coastguard Worker            'struct %(name)s *\n'
133*6777b538SAndroid Build Coastguard Worker            '%(name)s_new(void)\n'
134*6777b538SAndroid Build Coastguard Worker            '{\n'
135*6777b538SAndroid Build Coastguard Worker            '  struct %(name)s *tmp;\n'
136*6777b538SAndroid Build Coastguard Worker            '  if ((tmp = malloc(sizeof(struct %(name)s))) == NULL) {\n'
137*6777b538SAndroid Build Coastguard Worker            '    event_warn("%%s: malloc", __func__);\n'
138*6777b538SAndroid Build Coastguard Worker            '    return (NULL);\n'
139*6777b538SAndroid Build Coastguard Worker            '  }\n'
140*6777b538SAndroid Build Coastguard Worker            '  tmp->base = &__%(name)s_base;\n') % { 'name' : self._name }
141*6777b538SAndroid Build Coastguard Worker
142*6777b538SAndroid Build Coastguard Worker        for entry in self._entries:
143*6777b538SAndroid Build Coastguard Worker            self.PrintIdented(file, '  ', entry.CodeNew('tmp'))
144*6777b538SAndroid Build Coastguard Worker            print >>file, '  tmp->%s_set = 0;\n' % entry.Name()
145*6777b538SAndroid Build Coastguard Worker
146*6777b538SAndroid Build Coastguard Worker        print >>file, (
147*6777b538SAndroid Build Coastguard Worker            '  return (tmp);\n'
148*6777b538SAndroid Build Coastguard Worker            '}\n')
149*6777b538SAndroid Build Coastguard Worker
150*6777b538SAndroid Build Coastguard Worker        # Adding
151*6777b538SAndroid Build Coastguard Worker        for entry in self._entries:
152*6777b538SAndroid Build Coastguard Worker            if entry.Array():
153*6777b538SAndroid Build Coastguard Worker                self.PrintIdented(file, '', entry.CodeAdd())
154*6777b538SAndroid Build Coastguard Worker            print >>file, ''
155*6777b538SAndroid Build Coastguard Worker
156*6777b538SAndroid Build Coastguard Worker        # Assigning
157*6777b538SAndroid Build Coastguard Worker        for entry in self._entries:
158*6777b538SAndroid Build Coastguard Worker            self.PrintIdented(file, '', entry.CodeAssign())
159*6777b538SAndroid Build Coastguard Worker            print >>file, ''
160*6777b538SAndroid Build Coastguard Worker
161*6777b538SAndroid Build Coastguard Worker        # Getting
162*6777b538SAndroid Build Coastguard Worker        for entry in self._entries:
163*6777b538SAndroid Build Coastguard Worker            self.PrintIdented(file, '', entry.CodeGet())
164*6777b538SAndroid Build Coastguard Worker            print >>file, ''
165*6777b538SAndroid Build Coastguard Worker
166*6777b538SAndroid Build Coastguard Worker        # Clearing
167*6777b538SAndroid Build Coastguard Worker        print >>file, ( 'void\n'
168*6777b538SAndroid Build Coastguard Worker                        '%(name)s_clear(struct %(name)s *tmp)\n'
169*6777b538SAndroid Build Coastguard Worker                        '{'
170*6777b538SAndroid Build Coastguard Worker                        ) % { 'name' : self._name }
171*6777b538SAndroid Build Coastguard Worker        for entry in self._entries:
172*6777b538SAndroid Build Coastguard Worker            self.PrintIdented(file, '  ', entry.CodeClear('tmp'))
173*6777b538SAndroid Build Coastguard Worker
174*6777b538SAndroid Build Coastguard Worker        print >>file, '}\n'
175*6777b538SAndroid Build Coastguard Worker
176*6777b538SAndroid Build Coastguard Worker        # Freeing
177*6777b538SAndroid Build Coastguard Worker        print >>file, ( 'void\n'
178*6777b538SAndroid Build Coastguard Worker                        '%(name)s_free(struct %(name)s *tmp)\n'
179*6777b538SAndroid Build Coastguard Worker                        '{'
180*6777b538SAndroid Build Coastguard Worker                        ) % { 'name' : self._name }
181*6777b538SAndroid Build Coastguard Worker
182*6777b538SAndroid Build Coastguard Worker        for entry in self._entries:
183*6777b538SAndroid Build Coastguard Worker            self.PrintIdented(file, '  ', entry.CodeFree('tmp'))
184*6777b538SAndroid Build Coastguard Worker
185*6777b538SAndroid Build Coastguard Worker        print >>file, ('  free(tmp);\n'
186*6777b538SAndroid Build Coastguard Worker                       '}\n')
187*6777b538SAndroid Build Coastguard Worker
188*6777b538SAndroid Build Coastguard Worker        # Marshaling
189*6777b538SAndroid Build Coastguard Worker        print >>file, ('void\n'
190*6777b538SAndroid Build Coastguard Worker                       '%(name)s_marshal(struct evbuffer *evbuf, '
191*6777b538SAndroid Build Coastguard Worker                       'const struct %(name)s *tmp)'
192*6777b538SAndroid Build Coastguard Worker                       '{') % { 'name' : self._name }
193*6777b538SAndroid Build Coastguard Worker        for entry in self._entries:
194*6777b538SAndroid Build Coastguard Worker            indent = '  '
195*6777b538SAndroid Build Coastguard Worker            # Optional entries do not have to be set
196*6777b538SAndroid Build Coastguard Worker            if entry.Optional():
197*6777b538SAndroid Build Coastguard Worker                indent += '  '
198*6777b538SAndroid Build Coastguard Worker                print >>file, '  if (tmp->%s_set) {' % entry.Name()
199*6777b538SAndroid Build Coastguard Worker            self.PrintIdented(
200*6777b538SAndroid Build Coastguard Worker                file, indent,
201*6777b538SAndroid Build Coastguard Worker                entry.CodeMarshal('evbuf', self.EntryTagName(entry), 'tmp'))
202*6777b538SAndroid Build Coastguard Worker            if entry.Optional():
203*6777b538SAndroid Build Coastguard Worker                print >>file, '  }'
204*6777b538SAndroid Build Coastguard Worker
205*6777b538SAndroid Build Coastguard Worker        print >>file, '}\n'
206*6777b538SAndroid Build Coastguard Worker
207*6777b538SAndroid Build Coastguard Worker        # Unmarshaling
208*6777b538SAndroid Build Coastguard Worker        print >>file, ('int\n'
209*6777b538SAndroid Build Coastguard Worker                       '%(name)s_unmarshal(struct %(name)s *tmp, '
210*6777b538SAndroid Build Coastguard Worker                       ' struct evbuffer *evbuf)\n'
211*6777b538SAndroid Build Coastguard Worker                       '{\n'
212*6777b538SAndroid Build Coastguard Worker                       '  ev_uint32_t tag;\n'
213*6777b538SAndroid Build Coastguard Worker                       '  while (EVBUFFER_LENGTH(evbuf) > 0) {\n'
214*6777b538SAndroid Build Coastguard Worker                       '    if (evtag_peek(evbuf, &tag) == -1)\n'
215*6777b538SAndroid Build Coastguard Worker                       '      return (-1);\n'
216*6777b538SAndroid Build Coastguard Worker                       '    switch (tag) {\n'
217*6777b538SAndroid Build Coastguard Worker                       ) % { 'name' : self._name }
218*6777b538SAndroid Build Coastguard Worker        for entry in self._entries:
219*6777b538SAndroid Build Coastguard Worker            print >>file, '      case %s:\n' % self.EntryTagName(entry)
220*6777b538SAndroid Build Coastguard Worker            if not entry.Array():
221*6777b538SAndroid Build Coastguard Worker                print >>file, (
222*6777b538SAndroid Build Coastguard Worker                    '        if (tmp->%s_set)\n'
223*6777b538SAndroid Build Coastguard Worker                    '          return (-1);'
224*6777b538SAndroid Build Coastguard Worker                    ) % (entry.Name())
225*6777b538SAndroid Build Coastguard Worker
226*6777b538SAndroid Build Coastguard Worker            self.PrintIdented(
227*6777b538SAndroid Build Coastguard Worker                file, '        ',
228*6777b538SAndroid Build Coastguard Worker                entry.CodeUnmarshal('evbuf',
229*6777b538SAndroid Build Coastguard Worker                                    self.EntryTagName(entry), 'tmp'))
230*6777b538SAndroid Build Coastguard Worker
231*6777b538SAndroid Build Coastguard Worker            print >>file, ( '        tmp->%s_set = 1;\n' % entry.Name() +
232*6777b538SAndroid Build Coastguard Worker                            '        break;\n' )
233*6777b538SAndroid Build Coastguard Worker        print >>file, ( '      default:\n'
234*6777b538SAndroid Build Coastguard Worker                        '        return -1;\n'
235*6777b538SAndroid Build Coastguard Worker                        '    }\n'
236*6777b538SAndroid Build Coastguard Worker                        '  }\n' )
237*6777b538SAndroid Build Coastguard Worker        # Check if it was decoded completely
238*6777b538SAndroid Build Coastguard Worker        print >>file, ( '  if (%(name)s_complete(tmp) == -1)\n'
239*6777b538SAndroid Build Coastguard Worker                        '    return (-1);'
240*6777b538SAndroid Build Coastguard Worker                        ) % { 'name' : self._name }
241*6777b538SAndroid Build Coastguard Worker
242*6777b538SAndroid Build Coastguard Worker        # Successfully decoded
243*6777b538SAndroid Build Coastguard Worker        print >>file, ( '  return (0);\n'
244*6777b538SAndroid Build Coastguard Worker                        '}\n')
245*6777b538SAndroid Build Coastguard Worker
246*6777b538SAndroid Build Coastguard Worker        # Checking if a structure has all the required data
247*6777b538SAndroid Build Coastguard Worker        print >>file, (
248*6777b538SAndroid Build Coastguard Worker            'int\n'
249*6777b538SAndroid Build Coastguard Worker            '%(name)s_complete(struct %(name)s *msg)\n'
250*6777b538SAndroid Build Coastguard Worker            '{' ) % { 'name' : self._name }
251*6777b538SAndroid Build Coastguard Worker        for entry in self._entries:
252*6777b538SAndroid Build Coastguard Worker            self.PrintIdented(
253*6777b538SAndroid Build Coastguard Worker                file, '  ',
254*6777b538SAndroid Build Coastguard Worker                entry.CodeComplete('msg'))
255*6777b538SAndroid Build Coastguard Worker        print >>file, (
256*6777b538SAndroid Build Coastguard Worker            '  return (0);\n'
257*6777b538SAndroid Build Coastguard Worker            '}\n' )
258*6777b538SAndroid Build Coastguard Worker
259*6777b538SAndroid Build Coastguard Worker        # Complete message unmarshaling
260*6777b538SAndroid Build Coastguard Worker        print >>file, (
261*6777b538SAndroid Build Coastguard Worker            'int\n'
262*6777b538SAndroid Build Coastguard Worker            'evtag_unmarshal_%(name)s(struct evbuffer *evbuf, '
263*6777b538SAndroid Build Coastguard Worker            'ev_uint32_t need_tag, struct %(name)s *msg)\n'
264*6777b538SAndroid Build Coastguard Worker            '{\n'
265*6777b538SAndroid Build Coastguard Worker            '  ev_uint32_t tag;\n'
266*6777b538SAndroid Build Coastguard Worker            '  int res = -1;\n'
267*6777b538SAndroid Build Coastguard Worker            '\n'
268*6777b538SAndroid Build Coastguard Worker            '  struct evbuffer *tmp = evbuffer_new();\n'
269*6777b538SAndroid Build Coastguard Worker            '\n'
270*6777b538SAndroid Build Coastguard Worker            '  if (evtag_unmarshal(evbuf, &tag, tmp) == -1'
271*6777b538SAndroid Build Coastguard Worker            ' || tag != need_tag)\n'
272*6777b538SAndroid Build Coastguard Worker            '    goto error;\n'
273*6777b538SAndroid Build Coastguard Worker            '\n'
274*6777b538SAndroid Build Coastguard Worker            '  if (%(name)s_unmarshal(msg, tmp) == -1)\n'
275*6777b538SAndroid Build Coastguard Worker            '    goto error;\n'
276*6777b538SAndroid Build Coastguard Worker            '\n'
277*6777b538SAndroid Build Coastguard Worker            '  res = 0;\n'
278*6777b538SAndroid Build Coastguard Worker            '\n'
279*6777b538SAndroid Build Coastguard Worker            ' error:\n'
280*6777b538SAndroid Build Coastguard Worker            '  evbuffer_free(tmp);\n'
281*6777b538SAndroid Build Coastguard Worker            '  return (res);\n'
282*6777b538SAndroid Build Coastguard Worker            '}\n' ) % { 'name' : self._name }
283*6777b538SAndroid Build Coastguard Worker
284*6777b538SAndroid Build Coastguard Worker        # Complete message marshaling
285*6777b538SAndroid Build Coastguard Worker        print >>file, (
286*6777b538SAndroid Build Coastguard Worker            'void\n'
287*6777b538SAndroid Build Coastguard Worker            'evtag_marshal_%(name)s(struct evbuffer *evbuf, ev_uint32_t tag, '
288*6777b538SAndroid Build Coastguard Worker            'const struct %(name)s *msg)\n'
289*6777b538SAndroid Build Coastguard Worker            '{\n'
290*6777b538SAndroid Build Coastguard Worker            '  struct evbuffer *_buf = evbuffer_new();\n'
291*6777b538SAndroid Build Coastguard Worker            '  assert(_buf != NULL);\n'
292*6777b538SAndroid Build Coastguard Worker            '  evbuffer_drain(_buf, -1);\n'
293*6777b538SAndroid Build Coastguard Worker            '  %(name)s_marshal(_buf, msg);\n'
294*6777b538SAndroid Build Coastguard Worker            '  evtag_marshal(evbuf, tag, EVBUFFER_DATA(_buf), '
295*6777b538SAndroid Build Coastguard Worker            'EVBUFFER_LENGTH(_buf));\n'
296*6777b538SAndroid Build Coastguard Worker            '  evbuffer_free(_buf);\n'
297*6777b538SAndroid Build Coastguard Worker            '}\n' ) % { 'name' : self._name }
298*6777b538SAndroid Build Coastguard Worker
299*6777b538SAndroid Build Coastguard Workerclass Entry:
300*6777b538SAndroid Build Coastguard Worker    def __init__(self, type, name, tag):
301*6777b538SAndroid Build Coastguard Worker        self._type = type
302*6777b538SAndroid Build Coastguard Worker        self._name = name
303*6777b538SAndroid Build Coastguard Worker        self._tag = int(tag)
304*6777b538SAndroid Build Coastguard Worker        self._ctype = type
305*6777b538SAndroid Build Coastguard Worker        self._optional = 0
306*6777b538SAndroid Build Coastguard Worker        self._can_be_array = 0
307*6777b538SAndroid Build Coastguard Worker        self._array = 0
308*6777b538SAndroid Build Coastguard Worker        self._line_count = -1
309*6777b538SAndroid Build Coastguard Worker        self._struct = None
310*6777b538SAndroid Build Coastguard Worker        self._refname = None
311*6777b538SAndroid Build Coastguard Worker
312*6777b538SAndroid Build Coastguard Worker    def GetTranslation(self):
313*6777b538SAndroid Build Coastguard Worker        return { "parent_name" : self._struct.Name(),
314*6777b538SAndroid Build Coastguard Worker                 "name" : self._name,
315*6777b538SAndroid Build Coastguard Worker                 "ctype" : self._ctype,
316*6777b538SAndroid Build Coastguard Worker                 "refname" : self._refname
317*6777b538SAndroid Build Coastguard Worker                 }
318*6777b538SAndroid Build Coastguard Worker
319*6777b538SAndroid Build Coastguard Worker    def SetStruct(self, struct):
320*6777b538SAndroid Build Coastguard Worker        self._struct = struct
321*6777b538SAndroid Build Coastguard Worker
322*6777b538SAndroid Build Coastguard Worker    def LineCount(self):
323*6777b538SAndroid Build Coastguard Worker        assert self._line_count != -1
324*6777b538SAndroid Build Coastguard Worker        return self._line_count
325*6777b538SAndroid Build Coastguard Worker
326*6777b538SAndroid Build Coastguard Worker    def SetLineCount(self, number):
327*6777b538SAndroid Build Coastguard Worker        self._line_count = number
328*6777b538SAndroid Build Coastguard Worker
329*6777b538SAndroid Build Coastguard Worker    def Array(self):
330*6777b538SAndroid Build Coastguard Worker        return self._array
331*6777b538SAndroid Build Coastguard Worker
332*6777b538SAndroid Build Coastguard Worker    def Optional(self):
333*6777b538SAndroid Build Coastguard Worker        return self._optional
334*6777b538SAndroid Build Coastguard Worker
335*6777b538SAndroid Build Coastguard Worker    def Tag(self):
336*6777b538SAndroid Build Coastguard Worker        return self._tag
337*6777b538SAndroid Build Coastguard Worker
338*6777b538SAndroid Build Coastguard Worker    def Name(self):
339*6777b538SAndroid Build Coastguard Worker        return self._name
340*6777b538SAndroid Build Coastguard Worker
341*6777b538SAndroid Build Coastguard Worker    def Type(self):
342*6777b538SAndroid Build Coastguard Worker        return self._type
343*6777b538SAndroid Build Coastguard Worker
344*6777b538SAndroid Build Coastguard Worker    def MakeArray(self, yes=1):
345*6777b538SAndroid Build Coastguard Worker        self._array = yes
346*6777b538SAndroid Build Coastguard Worker
347*6777b538SAndroid Build Coastguard Worker    def MakeOptional(self):
348*6777b538SAndroid Build Coastguard Worker        self._optional = 1
349*6777b538SAndroid Build Coastguard Worker
350*6777b538SAndroid Build Coastguard Worker    def GetFuncName(self):
351*6777b538SAndroid Build Coastguard Worker        return '%s_%s_get' % (self._struct.Name(), self._name)
352*6777b538SAndroid Build Coastguard Worker
353*6777b538SAndroid Build Coastguard Worker    def GetDeclaration(self, funcname):
354*6777b538SAndroid Build Coastguard Worker        code = [ 'int %s(struct %s *, %s *);' % (
355*6777b538SAndroid Build Coastguard Worker            funcname, self._struct.Name(), self._ctype ) ]
356*6777b538SAndroid Build Coastguard Worker        return code
357*6777b538SAndroid Build Coastguard Worker
358*6777b538SAndroid Build Coastguard Worker    def CodeGet(self):
359*6777b538SAndroid Build Coastguard Worker        code = (
360*6777b538SAndroid Build Coastguard Worker            'int',
361*6777b538SAndroid Build Coastguard Worker            '%(parent_name)s_%(name)s_get(struct %(parent_name)s *msg, '
362*6777b538SAndroid Build Coastguard Worker            '%(ctype)s *value)',
363*6777b538SAndroid Build Coastguard Worker            '{',
364*6777b538SAndroid Build Coastguard Worker            '  if (msg->%(name)s_set != 1)',
365*6777b538SAndroid Build Coastguard Worker            '    return (-1);',
366*6777b538SAndroid Build Coastguard Worker            '  *value = msg->%(name)s_data;',
367*6777b538SAndroid Build Coastguard Worker            '  return (0);',
368*6777b538SAndroid Build Coastguard Worker            '}' )
369*6777b538SAndroid Build Coastguard Worker        code = '\n'.join(code)
370*6777b538SAndroid Build Coastguard Worker        code = code % self.GetTranslation()
371*6777b538SAndroid Build Coastguard Worker        return code.split('\n')
372*6777b538SAndroid Build Coastguard Worker
373*6777b538SAndroid Build Coastguard Worker    def AssignFuncName(self):
374*6777b538SAndroid Build Coastguard Worker        return '%s_%s_assign' % (self._struct.Name(), self._name)
375*6777b538SAndroid Build Coastguard Worker
376*6777b538SAndroid Build Coastguard Worker    def AddFuncName(self):
377*6777b538SAndroid Build Coastguard Worker        return '%s_%s_add' % (self._struct.Name(), self._name)
378*6777b538SAndroid Build Coastguard Worker
379*6777b538SAndroid Build Coastguard Worker    def AssignDeclaration(self, funcname):
380*6777b538SAndroid Build Coastguard Worker        code = [ 'int %s(struct %s *, const %s);' % (
381*6777b538SAndroid Build Coastguard Worker            funcname, self._struct.Name(), self._ctype ) ]
382*6777b538SAndroid Build Coastguard Worker        return code
383*6777b538SAndroid Build Coastguard Worker
384*6777b538SAndroid Build Coastguard Worker    def CodeAssign(self):
385*6777b538SAndroid Build Coastguard Worker        code = [ 'int',
386*6777b538SAndroid Build Coastguard Worker                 '%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg,'
387*6777b538SAndroid Build Coastguard Worker                 ' const %(ctype)s value)',
388*6777b538SAndroid Build Coastguard Worker                 '{',
389*6777b538SAndroid Build Coastguard Worker                 '  msg->%(name)s_set = 1;',
390*6777b538SAndroid Build Coastguard Worker                 '  msg->%(name)s_data = value;',
391*6777b538SAndroid Build Coastguard Worker                 '  return (0);',
392*6777b538SAndroid Build Coastguard Worker                 '}' ]
393*6777b538SAndroid Build Coastguard Worker        code = '\n'.join(code)
394*6777b538SAndroid Build Coastguard Worker        code = code % self.GetTranslation()
395*6777b538SAndroid Build Coastguard Worker        return code.split('\n')
396*6777b538SAndroid Build Coastguard Worker
397*6777b538SAndroid Build Coastguard Worker    def CodeClear(self, structname):
398*6777b538SAndroid Build Coastguard Worker        code = [ '%s->%s_set = 0;' % (structname, self.Name()) ]
399*6777b538SAndroid Build Coastguard Worker
400*6777b538SAndroid Build Coastguard Worker        return code
401*6777b538SAndroid Build Coastguard Worker
402*6777b538SAndroid Build Coastguard Worker    def CodeComplete(self, structname):
403*6777b538SAndroid Build Coastguard Worker        if self.Optional():
404*6777b538SAndroid Build Coastguard Worker            return []
405*6777b538SAndroid Build Coastguard Worker
406*6777b538SAndroid Build Coastguard Worker        code = [ 'if (!%s->%s_set)' % (structname, self.Name()),
407*6777b538SAndroid Build Coastguard Worker                 '  return (-1);' ]
408*6777b538SAndroid Build Coastguard Worker
409*6777b538SAndroid Build Coastguard Worker        return code
410*6777b538SAndroid Build Coastguard Worker
411*6777b538SAndroid Build Coastguard Worker    def CodeFree(self, name):
412*6777b538SAndroid Build Coastguard Worker        return []
413*6777b538SAndroid Build Coastguard Worker
414*6777b538SAndroid Build Coastguard Worker    def CodeBase(self):
415*6777b538SAndroid Build Coastguard Worker        code = [
416*6777b538SAndroid Build Coastguard Worker            '%(parent_name)s_%(name)s_assign,',
417*6777b538SAndroid Build Coastguard Worker            '%(parent_name)s_%(name)s_get,'
418*6777b538SAndroid Build Coastguard Worker            ]
419*6777b538SAndroid Build Coastguard Worker        if self.Array():
420*6777b538SAndroid Build Coastguard Worker            code.append('%(parent_name)s_%(name)s_add,')
421*6777b538SAndroid Build Coastguard Worker
422*6777b538SAndroid Build Coastguard Worker        code = '\n'.join(code)
423*6777b538SAndroid Build Coastguard Worker        code = code % self.GetTranslation()
424*6777b538SAndroid Build Coastguard Worker        return code.split('\n')
425*6777b538SAndroid Build Coastguard Worker
426*6777b538SAndroid Build Coastguard Worker    def Verify(self):
427*6777b538SAndroid Build Coastguard Worker        if self.Array() and not self._can_be_array:
428*6777b538SAndroid Build Coastguard Worker            print >>sys.stderr, (
429*6777b538SAndroid Build Coastguard Worker                'Entry "%s" cannot be created as an array '
430*6777b538SAndroid Build Coastguard Worker                'around line %d' ) % (self._name, self.LineCount())
431*6777b538SAndroid Build Coastguard Worker            sys.exit(1)
432*6777b538SAndroid Build Coastguard Worker        if not self._struct:
433*6777b538SAndroid Build Coastguard Worker            print >>sys.stderr, (
434*6777b538SAndroid Build Coastguard Worker                'Entry "%s" does not know which struct it belongs to '
435*6777b538SAndroid Build Coastguard Worker                'around line %d' ) % (self._name, self.LineCount())
436*6777b538SAndroid Build Coastguard Worker            sys.exit(1)
437*6777b538SAndroid Build Coastguard Worker        if self._optional and self._array:
438*6777b538SAndroid Build Coastguard Worker            print >>sys.stderr,  ( 'Entry "%s" has illegal combination of '
439*6777b538SAndroid Build Coastguard Worker                                   'optional and array around line %d' ) % (
440*6777b538SAndroid Build Coastguard Worker                self._name, self.LineCount() )
441*6777b538SAndroid Build Coastguard Worker            sys.exit(1)
442*6777b538SAndroid Build Coastguard Worker
443*6777b538SAndroid Build Coastguard Workerclass EntryBytes(Entry):
444*6777b538SAndroid Build Coastguard Worker    def __init__(self, type, name, tag, length):
445*6777b538SAndroid Build Coastguard Worker        # Init base class
446*6777b538SAndroid Build Coastguard Worker        Entry.__init__(self, type, name, tag)
447*6777b538SAndroid Build Coastguard Worker
448*6777b538SAndroid Build Coastguard Worker        self._length = length
449*6777b538SAndroid Build Coastguard Worker        self._ctype = 'ev_uint8_t'
450*6777b538SAndroid Build Coastguard Worker
451*6777b538SAndroid Build Coastguard Worker    def GetDeclaration(self, funcname):
452*6777b538SAndroid Build Coastguard Worker        code = [ 'int %s(struct %s *, %s **);' % (
453*6777b538SAndroid Build Coastguard Worker            funcname, self._struct.Name(), self._ctype ) ]
454*6777b538SAndroid Build Coastguard Worker        return code
455*6777b538SAndroid Build Coastguard Worker
456*6777b538SAndroid Build Coastguard Worker    def AssignDeclaration(self, funcname):
457*6777b538SAndroid Build Coastguard Worker        code = [ 'int %s(struct %s *, const %s *);' % (
458*6777b538SAndroid Build Coastguard Worker            funcname, self._struct.Name(), self._ctype ) ]
459*6777b538SAndroid Build Coastguard Worker        return code
460*6777b538SAndroid Build Coastguard Worker
461*6777b538SAndroid Build Coastguard Worker    def Declaration(self):
462*6777b538SAndroid Build Coastguard Worker        dcl  = ['ev_uint8_t %s_data[%s];' % (self._name, self._length)]
463*6777b538SAndroid Build Coastguard Worker
464*6777b538SAndroid Build Coastguard Worker        return dcl
465*6777b538SAndroid Build Coastguard Worker
466*6777b538SAndroid Build Coastguard Worker    def CodeGet(self):
467*6777b538SAndroid Build Coastguard Worker        name = self._name
468*6777b538SAndroid Build Coastguard Worker        code = [ 'int',
469*6777b538SAndroid Build Coastguard Worker                 '%s_%s_get(struct %s *msg, %s **value)' % (
470*6777b538SAndroid Build Coastguard Worker            self._struct.Name(), name,
471*6777b538SAndroid Build Coastguard Worker            self._struct.Name(), self._ctype),
472*6777b538SAndroid Build Coastguard Worker                 '{',
473*6777b538SAndroid Build Coastguard Worker                 '  if (msg->%s_set != 1)' % name,
474*6777b538SAndroid Build Coastguard Worker                 '    return (-1);',
475*6777b538SAndroid Build Coastguard Worker                 '  *value = msg->%s_data;' % name,
476*6777b538SAndroid Build Coastguard Worker                 '  return (0);',
477*6777b538SAndroid Build Coastguard Worker                 '}' ]
478*6777b538SAndroid Build Coastguard Worker        return code
479*6777b538SAndroid Build Coastguard Worker
480*6777b538SAndroid Build Coastguard Worker    def CodeAssign(self):
481*6777b538SAndroid Build Coastguard Worker        name = self._name
482*6777b538SAndroid Build Coastguard Worker        code = [ 'int',
483*6777b538SAndroid Build Coastguard Worker                 '%s_%s_assign(struct %s *msg, const %s *value)' % (
484*6777b538SAndroid Build Coastguard Worker            self._struct.Name(), name,
485*6777b538SAndroid Build Coastguard Worker            self._struct.Name(), self._ctype),
486*6777b538SAndroid Build Coastguard Worker                 '{',
487*6777b538SAndroid Build Coastguard Worker                 '  msg->%s_set = 1;' % name,
488*6777b538SAndroid Build Coastguard Worker                 '  memcpy(msg->%s_data, value, %s);' % (
489*6777b538SAndroid Build Coastguard Worker            name, self._length),
490*6777b538SAndroid Build Coastguard Worker                 '  return (0);',
491*6777b538SAndroid Build Coastguard Worker                 '}' ]
492*6777b538SAndroid Build Coastguard Worker        return code
493*6777b538SAndroid Build Coastguard Worker
494*6777b538SAndroid Build Coastguard Worker    def CodeUnmarshal(self, buf, tag_name, var_name):
495*6777b538SAndroid Build Coastguard Worker        code = [  'if (evtag_unmarshal_fixed(%s, %s, ' % (buf, tag_name) +
496*6777b538SAndroid Build Coastguard Worker                  '%s->%s_data, ' % (var_name, self._name) +
497*6777b538SAndroid Build Coastguard Worker                  'sizeof(%s->%s_data)) == -1) {' % (
498*6777b538SAndroid Build Coastguard Worker            var_name, self._name),
499*6777b538SAndroid Build Coastguard Worker                  '  event_warnx("%%s: failed to unmarshal %s", __func__);' % (
500*6777b538SAndroid Build Coastguard Worker            self._name ),
501*6777b538SAndroid Build Coastguard Worker                  '  return (-1);',
502*6777b538SAndroid Build Coastguard Worker                  '}'
503*6777b538SAndroid Build Coastguard Worker                  ]
504*6777b538SAndroid Build Coastguard Worker        return code
505*6777b538SAndroid Build Coastguard Worker
506*6777b538SAndroid Build Coastguard Worker    def CodeMarshal(self, buf, tag_name, var_name):
507*6777b538SAndroid Build Coastguard Worker        code = ['evtag_marshal(%s, %s, %s->%s_data, sizeof(%s->%s_data));' % (
508*6777b538SAndroid Build Coastguard Worker            buf, tag_name, var_name, self._name, var_name, self._name )]
509*6777b538SAndroid Build Coastguard Worker        return code
510*6777b538SAndroid Build Coastguard Worker
511*6777b538SAndroid Build Coastguard Worker    def CodeClear(self, structname):
512*6777b538SAndroid Build Coastguard Worker        code = [ '%s->%s_set = 0;' % (structname, self.Name()),
513*6777b538SAndroid Build Coastguard Worker                 'memset(%s->%s_data, 0, sizeof(%s->%s_data));' % (
514*6777b538SAndroid Build Coastguard Worker            structname, self._name, structname, self._name)]
515*6777b538SAndroid Build Coastguard Worker
516*6777b538SAndroid Build Coastguard Worker        return code
517*6777b538SAndroid Build Coastguard Worker
518*6777b538SAndroid Build Coastguard Worker    def CodeNew(self, name):
519*6777b538SAndroid Build Coastguard Worker        code  = ['memset(%s->%s_data, 0, sizeof(%s->%s_data));' % (
520*6777b538SAndroid Build Coastguard Worker            name, self._name, name, self._name)]
521*6777b538SAndroid Build Coastguard Worker        return code
522*6777b538SAndroid Build Coastguard Worker
523*6777b538SAndroid Build Coastguard Worker    def Verify(self):
524*6777b538SAndroid Build Coastguard Worker        if not self._length:
525*6777b538SAndroid Build Coastguard Worker            print >>sys.stderr, 'Entry "%s" needs a length around line %d' % (
526*6777b538SAndroid Build Coastguard Worker                self._name, self.LineCount() )
527*6777b538SAndroid Build Coastguard Worker            sys.exit(1)
528*6777b538SAndroid Build Coastguard Worker
529*6777b538SAndroid Build Coastguard Worker        Entry.Verify(self)
530*6777b538SAndroid Build Coastguard Worker
531*6777b538SAndroid Build Coastguard Workerclass EntryInt(Entry):
532*6777b538SAndroid Build Coastguard Worker    def __init__(self, type, name, tag):
533*6777b538SAndroid Build Coastguard Worker        # Init base class
534*6777b538SAndroid Build Coastguard Worker        Entry.__init__(self, type, name, tag)
535*6777b538SAndroid Build Coastguard Worker
536*6777b538SAndroid Build Coastguard Worker        self._ctype = 'ev_uint32_t'
537*6777b538SAndroid Build Coastguard Worker
538*6777b538SAndroid Build Coastguard Worker    def CodeUnmarshal(self, buf, tag_name, var_name):
539*6777b538SAndroid Build Coastguard Worker        code = ['if (evtag_unmarshal_int(%s, %s, &%s->%s_data) == -1) {' % (
540*6777b538SAndroid Build Coastguard Worker            buf, tag_name, var_name, self._name),
541*6777b538SAndroid Build Coastguard Worker                  '  event_warnx("%%s: failed to unmarshal %s", __func__);' % (
542*6777b538SAndroid Build Coastguard Worker            self._name ),
543*6777b538SAndroid Build Coastguard Worker                '  return (-1);',
544*6777b538SAndroid Build Coastguard Worker                '}' ]
545*6777b538SAndroid Build Coastguard Worker        return code
546*6777b538SAndroid Build Coastguard Worker
547*6777b538SAndroid Build Coastguard Worker    def CodeMarshal(self, buf, tag_name, var_name):
548*6777b538SAndroid Build Coastguard Worker        code = ['evtag_marshal_int(%s, %s, %s->%s_data);' % (
549*6777b538SAndroid Build Coastguard Worker            buf, tag_name, var_name, self._name)]
550*6777b538SAndroid Build Coastguard Worker        return code
551*6777b538SAndroid Build Coastguard Worker
552*6777b538SAndroid Build Coastguard Worker    def Declaration(self):
553*6777b538SAndroid Build Coastguard Worker        dcl  = ['ev_uint32_t %s_data;' % self._name]
554*6777b538SAndroid Build Coastguard Worker
555*6777b538SAndroid Build Coastguard Worker        return dcl
556*6777b538SAndroid Build Coastguard Worker
557*6777b538SAndroid Build Coastguard Worker    def CodeNew(self, name):
558*6777b538SAndroid Build Coastguard Worker        code = ['%s->%s_data = 0;' % (name, self._name)]
559*6777b538SAndroid Build Coastguard Worker        return code
560*6777b538SAndroid Build Coastguard Worker
561*6777b538SAndroid Build Coastguard Workerclass EntryString(Entry):
562*6777b538SAndroid Build Coastguard Worker    def __init__(self, type, name, tag):
563*6777b538SAndroid Build Coastguard Worker        # Init base class
564*6777b538SAndroid Build Coastguard Worker        Entry.__init__(self, type, name, tag)
565*6777b538SAndroid Build Coastguard Worker
566*6777b538SAndroid Build Coastguard Worker        self._ctype = 'char *'
567*6777b538SAndroid Build Coastguard Worker
568*6777b538SAndroid Build Coastguard Worker    def CodeAssign(self):
569*6777b538SAndroid Build Coastguard Worker        name = self._name
570*6777b538SAndroid Build Coastguard Worker        code = """int
571*6777b538SAndroid Build Coastguard Worker%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg,
572*6777b538SAndroid Build Coastguard Worker    const %(ctype)s value)
573*6777b538SAndroid Build Coastguard Worker{
574*6777b538SAndroid Build Coastguard Worker  if (msg->%(name)s_data != NULL)
575*6777b538SAndroid Build Coastguard Worker    free(msg->%(name)s_data);
576*6777b538SAndroid Build Coastguard Worker  if ((msg->%(name)s_data = strdup(value)) == NULL)
577*6777b538SAndroid Build Coastguard Worker    return (-1);
578*6777b538SAndroid Build Coastguard Worker  msg->%(name)s_set = 1;
579*6777b538SAndroid Build Coastguard Worker  return (0);
580*6777b538SAndroid Build Coastguard Worker}""" % self.GetTranslation()
581*6777b538SAndroid Build Coastguard Worker
582*6777b538SAndroid Build Coastguard Worker        return code.split('\n')
583*6777b538SAndroid Build Coastguard Worker
584*6777b538SAndroid Build Coastguard Worker    def CodeUnmarshal(self, buf, tag_name, var_name):
585*6777b538SAndroid Build Coastguard Worker        code = ['if (evtag_unmarshal_string(%s, %s, &%s->%s_data) == -1) {' % (
586*6777b538SAndroid Build Coastguard Worker            buf, tag_name, var_name, self._name),
587*6777b538SAndroid Build Coastguard Worker                '  event_warnx("%%s: failed to unmarshal %s", __func__);' % (
588*6777b538SAndroid Build Coastguard Worker            self._name ),
589*6777b538SAndroid Build Coastguard Worker                '  return (-1);',
590*6777b538SAndroid Build Coastguard Worker                '}'
591*6777b538SAndroid Build Coastguard Worker                ]
592*6777b538SAndroid Build Coastguard Worker        return code
593*6777b538SAndroid Build Coastguard Worker
594*6777b538SAndroid Build Coastguard Worker    def CodeMarshal(self, buf, tag_name, var_name):
595*6777b538SAndroid Build Coastguard Worker        code = ['evtag_marshal_string(%s, %s, %s->%s_data);' % (
596*6777b538SAndroid Build Coastguard Worker            buf, tag_name, var_name, self._name)]
597*6777b538SAndroid Build Coastguard Worker        return code
598*6777b538SAndroid Build Coastguard Worker
599*6777b538SAndroid Build Coastguard Worker    def CodeClear(self, structname):
600*6777b538SAndroid Build Coastguard Worker        code = [ 'if (%s->%s_set == 1) {' % (structname, self.Name()),
601*6777b538SAndroid Build Coastguard Worker                 '  free (%s->%s_data);' % (structname, self.Name()),
602*6777b538SAndroid Build Coastguard Worker                 '  %s->%s_data = NULL;' % (structname, self.Name()),
603*6777b538SAndroid Build Coastguard Worker                 '  %s->%s_set = 0;' % (structname, self.Name()),
604*6777b538SAndroid Build Coastguard Worker                 '}'
605*6777b538SAndroid Build Coastguard Worker                 ]
606*6777b538SAndroid Build Coastguard Worker
607*6777b538SAndroid Build Coastguard Worker        return code
608*6777b538SAndroid Build Coastguard Worker
609*6777b538SAndroid Build Coastguard Worker    def CodeNew(self, name):
610*6777b538SAndroid Build Coastguard Worker        code  = ['%s->%s_data = NULL;' % (name, self._name)]
611*6777b538SAndroid Build Coastguard Worker        return code
612*6777b538SAndroid Build Coastguard Worker
613*6777b538SAndroid Build Coastguard Worker    def CodeFree(self, name):
614*6777b538SAndroid Build Coastguard Worker        code  = ['if (%s->%s_data != NULL)' % (name, self._name),
615*6777b538SAndroid Build Coastguard Worker                 '    free (%s->%s_data); ' % (name, self._name)]
616*6777b538SAndroid Build Coastguard Worker
617*6777b538SAndroid Build Coastguard Worker        return code
618*6777b538SAndroid Build Coastguard Worker
619*6777b538SAndroid Build Coastguard Worker    def Declaration(self):
620*6777b538SAndroid Build Coastguard Worker        dcl  = ['char *%s_data;' % self._name]
621*6777b538SAndroid Build Coastguard Worker
622*6777b538SAndroid Build Coastguard Worker        return dcl
623*6777b538SAndroid Build Coastguard Worker
624*6777b538SAndroid Build Coastguard Workerclass EntryStruct(Entry):
625*6777b538SAndroid Build Coastguard Worker    def __init__(self, type, name, tag, refname):
626*6777b538SAndroid Build Coastguard Worker        # Init base class
627*6777b538SAndroid Build Coastguard Worker        Entry.__init__(self, type, name, tag)
628*6777b538SAndroid Build Coastguard Worker
629*6777b538SAndroid Build Coastguard Worker        self._can_be_array = 1
630*6777b538SAndroid Build Coastguard Worker        self._refname = refname
631*6777b538SAndroid Build Coastguard Worker        self._ctype = 'struct %s*' % refname
632*6777b538SAndroid Build Coastguard Worker
633*6777b538SAndroid Build Coastguard Worker    def CodeGet(self):
634*6777b538SAndroid Build Coastguard Worker        name = self._name
635*6777b538SAndroid Build Coastguard Worker        code = [ 'int',
636*6777b538SAndroid Build Coastguard Worker                 '%s_%s_get(struct %s *msg, %s *value)' % (
637*6777b538SAndroid Build Coastguard Worker            self._struct.Name(), name,
638*6777b538SAndroid Build Coastguard Worker            self._struct.Name(), self._ctype),
639*6777b538SAndroid Build Coastguard Worker                 '{',
640*6777b538SAndroid Build Coastguard Worker                 '  if (msg->%s_set != 1) {' % name,
641*6777b538SAndroid Build Coastguard Worker                 '    msg->%s_data = %s_new();' % (name, self._refname),
642*6777b538SAndroid Build Coastguard Worker                 '    if (msg->%s_data == NULL)' % name,
643*6777b538SAndroid Build Coastguard Worker                 '      return (-1);',
644*6777b538SAndroid Build Coastguard Worker                 '    msg->%s_set = 1;' % name,
645*6777b538SAndroid Build Coastguard Worker                 '  }',
646*6777b538SAndroid Build Coastguard Worker                 '  *value = msg->%s_data;' % name,
647*6777b538SAndroid Build Coastguard Worker                 '  return (0);',
648*6777b538SAndroid Build Coastguard Worker                 '}' ]
649*6777b538SAndroid Build Coastguard Worker        return code
650*6777b538SAndroid Build Coastguard Worker
651*6777b538SAndroid Build Coastguard Worker    def CodeAssign(self):
652*6777b538SAndroid Build Coastguard Worker        name = self._name
653*6777b538SAndroid Build Coastguard Worker        code = """int
654*6777b538SAndroid Build Coastguard Worker%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg,
655*6777b538SAndroid Build Coastguard Worker    const %(ctype)s value)
656*6777b538SAndroid Build Coastguard Worker{
657*6777b538SAndroid Build Coastguard Worker   struct evbuffer *tmp = NULL;
658*6777b538SAndroid Build Coastguard Worker   if (msg->%(name)s_set) {
659*6777b538SAndroid Build Coastguard Worker     %(refname)s_clear(msg->%(name)s_data);
660*6777b538SAndroid Build Coastguard Worker     msg->%(name)s_set = 0;
661*6777b538SAndroid Build Coastguard Worker   } else {
662*6777b538SAndroid Build Coastguard Worker     msg->%(name)s_data = %(refname)s_new();
663*6777b538SAndroid Build Coastguard Worker     if (msg->%(name)s_data == NULL) {
664*6777b538SAndroid Build Coastguard Worker       event_warn("%%s: %(refname)s_new()", __func__);
665*6777b538SAndroid Build Coastguard Worker       goto error;
666*6777b538SAndroid Build Coastguard Worker     }
667*6777b538SAndroid Build Coastguard Worker   }
668*6777b538SAndroid Build Coastguard Worker   if ((tmp = evbuffer_new()) == NULL) {
669*6777b538SAndroid Build Coastguard Worker     event_warn("%%s: evbuffer_new()", __func__);
670*6777b538SAndroid Build Coastguard Worker     goto error;
671*6777b538SAndroid Build Coastguard Worker   }
672*6777b538SAndroid Build Coastguard Worker   %(refname)s_marshal(tmp, value);
673*6777b538SAndroid Build Coastguard Worker   if (%(refname)s_unmarshal(msg->%(name)s_data, tmp) == -1) {
674*6777b538SAndroid Build Coastguard Worker     event_warnx("%%s: %(refname)s_unmarshal", __func__);
675*6777b538SAndroid Build Coastguard Worker     goto error;
676*6777b538SAndroid Build Coastguard Worker   }
677*6777b538SAndroid Build Coastguard Worker   msg->%(name)s_set = 1;
678*6777b538SAndroid Build Coastguard Worker   evbuffer_free(tmp);
679*6777b538SAndroid Build Coastguard Worker   return (0);
680*6777b538SAndroid Build Coastguard Worker error:
681*6777b538SAndroid Build Coastguard Worker   if (tmp != NULL)
682*6777b538SAndroid Build Coastguard Worker     evbuffer_free(tmp);
683*6777b538SAndroid Build Coastguard Worker   if (msg->%(name)s_data != NULL) {
684*6777b538SAndroid Build Coastguard Worker     %(refname)s_free(msg->%(name)s_data);
685*6777b538SAndroid Build Coastguard Worker     msg->%(name)s_data = NULL;
686*6777b538SAndroid Build Coastguard Worker   }
687*6777b538SAndroid Build Coastguard Worker   return (-1);
688*6777b538SAndroid Build Coastguard Worker}""" % self.GetTranslation()
689*6777b538SAndroid Build Coastguard Worker        return code.split('\n')
690*6777b538SAndroid Build Coastguard Worker
691*6777b538SAndroid Build Coastguard Worker    def CodeComplete(self, structname):
692*6777b538SAndroid Build Coastguard Worker        if self.Optional():
693*6777b538SAndroid Build Coastguard Worker            code = [ 'if (%s->%s_set && %s_complete(%s->%s_data) == -1)' % (
694*6777b538SAndroid Build Coastguard Worker                structname, self.Name(),
695*6777b538SAndroid Build Coastguard Worker                self._refname, structname, self.Name()),
696*6777b538SAndroid Build Coastguard Worker                     '  return (-1);' ]
697*6777b538SAndroid Build Coastguard Worker        else:
698*6777b538SAndroid Build Coastguard Worker            code = [ 'if (%s_complete(%s->%s_data) == -1)' % (
699*6777b538SAndroid Build Coastguard Worker                self._refname, structname, self.Name()),
700*6777b538SAndroid Build Coastguard Worker                     '  return (-1);' ]
701*6777b538SAndroid Build Coastguard Worker
702*6777b538SAndroid Build Coastguard Worker        return code
703*6777b538SAndroid Build Coastguard Worker
704*6777b538SAndroid Build Coastguard Worker    def CodeUnmarshal(self, buf, tag_name, var_name):
705*6777b538SAndroid Build Coastguard Worker        code = ['%s->%s_data = %s_new();' % (
706*6777b538SAndroid Build Coastguard Worker            var_name, self._name, self._refname),
707*6777b538SAndroid Build Coastguard Worker                'if (%s->%s_data == NULL)' % (var_name, self._name),
708*6777b538SAndroid Build Coastguard Worker                '  return (-1);',
709*6777b538SAndroid Build Coastguard Worker                'if (evtag_unmarshal_%s(%s, %s, %s->%s_data) == -1) {' % (
710*6777b538SAndroid Build Coastguard Worker            self._refname, buf, tag_name, var_name, self._name),
711*6777b538SAndroid Build Coastguard Worker                  '  event_warnx("%%s: failed to unmarshal %s", __func__);' % (
712*6777b538SAndroid Build Coastguard Worker            self._name ),
713*6777b538SAndroid Build Coastguard Worker                '  return (-1);',
714*6777b538SAndroid Build Coastguard Worker                '}'
715*6777b538SAndroid Build Coastguard Worker                ]
716*6777b538SAndroid Build Coastguard Worker        return code
717*6777b538SAndroid Build Coastguard Worker
718*6777b538SAndroid Build Coastguard Worker    def CodeMarshal(self, buf, tag_name, var_name):
719*6777b538SAndroid Build Coastguard Worker        code = ['evtag_marshal_%s(%s, %s, %s->%s_data);' % (
720*6777b538SAndroid Build Coastguard Worker            self._refname, buf, tag_name, var_name, self._name)]
721*6777b538SAndroid Build Coastguard Worker        return code
722*6777b538SAndroid Build Coastguard Worker
723*6777b538SAndroid Build Coastguard Worker    def CodeClear(self, structname):
724*6777b538SAndroid Build Coastguard Worker        code = [ 'if (%s->%s_set == 1) {' % (structname, self.Name()),
725*6777b538SAndroid Build Coastguard Worker                 '  %s_free(%s->%s_data);' % (
726*6777b538SAndroid Build Coastguard Worker            self._refname, structname, self.Name()),
727*6777b538SAndroid Build Coastguard Worker                 '  %s->%s_data = NULL;' % (structname, self.Name()),
728*6777b538SAndroid Build Coastguard Worker                 '  %s->%s_set = 0;' % (structname, self.Name()),
729*6777b538SAndroid Build Coastguard Worker                 '}'
730*6777b538SAndroid Build Coastguard Worker                 ]
731*6777b538SAndroid Build Coastguard Worker
732*6777b538SAndroid Build Coastguard Worker        return code
733*6777b538SAndroid Build Coastguard Worker
734*6777b538SAndroid Build Coastguard Worker    def CodeNew(self, name):
735*6777b538SAndroid Build Coastguard Worker        code  = ['%s->%s_data = NULL;' % (name, self._name)]
736*6777b538SAndroid Build Coastguard Worker        return code
737*6777b538SAndroid Build Coastguard Worker
738*6777b538SAndroid Build Coastguard Worker    def CodeFree(self, name):
739*6777b538SAndroid Build Coastguard Worker        code  = ['if (%s->%s_data != NULL)' % (name, self._name),
740*6777b538SAndroid Build Coastguard Worker                 '    %s_free(%s->%s_data); ' % (
741*6777b538SAndroid Build Coastguard Worker            self._refname, name, self._name)]
742*6777b538SAndroid Build Coastguard Worker
743*6777b538SAndroid Build Coastguard Worker        return code
744*6777b538SAndroid Build Coastguard Worker
745*6777b538SAndroid Build Coastguard Worker    def Declaration(self):
746*6777b538SAndroid Build Coastguard Worker        dcl  = ['%s %s_data;' % (self._ctype, self._name)]
747*6777b538SAndroid Build Coastguard Worker
748*6777b538SAndroid Build Coastguard Worker        return dcl
749*6777b538SAndroid Build Coastguard Worker
750*6777b538SAndroid Build Coastguard Workerclass EntryVarBytes(Entry):
751*6777b538SAndroid Build Coastguard Worker    def __init__(self, type, name, tag):
752*6777b538SAndroid Build Coastguard Worker        # Init base class
753*6777b538SAndroid Build Coastguard Worker        Entry.__init__(self, type, name, tag)
754*6777b538SAndroid Build Coastguard Worker
755*6777b538SAndroid Build Coastguard Worker        self._ctype = 'ev_uint8_t *'
756*6777b538SAndroid Build Coastguard Worker
757*6777b538SAndroid Build Coastguard Worker    def GetDeclaration(self, funcname):
758*6777b538SAndroid Build Coastguard Worker        code = [ 'int %s(struct %s *, %s *, ev_uint32_t *);' % (
759*6777b538SAndroid Build Coastguard Worker            funcname, self._struct.Name(), self._ctype ) ]
760*6777b538SAndroid Build Coastguard Worker        return code
761*6777b538SAndroid Build Coastguard Worker
762*6777b538SAndroid Build Coastguard Worker    def AssignDeclaration(self, funcname):
763*6777b538SAndroid Build Coastguard Worker        code = [ 'int %s(struct %s *, const %s, ev_uint32_t);' % (
764*6777b538SAndroid Build Coastguard Worker            funcname, self._struct.Name(), self._ctype ) ]
765*6777b538SAndroid Build Coastguard Worker        return code
766*6777b538SAndroid Build Coastguard Worker
767*6777b538SAndroid Build Coastguard Worker    def CodeAssign(self):
768*6777b538SAndroid Build Coastguard Worker        name = self._name
769*6777b538SAndroid Build Coastguard Worker        code = [ 'int',
770*6777b538SAndroid Build Coastguard Worker                 '%s_%s_assign(struct %s *msg, '
771*6777b538SAndroid Build Coastguard Worker                 'const %s value, ev_uint32_t len)' % (
772*6777b538SAndroid Build Coastguard Worker            self._struct.Name(), name,
773*6777b538SAndroid Build Coastguard Worker            self._struct.Name(), self._ctype),
774*6777b538SAndroid Build Coastguard Worker                 '{',
775*6777b538SAndroid Build Coastguard Worker                 '  if (msg->%s_data != NULL)' % name,
776*6777b538SAndroid Build Coastguard Worker                 '    free (msg->%s_data);' % name,
777*6777b538SAndroid Build Coastguard Worker                 '  msg->%s_data = malloc(len);' % name,
778*6777b538SAndroid Build Coastguard Worker                 '  if (msg->%s_data == NULL)' % name,
779*6777b538SAndroid Build Coastguard Worker                 '    return (-1);',
780*6777b538SAndroid Build Coastguard Worker                 '  msg->%s_set = 1;' % name,
781*6777b538SAndroid Build Coastguard Worker                 '  msg->%s_length = len;' % name,
782*6777b538SAndroid Build Coastguard Worker                 '  memcpy(msg->%s_data, value, len);' % name,
783*6777b538SAndroid Build Coastguard Worker                 '  return (0);',
784*6777b538SAndroid Build Coastguard Worker                 '}' ]
785*6777b538SAndroid Build Coastguard Worker        return code
786*6777b538SAndroid Build Coastguard Worker
787*6777b538SAndroid Build Coastguard Worker    def CodeGet(self):
788*6777b538SAndroid Build Coastguard Worker        name = self._name
789*6777b538SAndroid Build Coastguard Worker        code = [ 'int',
790*6777b538SAndroid Build Coastguard Worker                 '%s_%s_get(struct %s *msg, %s *value, ev_uint32_t *plen)' % (
791*6777b538SAndroid Build Coastguard Worker            self._struct.Name(), name,
792*6777b538SAndroid Build Coastguard Worker            self._struct.Name(), self._ctype),
793*6777b538SAndroid Build Coastguard Worker                 '{',
794*6777b538SAndroid Build Coastguard Worker                 '  if (msg->%s_set != 1)' % name,
795*6777b538SAndroid Build Coastguard Worker                 '    return (-1);',
796*6777b538SAndroid Build Coastguard Worker                 '  *value = msg->%s_data;' % name,
797*6777b538SAndroid Build Coastguard Worker                 '  *plen = msg->%s_length;' % name,
798*6777b538SAndroid Build Coastguard Worker                 '  return (0);',
799*6777b538SAndroid Build Coastguard Worker                 '}' ]
800*6777b538SAndroid Build Coastguard Worker        return code
801*6777b538SAndroid Build Coastguard Worker
802*6777b538SAndroid Build Coastguard Worker    def CodeUnmarshal(self, buf, tag_name, var_name):
803*6777b538SAndroid Build Coastguard Worker        code = ['if (evtag_payload_length(%s, &%s->%s_length) == -1)' % (
804*6777b538SAndroid Build Coastguard Worker            buf, var_name, self._name),
805*6777b538SAndroid Build Coastguard Worker                '  return (-1);',
806*6777b538SAndroid Build Coastguard Worker                # We do not want DoS opportunities
807*6777b538SAndroid Build Coastguard Worker                'if (%s->%s_length > EVBUFFER_LENGTH(%s))' % (
808*6777b538SAndroid Build Coastguard Worker            var_name, self._name, buf),
809*6777b538SAndroid Build Coastguard Worker                '  return (-1);',
810*6777b538SAndroid Build Coastguard Worker                'if ((%s->%s_data = malloc(%s->%s_length)) == NULL)' % (
811*6777b538SAndroid Build Coastguard Worker            var_name, self._name, var_name, self._name),
812*6777b538SAndroid Build Coastguard Worker                '  return (-1);',
813*6777b538SAndroid Build Coastguard Worker                'if (evtag_unmarshal_fixed(%s, %s, %s->%s_data, '
814*6777b538SAndroid Build Coastguard Worker                '%s->%s_length) == -1) {' % (
815*6777b538SAndroid Build Coastguard Worker            buf, tag_name, var_name, self._name, var_name, self._name),
816*6777b538SAndroid Build Coastguard Worker                '  event_warnx("%%s: failed to unmarshal %s", __func__);' % (
817*6777b538SAndroid Build Coastguard Worker            self._name ),
818*6777b538SAndroid Build Coastguard Worker                '  return (-1);',
819*6777b538SAndroid Build Coastguard Worker                '}'
820*6777b538SAndroid Build Coastguard Worker                ]
821*6777b538SAndroid Build Coastguard Worker        return code
822*6777b538SAndroid Build Coastguard Worker
823*6777b538SAndroid Build Coastguard Worker    def CodeMarshal(self, buf, tag_name, var_name):
824*6777b538SAndroid Build Coastguard Worker        code = ['evtag_marshal(%s, %s, %s->%s_data, %s->%s_length);' % (
825*6777b538SAndroid Build Coastguard Worker            buf, tag_name, var_name, self._name, var_name, self._name)]
826*6777b538SAndroid Build Coastguard Worker        return code
827*6777b538SAndroid Build Coastguard Worker
828*6777b538SAndroid Build Coastguard Worker    def CodeClear(self, structname):
829*6777b538SAndroid Build Coastguard Worker        code = [ 'if (%s->%s_set == 1) {' % (structname, self.Name()),
830*6777b538SAndroid Build Coastguard Worker                 '  free (%s->%s_data);' % (structname, self.Name()),
831*6777b538SAndroid Build Coastguard Worker                 '  %s->%s_data = NULL;' % (structname, self.Name()),
832*6777b538SAndroid Build Coastguard Worker                 '  %s->%s_length = 0;' % (structname, self.Name()),
833*6777b538SAndroid Build Coastguard Worker                 '  %s->%s_set = 0;' % (structname, self.Name()),
834*6777b538SAndroid Build Coastguard Worker                 '}'
835*6777b538SAndroid Build Coastguard Worker                 ]
836*6777b538SAndroid Build Coastguard Worker
837*6777b538SAndroid Build Coastguard Worker        return code
838*6777b538SAndroid Build Coastguard Worker
839*6777b538SAndroid Build Coastguard Worker    def CodeNew(self, name):
840*6777b538SAndroid Build Coastguard Worker        code  = ['%s->%s_data = NULL;' % (name, self._name),
841*6777b538SAndroid Build Coastguard Worker                 '%s->%s_length = 0;' % (name, self._name) ]
842*6777b538SAndroid Build Coastguard Worker        return code
843*6777b538SAndroid Build Coastguard Worker
844*6777b538SAndroid Build Coastguard Worker    def CodeFree(self, name):
845*6777b538SAndroid Build Coastguard Worker        code  = ['if (%s->%s_data != NULL)' % (name, self._name),
846*6777b538SAndroid Build Coastguard Worker                 '    free (%s->%s_data); ' % (name, self._name)]
847*6777b538SAndroid Build Coastguard Worker
848*6777b538SAndroid Build Coastguard Worker        return code
849*6777b538SAndroid Build Coastguard Worker
850*6777b538SAndroid Build Coastguard Worker    def Declaration(self):
851*6777b538SAndroid Build Coastguard Worker        dcl  = ['ev_uint8_t *%s_data;' % self._name,
852*6777b538SAndroid Build Coastguard Worker                'ev_uint32_t %s_length;' % self._name]
853*6777b538SAndroid Build Coastguard Worker
854*6777b538SAndroid Build Coastguard Worker        return dcl
855*6777b538SAndroid Build Coastguard Worker
856*6777b538SAndroid Build Coastguard Workerclass EntryArray(Entry):
857*6777b538SAndroid Build Coastguard Worker    def __init__(self, entry):
858*6777b538SAndroid Build Coastguard Worker        # Init base class
859*6777b538SAndroid Build Coastguard Worker        Entry.__init__(self, entry._type, entry._name, entry._tag)
860*6777b538SAndroid Build Coastguard Worker
861*6777b538SAndroid Build Coastguard Worker        self._entry = entry
862*6777b538SAndroid Build Coastguard Worker        self._refname = entry._refname
863*6777b538SAndroid Build Coastguard Worker        self._ctype = 'struct %s *' % self._refname
864*6777b538SAndroid Build Coastguard Worker
865*6777b538SAndroid Build Coastguard Worker    def GetDeclaration(self, funcname):
866*6777b538SAndroid Build Coastguard Worker        """Allows direct access to elements of the array."""
867*6777b538SAndroid Build Coastguard Worker        translate = self.GetTranslation()
868*6777b538SAndroid Build Coastguard Worker        translate["funcname"] = funcname
869*6777b538SAndroid Build Coastguard Worker        code = [
870*6777b538SAndroid Build Coastguard Worker            'int %(funcname)s(struct %(parent_name)s *, int, %(ctype)s *);' %
871*6777b538SAndroid Build Coastguard Worker            translate ]
872*6777b538SAndroid Build Coastguard Worker        return code
873*6777b538SAndroid Build Coastguard Worker
874*6777b538SAndroid Build Coastguard Worker    def AssignDeclaration(self, funcname):
875*6777b538SAndroid Build Coastguard Worker        code = [ 'int %s(struct %s *, int, const %s);' % (
876*6777b538SAndroid Build Coastguard Worker            funcname, self._struct.Name(), self._ctype ) ]
877*6777b538SAndroid Build Coastguard Worker        return code
878*6777b538SAndroid Build Coastguard Worker
879*6777b538SAndroid Build Coastguard Worker    def AddDeclaration(self, funcname):
880*6777b538SAndroid Build Coastguard Worker        code = [ '%s %s(struct %s *);' % (
881*6777b538SAndroid Build Coastguard Worker            self._ctype, funcname, self._struct.Name() ) ]
882*6777b538SAndroid Build Coastguard Worker        return code
883*6777b538SAndroid Build Coastguard Worker
884*6777b538SAndroid Build Coastguard Worker    def CodeGet(self):
885*6777b538SAndroid Build Coastguard Worker        code = """int
886*6777b538SAndroid Build Coastguard Worker%(parent_name)s_%(name)s_get(struct %(parent_name)s *msg, int offset,
887*6777b538SAndroid Build Coastguard Worker    %(ctype)s *value)
888*6777b538SAndroid Build Coastguard Worker{
889*6777b538SAndroid Build Coastguard Worker  if (!msg->%(name)s_set || offset < 0 || offset >= msg->%(name)s_length)
890*6777b538SAndroid Build Coastguard Worker    return (-1);
891*6777b538SAndroid Build Coastguard Worker  *value = msg->%(name)s_data[offset];
892*6777b538SAndroid Build Coastguard Worker  return (0);
893*6777b538SAndroid Build Coastguard Worker}""" % self.GetTranslation()
894*6777b538SAndroid Build Coastguard Worker
895*6777b538SAndroid Build Coastguard Worker        return code.split('\n')
896*6777b538SAndroid Build Coastguard Worker
897*6777b538SAndroid Build Coastguard Worker    def CodeAssign(self):
898*6777b538SAndroid Build Coastguard Worker        code = """int
899*6777b538SAndroid Build Coastguard Worker%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg, int off,
900*6777b538SAndroid Build Coastguard Worker    const %(ctype)s value)
901*6777b538SAndroid Build Coastguard Worker{
902*6777b538SAndroid Build Coastguard Worker  struct evbuffer *tmp = NULL;
903*6777b538SAndroid Build Coastguard Worker  if (!msg->%(name)s_set || off < 0 || off >= msg->%(name)s_length)
904*6777b538SAndroid Build Coastguard Worker    return (-1);
905*6777b538SAndroid Build Coastguard Worker  %(refname)s_clear(msg->%(name)s_data[off]);
906*6777b538SAndroid Build Coastguard Worker  if ((tmp = evbuffer_new()) == NULL) {
907*6777b538SAndroid Build Coastguard Worker    event_warn("%%s: evbuffer_new()", __func__);
908*6777b538SAndroid Build Coastguard Worker    goto error;
909*6777b538SAndroid Build Coastguard Worker  }
910*6777b538SAndroid Build Coastguard Worker  %(refname)s_marshal(tmp, value);
911*6777b538SAndroid Build Coastguard Worker  if (%(refname)s_unmarshal(msg->%(name)s_data[off], tmp) == -1) {
912*6777b538SAndroid Build Coastguard Worker    event_warnx("%%s: %(refname)s_unmarshal", __func__);
913*6777b538SAndroid Build Coastguard Worker    goto error;
914*6777b538SAndroid Build Coastguard Worker  }
915*6777b538SAndroid Build Coastguard Worker  evbuffer_free(tmp);
916*6777b538SAndroid Build Coastguard Worker  return (0);
917*6777b538SAndroid Build Coastguard Workererror:
918*6777b538SAndroid Build Coastguard Worker  if (tmp != NULL)
919*6777b538SAndroid Build Coastguard Worker    evbuffer_free(tmp);
920*6777b538SAndroid Build Coastguard Worker  %(refname)s_clear(msg->%(name)s_data[off]);
921*6777b538SAndroid Build Coastguard Worker  return (-1);
922*6777b538SAndroid Build Coastguard Worker}""" % self.GetTranslation()
923*6777b538SAndroid Build Coastguard Worker
924*6777b538SAndroid Build Coastguard Worker        return code.split('\n')
925*6777b538SAndroid Build Coastguard Worker
926*6777b538SAndroid Build Coastguard Worker    def CodeAdd(self):
927*6777b538SAndroid Build Coastguard Worker        code = \
928*6777b538SAndroid Build Coastguard Worker"""%(ctype)s
929*6777b538SAndroid Build Coastguard Worker%(parent_name)s_%(name)s_add(struct %(parent_name)s *msg)
930*6777b538SAndroid Build Coastguard Worker{
931*6777b538SAndroid Build Coastguard Worker  if (++msg->%(name)s_length >= msg->%(name)s_num_allocated) {
932*6777b538SAndroid Build Coastguard Worker    int tobe_allocated = msg->%(name)s_num_allocated;
933*6777b538SAndroid Build Coastguard Worker    %(ctype)s* new_data = NULL;
934*6777b538SAndroid Build Coastguard Worker    tobe_allocated = !tobe_allocated ? 1 : tobe_allocated << 1;
935*6777b538SAndroid Build Coastguard Worker    new_data = (%(ctype)s*) realloc(msg->%(name)s_data,
936*6777b538SAndroid Build Coastguard Worker        tobe_allocated * sizeof(%(ctype)s));
937*6777b538SAndroid Build Coastguard Worker    if (new_data == NULL)
938*6777b538SAndroid Build Coastguard Worker      goto error;
939*6777b538SAndroid Build Coastguard Worker    msg->%(name)s_data = new_data;
940*6777b538SAndroid Build Coastguard Worker    msg->%(name)s_num_allocated = tobe_allocated;
941*6777b538SAndroid Build Coastguard Worker  }
942*6777b538SAndroid Build Coastguard Worker  msg->%(name)s_data[msg->%(name)s_length - 1] = %(refname)s_new();
943*6777b538SAndroid Build Coastguard Worker  if (msg->%(name)s_data[msg->%(name)s_length - 1] == NULL)
944*6777b538SAndroid Build Coastguard Worker    goto error;
945*6777b538SAndroid Build Coastguard Worker  msg->%(name)s_set = 1;
946*6777b538SAndroid Build Coastguard Worker  return (msg->%(name)s_data[msg->%(name)s_length - 1]);
947*6777b538SAndroid Build Coastguard Workererror:
948*6777b538SAndroid Build Coastguard Worker  --msg->%(name)s_length;
949*6777b538SAndroid Build Coastguard Worker  return (NULL);
950*6777b538SAndroid Build Coastguard Worker}
951*6777b538SAndroid Build Coastguard Worker        """ % self.GetTranslation()
952*6777b538SAndroid Build Coastguard Worker
953*6777b538SAndroid Build Coastguard Worker        return code.split('\n')
954*6777b538SAndroid Build Coastguard Worker
955*6777b538SAndroid Build Coastguard Worker    def CodeComplete(self, structname):
956*6777b538SAndroid Build Coastguard Worker        code = []
957*6777b538SAndroid Build Coastguard Worker        translate = self.GetTranslation()
958*6777b538SAndroid Build Coastguard Worker
959*6777b538SAndroid Build Coastguard Worker        if self.Optional():
960*6777b538SAndroid Build Coastguard Worker            code.append( 'if (%(structname)s->%(name)s_set)'  % translate)
961*6777b538SAndroid Build Coastguard Worker
962*6777b538SAndroid Build Coastguard Worker        translate["structname"] = structname
963*6777b538SAndroid Build Coastguard Worker        tmp = """{
964*6777b538SAndroid Build Coastguard Worker  int i;
965*6777b538SAndroid Build Coastguard Worker  for (i = 0; i < %(structname)s->%(name)s_length; ++i) {
966*6777b538SAndroid Build Coastguard Worker    if (%(refname)s_complete(%(structname)s->%(name)s_data[i]) == -1)
967*6777b538SAndroid Build Coastguard Worker      return (-1);
968*6777b538SAndroid Build Coastguard Worker  }
969*6777b538SAndroid Build Coastguard Worker}""" % translate
970*6777b538SAndroid Build Coastguard Worker        code.extend(tmp.split('\n'))
971*6777b538SAndroid Build Coastguard Worker
972*6777b538SAndroid Build Coastguard Worker        return code
973*6777b538SAndroid Build Coastguard Worker
974*6777b538SAndroid Build Coastguard Worker    def CodeUnmarshal(self, buf, tag_name, var_name):
975*6777b538SAndroid Build Coastguard Worker        translate = self.GetTranslation()
976*6777b538SAndroid Build Coastguard Worker        translate["var_name"] = var_name
977*6777b538SAndroid Build Coastguard Worker        translate["buf"] = buf
978*6777b538SAndroid Build Coastguard Worker        translate["tag_name"] = tag_name
979*6777b538SAndroid Build Coastguard Worker        code = """if (%(parent_name)s_%(name)s_add(%(var_name)s) == NULL)
980*6777b538SAndroid Build Coastguard Worker  return (-1);
981*6777b538SAndroid Build Coastguard Workerif (evtag_unmarshal_%(refname)s(%(buf)s, %(tag_name)s,
982*6777b538SAndroid Build Coastguard Worker  %(var_name)s->%(name)s_data[%(var_name)s->%(name)s_length - 1]) == -1) {
983*6777b538SAndroid Build Coastguard Worker  --%(var_name)s->%(name)s_length;
984*6777b538SAndroid Build Coastguard Worker  event_warnx("%%s: failed to unmarshal %(name)s", __func__);
985*6777b538SAndroid Build Coastguard Worker  return (-1);
986*6777b538SAndroid Build Coastguard Worker}""" % translate
987*6777b538SAndroid Build Coastguard Worker
988*6777b538SAndroid Build Coastguard Worker        return code.split('\n')
989*6777b538SAndroid Build Coastguard Worker
990*6777b538SAndroid Build Coastguard Worker    def CodeMarshal(self, buf, tag_name, var_name):
991*6777b538SAndroid Build Coastguard Worker        code = ['{',
992*6777b538SAndroid Build Coastguard Worker                '  int i;',
993*6777b538SAndroid Build Coastguard Worker                '  for (i = 0; i < %s->%s_length; ++i) {' % (
994*6777b538SAndroid Build Coastguard Worker            var_name, self._name),
995*6777b538SAndroid Build Coastguard Worker                '    evtag_marshal_%s(%s, %s, %s->%s_data[i]);' % (
996*6777b538SAndroid Build Coastguard Worker            self._refname, buf, tag_name, var_name, self._name),
997*6777b538SAndroid Build Coastguard Worker                '  }',
998*6777b538SAndroid Build Coastguard Worker                '}'
999*6777b538SAndroid Build Coastguard Worker                ]
1000*6777b538SAndroid Build Coastguard Worker        return code
1001*6777b538SAndroid Build Coastguard Worker
1002*6777b538SAndroid Build Coastguard Worker    def CodeClear(self, structname):
1003*6777b538SAndroid Build Coastguard Worker        code = [ 'if (%s->%s_set == 1) {' % (structname, self.Name()),
1004*6777b538SAndroid Build Coastguard Worker                 '  int i;',
1005*6777b538SAndroid Build Coastguard Worker                 '  for (i = 0; i < %s->%s_length; ++i) {' % (
1006*6777b538SAndroid Build Coastguard Worker            structname, self.Name()),
1007*6777b538SAndroid Build Coastguard Worker                 '    %s_free(%s->%s_data[i]);' % (
1008*6777b538SAndroid Build Coastguard Worker            self._refname, structname, self.Name()),
1009*6777b538SAndroid Build Coastguard Worker                 '  }',
1010*6777b538SAndroid Build Coastguard Worker                 '  free(%s->%s_data);' % (structname, self.Name()),
1011*6777b538SAndroid Build Coastguard Worker                 '  %s->%s_data = NULL;' % (structname, self.Name()),
1012*6777b538SAndroid Build Coastguard Worker                 '  %s->%s_set = 0;' % (structname, self.Name()),
1013*6777b538SAndroid Build Coastguard Worker                 '  %s->%s_length = 0;' % (structname, self.Name()),
1014*6777b538SAndroid Build Coastguard Worker                 '  %s->%s_num_allocated = 0;' % (structname, self.Name()),
1015*6777b538SAndroid Build Coastguard Worker                 '}'
1016*6777b538SAndroid Build Coastguard Worker                 ]
1017*6777b538SAndroid Build Coastguard Worker
1018*6777b538SAndroid Build Coastguard Worker        return code
1019*6777b538SAndroid Build Coastguard Worker
1020*6777b538SAndroid Build Coastguard Worker    def CodeNew(self, name):
1021*6777b538SAndroid Build Coastguard Worker        code  = ['%s->%s_data = NULL;' % (name, self._name),
1022*6777b538SAndroid Build Coastguard Worker                 '%s->%s_length = 0;' % (name, self._name),
1023*6777b538SAndroid Build Coastguard Worker                 '%s->%s_num_allocated = 0;' % (name, self._name)]
1024*6777b538SAndroid Build Coastguard Worker        return code
1025*6777b538SAndroid Build Coastguard Worker
1026*6777b538SAndroid Build Coastguard Worker    def CodeFree(self, name):
1027*6777b538SAndroid Build Coastguard Worker        code  = ['if (%s->%s_data != NULL) {' % (name, self._name),
1028*6777b538SAndroid Build Coastguard Worker                 '  int i;',
1029*6777b538SAndroid Build Coastguard Worker                 '  for (i = 0; i < %s->%s_length; ++i) {' % (
1030*6777b538SAndroid Build Coastguard Worker            name, self._name),
1031*6777b538SAndroid Build Coastguard Worker                 '    %s_free(%s->%s_data[i]); ' % (
1032*6777b538SAndroid Build Coastguard Worker            self._refname, name, self._name),
1033*6777b538SAndroid Build Coastguard Worker                 '    %s->%s_data[i] = NULL;' % (name, self._name),
1034*6777b538SAndroid Build Coastguard Worker                 '  }',
1035*6777b538SAndroid Build Coastguard Worker                 '  free(%s->%s_data);' % (name, self._name),
1036*6777b538SAndroid Build Coastguard Worker                 '  %s->%s_data = NULL;' % (name, self._name),
1037*6777b538SAndroid Build Coastguard Worker                 '  %s->%s_length = 0;' % (name, self._name),
1038*6777b538SAndroid Build Coastguard Worker                 '  %s->%s_num_allocated = 0;' % (name, self._name),
1039*6777b538SAndroid Build Coastguard Worker                 '}'
1040*6777b538SAndroid Build Coastguard Worker                 ]
1041*6777b538SAndroid Build Coastguard Worker
1042*6777b538SAndroid Build Coastguard Worker        return code
1043*6777b538SAndroid Build Coastguard Worker
1044*6777b538SAndroid Build Coastguard Worker    def Declaration(self):
1045*6777b538SAndroid Build Coastguard Worker        dcl  = ['struct %s **%s_data;' % (self._refname, self._name),
1046*6777b538SAndroid Build Coastguard Worker                'int %s_length;' % self._name,
1047*6777b538SAndroid Build Coastguard Worker                'int %s_num_allocated;' % self._name ]
1048*6777b538SAndroid Build Coastguard Worker
1049*6777b538SAndroid Build Coastguard Worker        return dcl
1050*6777b538SAndroid Build Coastguard Worker
1051*6777b538SAndroid Build Coastguard Workerdef NormalizeLine(line):
1052*6777b538SAndroid Build Coastguard Worker    global white
1053*6777b538SAndroid Build Coastguard Worker    global cppcomment
1054*6777b538SAndroid Build Coastguard Worker
1055*6777b538SAndroid Build Coastguard Worker    line = cppcomment.sub('', line)
1056*6777b538SAndroid Build Coastguard Worker    line = line.strip()
1057*6777b538SAndroid Build Coastguard Worker    line = white.sub(' ', line)
1058*6777b538SAndroid Build Coastguard Worker
1059*6777b538SAndroid Build Coastguard Worker    return line
1060*6777b538SAndroid Build Coastguard Worker
1061*6777b538SAndroid Build Coastguard Workerdef ProcessOneEntry(newstruct, entry):
1062*6777b538SAndroid Build Coastguard Worker    optional = 0
1063*6777b538SAndroid Build Coastguard Worker    array = 0
1064*6777b538SAndroid Build Coastguard Worker    entry_type = ''
1065*6777b538SAndroid Build Coastguard Worker    name = ''
1066*6777b538SAndroid Build Coastguard Worker    tag = ''
1067*6777b538SAndroid Build Coastguard Worker    tag_set = None
1068*6777b538SAndroid Build Coastguard Worker    separator = ''
1069*6777b538SAndroid Build Coastguard Worker    fixed_length = ''
1070*6777b538SAndroid Build Coastguard Worker
1071*6777b538SAndroid Build Coastguard Worker    tokens = entry.split(' ')
1072*6777b538SAndroid Build Coastguard Worker    while tokens:
1073*6777b538SAndroid Build Coastguard Worker        token = tokens[0]
1074*6777b538SAndroid Build Coastguard Worker        tokens = tokens[1:]
1075*6777b538SAndroid Build Coastguard Worker
1076*6777b538SAndroid Build Coastguard Worker        if not entry_type:
1077*6777b538SAndroid Build Coastguard Worker            if not optional and token == 'optional':
1078*6777b538SAndroid Build Coastguard Worker                optional = 1
1079*6777b538SAndroid Build Coastguard Worker                continue
1080*6777b538SAndroid Build Coastguard Worker
1081*6777b538SAndroid Build Coastguard Worker            if not array and token == 'array':
1082*6777b538SAndroid Build Coastguard Worker                array = 1
1083*6777b538SAndroid Build Coastguard Worker                continue
1084*6777b538SAndroid Build Coastguard Worker
1085*6777b538SAndroid Build Coastguard Worker        if not entry_type:
1086*6777b538SAndroid Build Coastguard Worker            entry_type = token
1087*6777b538SAndroid Build Coastguard Worker            continue
1088*6777b538SAndroid Build Coastguard Worker
1089*6777b538SAndroid Build Coastguard Worker        if not name:
1090*6777b538SAndroid Build Coastguard Worker            res = re.match(r'^([^\[\]]+)(\[.*\])?$', token)
1091*6777b538SAndroid Build Coastguard Worker            if not res:
1092*6777b538SAndroid Build Coastguard Worker                print >>sys.stderr, 'Cannot parse name: \"%s\" around %d' % (
1093*6777b538SAndroid Build Coastguard Worker                    entry, line_count)
1094*6777b538SAndroid Build Coastguard Worker                sys.exit(1)
1095*6777b538SAndroid Build Coastguard Worker            name = res.group(1)
1096*6777b538SAndroid Build Coastguard Worker            fixed_length = res.group(2)
1097*6777b538SAndroid Build Coastguard Worker            if fixed_length:
1098*6777b538SAndroid Build Coastguard Worker                fixed_length = fixed_length[1:-1]
1099*6777b538SAndroid Build Coastguard Worker            continue
1100*6777b538SAndroid Build Coastguard Worker
1101*6777b538SAndroid Build Coastguard Worker        if not separator:
1102*6777b538SAndroid Build Coastguard Worker            separator = token
1103*6777b538SAndroid Build Coastguard Worker            if separator != '=':
1104*6777b538SAndroid Build Coastguard Worker                print >>sys.stderr, 'Expected "=" after name \"%s\" got %s' % (
1105*6777b538SAndroid Build Coastguard Worker                    name, token)
1106*6777b538SAndroid Build Coastguard Worker                sys.exit(1)
1107*6777b538SAndroid Build Coastguard Worker            continue
1108*6777b538SAndroid Build Coastguard Worker
1109*6777b538SAndroid Build Coastguard Worker        if not tag_set:
1110*6777b538SAndroid Build Coastguard Worker            tag_set = 1
1111*6777b538SAndroid Build Coastguard Worker            if not re.match(r'^(0x)?[0-9]+$', token):
1112*6777b538SAndroid Build Coastguard Worker                print >>sys.stderr, 'Expected tag number: \"%s\"' % entry
1113*6777b538SAndroid Build Coastguard Worker                sys.exit(1)
1114*6777b538SAndroid Build Coastguard Worker            tag = int(token, 0)
1115*6777b538SAndroid Build Coastguard Worker            continue
1116*6777b538SAndroid Build Coastguard Worker
1117*6777b538SAndroid Build Coastguard Worker        print >>sys.stderr, 'Cannot parse \"%s\"' % entry
1118*6777b538SAndroid Build Coastguard Worker        sys.exit(1)
1119*6777b538SAndroid Build Coastguard Worker
1120*6777b538SAndroid Build Coastguard Worker    if not tag_set:
1121*6777b538SAndroid Build Coastguard Worker        print >>sys.stderr, 'Need tag number: \"%s\"' % entry
1122*6777b538SAndroid Build Coastguard Worker        sys.exit(1)
1123*6777b538SAndroid Build Coastguard Worker
1124*6777b538SAndroid Build Coastguard Worker    # Create the right entry
1125*6777b538SAndroid Build Coastguard Worker    if entry_type == 'bytes':
1126*6777b538SAndroid Build Coastguard Worker        if fixed_length:
1127*6777b538SAndroid Build Coastguard Worker            newentry = EntryBytes(entry_type, name, tag, fixed_length)
1128*6777b538SAndroid Build Coastguard Worker        else:
1129*6777b538SAndroid Build Coastguard Worker            newentry = EntryVarBytes(entry_type, name, tag)
1130*6777b538SAndroid Build Coastguard Worker    elif entry_type == 'int' and not fixed_length:
1131*6777b538SAndroid Build Coastguard Worker        newentry = EntryInt(entry_type, name, tag)
1132*6777b538SAndroid Build Coastguard Worker    elif entry_type == 'string' and not fixed_length:
1133*6777b538SAndroid Build Coastguard Worker        newentry = EntryString(entry_type, name, tag)
1134*6777b538SAndroid Build Coastguard Worker    else:
1135*6777b538SAndroid Build Coastguard Worker        res = re.match(r'^struct\[(%s)\]$' % _STRUCT_RE,
1136*6777b538SAndroid Build Coastguard Worker                       entry_type, re.IGNORECASE)
1137*6777b538SAndroid Build Coastguard Worker        if res:
1138*6777b538SAndroid Build Coastguard Worker            # References another struct defined in our file
1139*6777b538SAndroid Build Coastguard Worker            newentry = EntryStruct(entry_type, name, tag, res.group(1))
1140*6777b538SAndroid Build Coastguard Worker        else:
1141*6777b538SAndroid Build Coastguard Worker            print >>sys.stderr, 'Bad type: "%s" in "%s"' % (entry_type, entry)
1142*6777b538SAndroid Build Coastguard Worker            sys.exit(1)
1143*6777b538SAndroid Build Coastguard Worker
1144*6777b538SAndroid Build Coastguard Worker    structs = []
1145*6777b538SAndroid Build Coastguard Worker
1146*6777b538SAndroid Build Coastguard Worker    if optional:
1147*6777b538SAndroid Build Coastguard Worker        newentry.MakeOptional()
1148*6777b538SAndroid Build Coastguard Worker    if array:
1149*6777b538SAndroid Build Coastguard Worker        newentry.MakeArray()
1150*6777b538SAndroid Build Coastguard Worker
1151*6777b538SAndroid Build Coastguard Worker    newentry.SetStruct(newstruct)
1152*6777b538SAndroid Build Coastguard Worker    newentry.SetLineCount(line_count)
1153*6777b538SAndroid Build Coastguard Worker    newentry.Verify()
1154*6777b538SAndroid Build Coastguard Worker
1155*6777b538SAndroid Build Coastguard Worker    if array:
1156*6777b538SAndroid Build Coastguard Worker        # We need to encapsulate this entry into a struct
1157*6777b538SAndroid Build Coastguard Worker        newname = newentry.Name()+ '_array'
1158*6777b538SAndroid Build Coastguard Worker
1159*6777b538SAndroid Build Coastguard Worker        # Now borgify the new entry.
1160*6777b538SAndroid Build Coastguard Worker        newentry = EntryArray(newentry)
1161*6777b538SAndroid Build Coastguard Worker        newentry.SetStruct(newstruct)
1162*6777b538SAndroid Build Coastguard Worker        newentry.SetLineCount(line_count)
1163*6777b538SAndroid Build Coastguard Worker        newentry.MakeArray()
1164*6777b538SAndroid Build Coastguard Worker
1165*6777b538SAndroid Build Coastguard Worker    newstruct.AddEntry(newentry)
1166*6777b538SAndroid Build Coastguard Worker
1167*6777b538SAndroid Build Coastguard Worker    return structs
1168*6777b538SAndroid Build Coastguard Worker
1169*6777b538SAndroid Build Coastguard Workerdef ProcessStruct(data):
1170*6777b538SAndroid Build Coastguard Worker    tokens = data.split(' ')
1171*6777b538SAndroid Build Coastguard Worker
1172*6777b538SAndroid Build Coastguard Worker    # First three tokens are: 'struct' 'name' '{'
1173*6777b538SAndroid Build Coastguard Worker    newstruct = Struct(tokens[1])
1174*6777b538SAndroid Build Coastguard Worker
1175*6777b538SAndroid Build Coastguard Worker    inside = ' '.join(tokens[3:-1])
1176*6777b538SAndroid Build Coastguard Worker
1177*6777b538SAndroid Build Coastguard Worker    tokens = inside.split(';')
1178*6777b538SAndroid Build Coastguard Worker
1179*6777b538SAndroid Build Coastguard Worker    structs = []
1180*6777b538SAndroid Build Coastguard Worker
1181*6777b538SAndroid Build Coastguard Worker    for entry in tokens:
1182*6777b538SAndroid Build Coastguard Worker        entry = NormalizeLine(entry)
1183*6777b538SAndroid Build Coastguard Worker        if not entry:
1184*6777b538SAndroid Build Coastguard Worker            continue
1185*6777b538SAndroid Build Coastguard Worker
1186*6777b538SAndroid Build Coastguard Worker        # It's possible that new structs get defined in here
1187*6777b538SAndroid Build Coastguard Worker        structs.extend(ProcessOneEntry(newstruct, entry))
1188*6777b538SAndroid Build Coastguard Worker
1189*6777b538SAndroid Build Coastguard Worker    structs.append(newstruct)
1190*6777b538SAndroid Build Coastguard Worker    return structs
1191*6777b538SAndroid Build Coastguard Worker
1192*6777b538SAndroid Build Coastguard Workerdef GetNextStruct(file):
1193*6777b538SAndroid Build Coastguard Worker    global line_count
1194*6777b538SAndroid Build Coastguard Worker    global cppdirect
1195*6777b538SAndroid Build Coastguard Worker
1196*6777b538SAndroid Build Coastguard Worker    got_struct = 0
1197*6777b538SAndroid Build Coastguard Worker
1198*6777b538SAndroid Build Coastguard Worker    processed_lines = []
1199*6777b538SAndroid Build Coastguard Worker
1200*6777b538SAndroid Build Coastguard Worker    have_c_comment = 0
1201*6777b538SAndroid Build Coastguard Worker    data = ''
1202*6777b538SAndroid Build Coastguard Worker    while 1:
1203*6777b538SAndroid Build Coastguard Worker        line = file.readline()
1204*6777b538SAndroid Build Coastguard Worker        if not line:
1205*6777b538SAndroid Build Coastguard Worker            break
1206*6777b538SAndroid Build Coastguard Worker
1207*6777b538SAndroid Build Coastguard Worker        line_count += 1
1208*6777b538SAndroid Build Coastguard Worker        line = line[:-1]
1209*6777b538SAndroid Build Coastguard Worker
1210*6777b538SAndroid Build Coastguard Worker        if not have_c_comment and re.search(r'/\*', line):
1211*6777b538SAndroid Build Coastguard Worker            if re.search(r'/\*.*\*/', line):
1212*6777b538SAndroid Build Coastguard Worker                line = re.sub(r'/\*.*\*/', '', line)
1213*6777b538SAndroid Build Coastguard Worker            else:
1214*6777b538SAndroid Build Coastguard Worker                line = re.sub(r'/\*.*$', '', line)
1215*6777b538SAndroid Build Coastguard Worker                have_c_comment = 1
1216*6777b538SAndroid Build Coastguard Worker
1217*6777b538SAndroid Build Coastguard Worker        if have_c_comment:
1218*6777b538SAndroid Build Coastguard Worker            if not re.search(r'\*/', line):
1219*6777b538SAndroid Build Coastguard Worker                continue
1220*6777b538SAndroid Build Coastguard Worker            have_c_comment = 0
1221*6777b538SAndroid Build Coastguard Worker            line = re.sub(r'^.*\*/', '', line)
1222*6777b538SAndroid Build Coastguard Worker
1223*6777b538SAndroid Build Coastguard Worker        line = NormalizeLine(line)
1224*6777b538SAndroid Build Coastguard Worker
1225*6777b538SAndroid Build Coastguard Worker        if not line:
1226*6777b538SAndroid Build Coastguard Worker            continue
1227*6777b538SAndroid Build Coastguard Worker
1228*6777b538SAndroid Build Coastguard Worker        if not got_struct:
1229*6777b538SAndroid Build Coastguard Worker            if re.match(r'#include ["<].*[>"]', line):
1230*6777b538SAndroid Build Coastguard Worker                cppdirect.append(line)
1231*6777b538SAndroid Build Coastguard Worker                continue
1232*6777b538SAndroid Build Coastguard Worker
1233*6777b538SAndroid Build Coastguard Worker            if re.match(r'^#(if( |def)|endif)', line):
1234*6777b538SAndroid Build Coastguard Worker                cppdirect.append(line)
1235*6777b538SAndroid Build Coastguard Worker                continue
1236*6777b538SAndroid Build Coastguard Worker
1237*6777b538SAndroid Build Coastguard Worker            if re.match(r'^#define', line):
1238*6777b538SAndroid Build Coastguard Worker                headerdirect.append(line)
1239*6777b538SAndroid Build Coastguard Worker                continue
1240*6777b538SAndroid Build Coastguard Worker
1241*6777b538SAndroid Build Coastguard Worker            if not re.match(r'^struct %s {$' % _STRUCT_RE,
1242*6777b538SAndroid Build Coastguard Worker                            line, re.IGNORECASE):
1243*6777b538SAndroid Build Coastguard Worker                print >>sys.stderr, 'Missing struct on line %d: %s' % (
1244*6777b538SAndroid Build Coastguard Worker                    line_count, line)
1245*6777b538SAndroid Build Coastguard Worker                sys.exit(1)
1246*6777b538SAndroid Build Coastguard Worker            else:
1247*6777b538SAndroid Build Coastguard Worker                got_struct = 1
1248*6777b538SAndroid Build Coastguard Worker                data += line
1249*6777b538SAndroid Build Coastguard Worker            continue
1250*6777b538SAndroid Build Coastguard Worker
1251*6777b538SAndroid Build Coastguard Worker        # We are inside the struct
1252*6777b538SAndroid Build Coastguard Worker        tokens = line.split('}')
1253*6777b538SAndroid Build Coastguard Worker        if len(tokens) == 1:
1254*6777b538SAndroid Build Coastguard Worker            data += ' ' + line
1255*6777b538SAndroid Build Coastguard Worker            continue
1256*6777b538SAndroid Build Coastguard Worker
1257*6777b538SAndroid Build Coastguard Worker        if len(tokens[1]):
1258*6777b538SAndroid Build Coastguard Worker            print >>sys.stderr, 'Trailing garbage after struct on line %d' % (
1259*6777b538SAndroid Build Coastguard Worker                line_count )
1260*6777b538SAndroid Build Coastguard Worker            sys.exit(1)
1261*6777b538SAndroid Build Coastguard Worker
1262*6777b538SAndroid Build Coastguard Worker        # We found the end of the struct
1263*6777b538SAndroid Build Coastguard Worker        data += ' %s}' % tokens[0]
1264*6777b538SAndroid Build Coastguard Worker        break
1265*6777b538SAndroid Build Coastguard Worker
1266*6777b538SAndroid Build Coastguard Worker    # Remove any comments, that might be in there
1267*6777b538SAndroid Build Coastguard Worker    data = re.sub(r'/\*.*\*/', '', data)
1268*6777b538SAndroid Build Coastguard Worker
1269*6777b538SAndroid Build Coastguard Worker    return data
1270*6777b538SAndroid Build Coastguard Worker
1271*6777b538SAndroid Build Coastguard Worker
1272*6777b538SAndroid Build Coastguard Workerdef Parse(file):
1273*6777b538SAndroid Build Coastguard Worker    """
1274*6777b538SAndroid Build Coastguard Worker    Parses the input file and returns C code and corresponding header file.
1275*6777b538SAndroid Build Coastguard Worker    """
1276*6777b538SAndroid Build Coastguard Worker
1277*6777b538SAndroid Build Coastguard Worker    entities = []
1278*6777b538SAndroid Build Coastguard Worker
1279*6777b538SAndroid Build Coastguard Worker    while 1:
1280*6777b538SAndroid Build Coastguard Worker        # Just gets the whole struct nicely formatted
1281*6777b538SAndroid Build Coastguard Worker        data = GetNextStruct(file)
1282*6777b538SAndroid Build Coastguard Worker
1283*6777b538SAndroid Build Coastguard Worker        if not data:
1284*6777b538SAndroid Build Coastguard Worker            break
1285*6777b538SAndroid Build Coastguard Worker
1286*6777b538SAndroid Build Coastguard Worker        entities.extend(ProcessStruct(data))
1287*6777b538SAndroid Build Coastguard Worker
1288*6777b538SAndroid Build Coastguard Worker    return entities
1289*6777b538SAndroid Build Coastguard Worker
1290*6777b538SAndroid Build Coastguard Workerdef GuardName(name):
1291*6777b538SAndroid Build Coastguard Worker    name = '_'.join(name.split('.'))
1292*6777b538SAndroid Build Coastguard Worker    name = '_'.join(name.split('/'))
1293*6777b538SAndroid Build Coastguard Worker    guard = '_'+name.upper()+'_'
1294*6777b538SAndroid Build Coastguard Worker
1295*6777b538SAndroid Build Coastguard Worker    return guard
1296*6777b538SAndroid Build Coastguard Worker
1297*6777b538SAndroid Build Coastguard Workerdef HeaderPreamble(name):
1298*6777b538SAndroid Build Coastguard Worker    guard = GuardName(name)
1299*6777b538SAndroid Build Coastguard Worker    pre = (
1300*6777b538SAndroid Build Coastguard Worker        '/*\n'
1301*6777b538SAndroid Build Coastguard Worker        ' * Automatically generated from %s\n'
1302*6777b538SAndroid Build Coastguard Worker        ' */\n\n'
1303*6777b538SAndroid Build Coastguard Worker        '#ifndef %s\n'
1304*6777b538SAndroid Build Coastguard Worker        '#define %s\n\n' ) % (
1305*6777b538SAndroid Build Coastguard Worker        name, guard, guard)
1306*6777b538SAndroid Build Coastguard Worker
1307*6777b538SAndroid Build Coastguard Worker    # insert stdint.h - let's hope everyone has it
1308*6777b538SAndroid Build Coastguard Worker    pre += (
1309*6777b538SAndroid Build Coastguard Worker        '#include <event-config.h>\n'
1310*6777b538SAndroid Build Coastguard Worker        '#ifdef _EVENT_HAVE_STDINT_H\n'
1311*6777b538SAndroid Build Coastguard Worker        '#include <stdint.h>\n'
1312*6777b538SAndroid Build Coastguard Worker        '#endif\n' )
1313*6777b538SAndroid Build Coastguard Worker
1314*6777b538SAndroid Build Coastguard Worker    for statement in headerdirect:
1315*6777b538SAndroid Build Coastguard Worker        pre += '%s\n' % statement
1316*6777b538SAndroid Build Coastguard Worker    if headerdirect:
1317*6777b538SAndroid Build Coastguard Worker        pre += '\n'
1318*6777b538SAndroid Build Coastguard Worker
1319*6777b538SAndroid Build Coastguard Worker    pre += (
1320*6777b538SAndroid Build Coastguard Worker        '#define EVTAG_HAS(msg, member) ((msg)->member##_set == 1)\n'
1321*6777b538SAndroid Build Coastguard Worker        '#ifdef __GNUC__\n'
1322*6777b538SAndroid Build Coastguard Worker        '#define EVTAG_ASSIGN(msg, member, args...) '
1323*6777b538SAndroid Build Coastguard Worker        '(*(msg)->base->member##_assign)(msg, ## args)\n'
1324*6777b538SAndroid Build Coastguard Worker        '#define EVTAG_GET(msg, member, args...) '
1325*6777b538SAndroid Build Coastguard Worker        '(*(msg)->base->member##_get)(msg, ## args)\n'
1326*6777b538SAndroid Build Coastguard Worker        '#else\n'
1327*6777b538SAndroid Build Coastguard Worker        '#define EVTAG_ASSIGN(msg, member, ...) '
1328*6777b538SAndroid Build Coastguard Worker        '(*(msg)->base->member##_assign)(msg, ## __VA_ARGS__)\n'
1329*6777b538SAndroid Build Coastguard Worker        '#define EVTAG_GET(msg, member, ...) '
1330*6777b538SAndroid Build Coastguard Worker        '(*(msg)->base->member##_get)(msg, ## __VA_ARGS__)\n'
1331*6777b538SAndroid Build Coastguard Worker        '#endif\n'
1332*6777b538SAndroid Build Coastguard Worker        '#define EVTAG_ADD(msg, member) (*(msg)->base->member##_add)(msg)\n'
1333*6777b538SAndroid Build Coastguard Worker        '#define EVTAG_LEN(msg, member) ((msg)->member##_length)\n'
1334*6777b538SAndroid Build Coastguard Worker        )
1335*6777b538SAndroid Build Coastguard Worker
1336*6777b538SAndroid Build Coastguard Worker    return pre
1337*6777b538SAndroid Build Coastguard Worker
1338*6777b538SAndroid Build Coastguard Worker
1339*6777b538SAndroid Build Coastguard Workerdef HeaderPostamble(name):
1340*6777b538SAndroid Build Coastguard Worker    guard = GuardName(name)
1341*6777b538SAndroid Build Coastguard Worker    return '#endif  /* %s */' % guard
1342*6777b538SAndroid Build Coastguard Worker
1343*6777b538SAndroid Build Coastguard Workerdef BodyPreamble(name):
1344*6777b538SAndroid Build Coastguard Worker    global _NAME
1345*6777b538SAndroid Build Coastguard Worker    global _VERSION
1346*6777b538SAndroid Build Coastguard Worker
1347*6777b538SAndroid Build Coastguard Worker    header_file = '.'.join(name.split('.')[:-1]) + '.gen.h'
1348*6777b538SAndroid Build Coastguard Worker
1349*6777b538SAndroid Build Coastguard Worker    pre = ( '/*\n'
1350*6777b538SAndroid Build Coastguard Worker            ' * Automatically generated from %s\n'
1351*6777b538SAndroid Build Coastguard Worker            ' * by %s/%s.  DO NOT EDIT THIS FILE.\n'
1352*6777b538SAndroid Build Coastguard Worker            ' */\n\n' ) % (name, _NAME, _VERSION)
1353*6777b538SAndroid Build Coastguard Worker    pre += ( '#include <sys/types.h>\n'
1354*6777b538SAndroid Build Coastguard Worker             '#ifdef _EVENT_HAVE_SYS_TIME_H\n'
1355*6777b538SAndroid Build Coastguard Worker             '#include <sys/time.h>\n'
1356*6777b538SAndroid Build Coastguard Worker             '#endif\n'
1357*6777b538SAndroid Build Coastguard Worker             '#include <stdlib.h>\n'
1358*6777b538SAndroid Build Coastguard Worker             '#include <string.h>\n'
1359*6777b538SAndroid Build Coastguard Worker             '#include <assert.h>\n'
1360*6777b538SAndroid Build Coastguard Worker             '#define EVENT_NO_STRUCT\n'
1361*6777b538SAndroid Build Coastguard Worker             '#include <event.h>\n\n'
1362*6777b538SAndroid Build Coastguard Worker             '#ifdef _EVENT___func__\n'
1363*6777b538SAndroid Build Coastguard Worker             '#define __func__ _EVENT___func__\n'
1364*6777b538SAndroid Build Coastguard Worker             '#endif\n' )
1365*6777b538SAndroid Build Coastguard Worker
1366*6777b538SAndroid Build Coastguard Worker    for statement in cppdirect:
1367*6777b538SAndroid Build Coastguard Worker        pre += '%s\n' % statement
1368*6777b538SAndroid Build Coastguard Worker
1369*6777b538SAndroid Build Coastguard Worker    pre += '\n#include "%s"\n\n' % header_file
1370*6777b538SAndroid Build Coastguard Worker
1371*6777b538SAndroid Build Coastguard Worker    pre += 'void event_err(int eval, const char *fmt, ...);\n'
1372*6777b538SAndroid Build Coastguard Worker    pre += 'void event_warn(const char *fmt, ...);\n'
1373*6777b538SAndroid Build Coastguard Worker    pre += 'void event_errx(int eval, const char *fmt, ...);\n'
1374*6777b538SAndroid Build Coastguard Worker    pre += 'void event_warnx(const char *fmt, ...);\n\n'
1375*6777b538SAndroid Build Coastguard Worker
1376*6777b538SAndroid Build Coastguard Worker    return pre
1377*6777b538SAndroid Build Coastguard Worker
1378*6777b538SAndroid Build Coastguard Workerdef main(argv):
1379*6777b538SAndroid Build Coastguard Worker    if len(argv) < 2 or not argv[1]:
1380*6777b538SAndroid Build Coastguard Worker        print >>sys.stderr, 'Need RPC description file as first argument.'
1381*6777b538SAndroid Build Coastguard Worker        sys.exit(1)
1382*6777b538SAndroid Build Coastguard Worker
1383*6777b538SAndroid Build Coastguard Worker    filename = argv[1]
1384*6777b538SAndroid Build Coastguard Worker
1385*6777b538SAndroid Build Coastguard Worker    ext = filename.split('.')[-1]
1386*6777b538SAndroid Build Coastguard Worker    if ext != 'rpc':
1387*6777b538SAndroid Build Coastguard Worker        print >>sys.stderr, 'Unrecognized file extension: %s' % ext
1388*6777b538SAndroid Build Coastguard Worker        sys.exit(1)
1389*6777b538SAndroid Build Coastguard Worker
1390*6777b538SAndroid Build Coastguard Worker    print >>sys.stderr, 'Reading \"%s\"' % filename
1391*6777b538SAndroid Build Coastguard Worker
1392*6777b538SAndroid Build Coastguard Worker    fp = open(filename, 'r')
1393*6777b538SAndroid Build Coastguard Worker    entities = Parse(fp)
1394*6777b538SAndroid Build Coastguard Worker    fp.close()
1395*6777b538SAndroid Build Coastguard Worker
1396*6777b538SAndroid Build Coastguard Worker    header_file = '.'.join(filename.split('.')[:-1]) + '.gen.h'
1397*6777b538SAndroid Build Coastguard Worker    impl_file = '.'.join(filename.split('.')[:-1]) + '.gen.c'
1398*6777b538SAndroid Build Coastguard Worker
1399*6777b538SAndroid Build Coastguard Worker    print >>sys.stderr, '... creating "%s"' % header_file
1400*6777b538SAndroid Build Coastguard Worker    header_fp = open(header_file, 'w')
1401*6777b538SAndroid Build Coastguard Worker    print >>header_fp, HeaderPreamble(filename)
1402*6777b538SAndroid Build Coastguard Worker
1403*6777b538SAndroid Build Coastguard Worker    # Create forward declarations: allows other structs to reference
1404*6777b538SAndroid Build Coastguard Worker    # each other
1405*6777b538SAndroid Build Coastguard Worker    for entry in entities:
1406*6777b538SAndroid Build Coastguard Worker        entry.PrintForwardDeclaration(header_fp)
1407*6777b538SAndroid Build Coastguard Worker    print >>header_fp, ''
1408*6777b538SAndroid Build Coastguard Worker
1409*6777b538SAndroid Build Coastguard Worker    for entry in entities:
1410*6777b538SAndroid Build Coastguard Worker        entry.PrintTags(header_fp)
1411*6777b538SAndroid Build Coastguard Worker        entry.PrintDeclaration(header_fp)
1412*6777b538SAndroid Build Coastguard Worker    print >>header_fp, HeaderPostamble(filename)
1413*6777b538SAndroid Build Coastguard Worker    header_fp.close()
1414*6777b538SAndroid Build Coastguard Worker
1415*6777b538SAndroid Build Coastguard Worker    print >>sys.stderr, '... creating "%s"' % impl_file
1416*6777b538SAndroid Build Coastguard Worker    impl_fp = open(impl_file, 'w')
1417*6777b538SAndroid Build Coastguard Worker    print >>impl_fp, BodyPreamble(filename)
1418*6777b538SAndroid Build Coastguard Worker    for entry in entities:
1419*6777b538SAndroid Build Coastguard Worker        entry.PrintCode(impl_fp)
1420*6777b538SAndroid Build Coastguard Worker    impl_fp.close()
1421*6777b538SAndroid Build Coastguard Worker
1422*6777b538SAndroid Build Coastguard Workerif __name__ == '__main__':
1423*6777b538SAndroid Build Coastguard Worker    main(sys.argv)
1424