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