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