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