1532a8cc3SKiyoshi Aman#!/usr/bin/env python 2c4e60994SNiels Provos# 3e49e2891SNick Mathewson# Copyright (c) 2005-2007 Niels Provos <[email protected]> 4e49e2891SNick Mathewson# Copyright (c) 2007-2012 Niels Provos and Nick Mathewson 5949cbd12SNiels Provos# All rights reserved. 6949cbd12SNiels Provos# 7226fd50aSNiels Provos# Generates marshaling code based on libevent. 8949cbd12SNiels Provos 9f0ded5f3SAzat Khuzhin# pylint: disable=too-many-lines 10f0ded5f3SAzat Khuzhin# pylint: disable=too-many-branches 11f0ded5f3SAzat Khuzhin# pylint: disable=too-many-public-methods 12f0ded5f3SAzat Khuzhin# pylint: disable=too-many-statements 13f0ded5f3SAzat Khuzhin# pylint: disable=global-statement 146469598eSNiels Provos 15f0ded5f3SAzat Khuzhin# TODO: 16f0ded5f3SAzat Khuzhin# 1) propagate the arguments/options parsed by argparse down to the 17f0ded5f3SAzat Khuzhin# instantiated factory objects. 18f0ded5f3SAzat Khuzhin# 2) move the globals into a class that manages execution, including the 19f0ded5f3SAzat Khuzhin# progress outputs that go to stderr at the moment. 20f0ded5f3SAzat Khuzhin# 3) emit other languages. 21f0ded5f3SAzat Khuzhin 22f0ded5f3SAzat Khuzhinimport argparse 23949cbd12SNiels Provosimport re 24f0ded5f3SAzat Khuzhinimport sys 25949cbd12SNiels Provos 26949cbd12SNiels Provos_NAME = "event_rpcgen.py" 27949cbd12SNiels Provos_VERSION = "0.1" 28949cbd12SNiels Provos 29949cbd12SNiels Provos# Globals 30f0ded5f3SAzat KhuzhinLINE_COUNT = 0 31949cbd12SNiels Provos 32f0ded5f3SAzat KhuzhinCPPCOMMENT_RE = re.compile(r"\/\/.*$") 33f0ded5f3SAzat KhuzhinNONIDENT_RE = re.compile(r"\W") 34f0ded5f3SAzat KhuzhinPREPROCESSOR_DEF_RE = re.compile(r"^#define") 35f0ded5f3SAzat KhuzhinSTRUCT_REF_RE = re.compile(r"^struct\[(?P<name>[a-zA-Z_][a-zA-Z0-9_]*)\]$") 36f0ded5f3SAzat KhuzhinSTRUCT_DEF_RE = re.compile(r"^struct +[a-zA-Z_][a-zA-Z0-9_]* *{$") 37f0ded5f3SAzat KhuzhinWHITESPACE_RE = re.compile(r"\s+") 386469598eSNiels Provos 39f0ded5f3SAzat KhuzhinHEADER_DIRECT = [] 40f0ded5f3SAzat KhuzhinCPP_DIRECT = [] 41949cbd12SNiels Provos 42f0ded5f3SAzat KhuzhinQUIETLY = False 43f0ded5f3SAzat Khuzhin 44aa59c1e9SNick Mathewson 45aa59c1e9SNick Mathewsondef declare(s): 46aa59c1e9SNick Mathewson if not QUIETLY: 47532a8cc3SKiyoshi Aman print(s) 48aa59c1e9SNick Mathewson 49f0ded5f3SAzat Khuzhin 5068725dc8SNiels Provosdef TranslateList(mylist, mydict): 51532a8cc3SKiyoshi Aman return [x % mydict for x in mylist] 5268725dc8SNiels Provos 53f0ded5f3SAzat Khuzhin 5437d3e16cSNiels Provosclass RpcGenError(Exception): 55f0ded5f3SAzat Khuzhin """An Exception class for parse errors.""" 56f0ded5f3SAzat Khuzhin 57f0ded5f3SAzat Khuzhin def __init__(self, why): # pylint: disable=super-init-not-called 5837d3e16cSNiels Provos self.why = why 59f0ded5f3SAzat Khuzhin 6037d3e16cSNiels Provos def __str__(self): 6137d3e16cSNiels Provos return str(self.why) 6237d3e16cSNiels Provos 63f0ded5f3SAzat Khuzhin 64949cbd12SNiels Provos# Holds everything that makes a struct 65*48e04887SEnji Cooperclass Struct(object): 66949cbd12SNiels Provos def __init__(self, name): 67949cbd12SNiels Provos self._name = name 68949cbd12SNiels Provos self._entries = [] 69949cbd12SNiels Provos self._tags = {} 70f0ded5f3SAzat Khuzhin declare(" Created struct: %s" % name) 71949cbd12SNiels Provos 72949cbd12SNiels Provos def AddEntry(self, entry): 73532a8cc3SKiyoshi Aman if entry.Tag() in self._tags: 7437d3e16cSNiels Provos raise RpcGenError( 7537d3e16cSNiels Provos 'Entry "%s" duplicates tag number %d from "%s" ' 76f0ded5f3SAzat Khuzhin "around line %d" 77f0ded5f3SAzat Khuzhin % (entry.Name(), entry.Tag(), self._tags[entry.Tag()], LINE_COUNT) 78f0ded5f3SAzat Khuzhin ) 79949cbd12SNiels Provos self._entries.append(entry) 80949cbd12SNiels Provos self._tags[entry.Tag()] = entry.Name() 81f0ded5f3SAzat Khuzhin declare(" Added entry: %s" % entry.Name()) 82949cbd12SNiels Provos 83949cbd12SNiels Provos def Name(self): 84949cbd12SNiels Provos return self._name 85949cbd12SNiels Provos 86949cbd12SNiels Provos def EntryTagName(self, entry): 87b4ab56dcSNiels Provos """Creates the name inside an enumeration for distinguishing data 88b4ab56dcSNiels Provos types.""" 89949cbd12SNiels Provos name = "%s_%s" % (self._name, entry.Name()) 90949cbd12SNiels Provos return name.upper() 91949cbd12SNiels Provos 92f0ded5f3SAzat Khuzhin @staticmethod 93f0ded5f3SAzat Khuzhin def PrintIndented(filep, ident, code): 94812d2fd8SNiels Provos """Takes an array, add indentation to each entry and prints it.""" 95812d2fd8SNiels Provos for entry in code: 96f0ded5f3SAzat Khuzhin filep.write("%s%s\n" % (ident, entry)) 97f0ded5f3SAzat Khuzhin 98812d2fd8SNiels Provos 99a7e39551SNiels Provosclass StructCCode(Struct): 100a7e39551SNiels Provos """ Knows how to generate C code for a struct """ 101a7e39551SNiels Provos 102a7e39551SNiels Provos def __init__(self, name): 103a7e39551SNiels Provos Struct.__init__(self, name) 104a7e39551SNiels Provos 105f0ded5f3SAzat Khuzhin def PrintTags(self, filep): 106b4ab56dcSNiels Provos """Prints the tag definitions for a structure.""" 107f0ded5f3SAzat Khuzhin filep.write("/* Tag definition for %s */\n" % self._name) 108f0ded5f3SAzat Khuzhin filep.write("enum %s_ {\n" % self._name.lower()) 109949cbd12SNiels Provos for entry in self._entries: 110f0ded5f3SAzat Khuzhin filep.write(" %s=%d,\n" % (self.EntryTagName(entry), entry.Tag())) 111f0ded5f3SAzat Khuzhin filep.write(" %s_MAX_TAGS\n" % (self._name.upper())) 112f0ded5f3SAzat Khuzhin filep.write("};\n\n") 113949cbd12SNiels Provos 114f0ded5f3SAzat Khuzhin def PrintForwardDeclaration(self, filep): 115f0ded5f3SAzat Khuzhin filep.write("struct %s;\n" % self._name) 116949cbd12SNiels Provos 117f0ded5f3SAzat Khuzhin def PrintDeclaration(self, filep): 118f0ded5f3SAzat Khuzhin filep.write("/* Structure declaration for %s */\n" % self._name) 119f0ded5f3SAzat Khuzhin filep.write("struct %s_access_ {\n" % self._name) 120949cbd12SNiels Provos for entry in self._entries: 121f0ded5f3SAzat Khuzhin dcl = entry.AssignDeclaration("(*%s_assign)" % entry.Name()) 122f0ded5f3SAzat Khuzhin dcl.extend(entry.GetDeclaration("(*%s_get)" % entry.Name())) 123b4ab56dcSNiels Provos if entry.Array(): 124f0ded5f3SAzat Khuzhin dcl.extend(entry.AddDeclaration("(*%s_add)" % entry.Name())) 125f0ded5f3SAzat Khuzhin self.PrintIndented(filep, " ", dcl) 126f0ded5f3SAzat Khuzhin filep.write("};\n\n") 1273b345f3eSNiels Provos 128f0ded5f3SAzat Khuzhin filep.write("struct %s {\n" % self._name) 129f0ded5f3SAzat Khuzhin filep.write(" struct %s_access_ *base;\n\n" % self._name) 1303b345f3eSNiels Provos for entry in self._entries: 1313b345f3eSNiels Provos dcl = entry.Declaration() 132f0ded5f3SAzat Khuzhin self.PrintIndented(filep, " ", dcl) 133f0ded5f3SAzat Khuzhin filep.write("\n") 134949cbd12SNiels Provos for entry in self._entries: 135f0ded5f3SAzat Khuzhin filep.write(" ev_uint8_t %s_set;\n" % entry.Name()) 136f0ded5f3SAzat Khuzhin filep.write("};\n\n") 137949cbd12SNiels Provos 138f0ded5f3SAzat Khuzhin filep.write( 139f0ded5f3SAzat Khuzhin """struct %(name)s *%(name)s_new(void); 140755fbf16SShuo Chenstruct %(name)s *%(name)s_new_with_arg(void *); 1413c1a6a68SNiels Provosvoid %(name)s_free(struct %(name)s *); 1423c1a6a68SNiels Provosvoid %(name)s_clear(struct %(name)s *); 1433c1a6a68SNiels Provosvoid %(name)s_marshal(struct evbuffer *, const struct %(name)s *); 1443c1a6a68SNiels Provosint %(name)s_unmarshal(struct %(name)s *, struct evbuffer *); 1453c1a6a68SNiels Provosint %(name)s_complete(struct %(name)s *); 14611230f7eSNick Mathewsonvoid evtag_marshal_%(name)s(struct evbuffer *, ev_uint32_t, 1473c1a6a68SNiels Provos const struct %(name)s *); 14811230f7eSNick Mathewsonint evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t, 149f0ded5f3SAzat Khuzhin struct %(name)s *);\n""" 150f0ded5f3SAzat Khuzhin % {"name": self._name} 151f0ded5f3SAzat Khuzhin ) 152949cbd12SNiels Provos 153949cbd12SNiels Provos # Write a setting function of every variable 154949cbd12SNiels Provos for entry in self._entries: 155f0ded5f3SAzat Khuzhin self.PrintIndented( 156f0ded5f3SAzat Khuzhin filep, "", entry.AssignDeclaration(entry.AssignFuncName()) 157f0ded5f3SAzat Khuzhin ) 158f0ded5f3SAzat Khuzhin self.PrintIndented(filep, "", entry.GetDeclaration(entry.GetFuncName())) 159b4ab56dcSNiels Provos if entry.Array(): 160f0ded5f3SAzat Khuzhin self.PrintIndented(filep, "", entry.AddDeclaration(entry.AddFuncName())) 161949cbd12SNiels Provos 162f0ded5f3SAzat Khuzhin filep.write("/* --- %s done --- */\n\n" % self._name) 163949cbd12SNiels Provos 164f0ded5f3SAzat Khuzhin def PrintCode(self, filep): 165f0ded5f3SAzat Khuzhin filep.write( 166f0ded5f3SAzat Khuzhin """/* 167f0ded5f3SAzat Khuzhin * Implementation of %s 168f0ded5f3SAzat Khuzhin */ 169f0ded5f3SAzat Khuzhin""" 170f0ded5f3SAzat Khuzhin % (self._name) 171f0ded5f3SAzat Khuzhin ) 172949cbd12SNiels Provos 173f0ded5f3SAzat Khuzhin filep.write( 174f0ded5f3SAzat Khuzhin """ 175f0ded5f3SAzat Khuzhinstatic struct %(name)s_access_ %(name)s_base__ = { 176f0ded5f3SAzat Khuzhin""" 177f0ded5f3SAzat Khuzhin % {"name": self._name} 178f0ded5f3SAzat Khuzhin ) 1793b345f3eSNiels Provos for entry in self._entries: 180f0ded5f3SAzat Khuzhin self.PrintIndented(filep, " ", entry.CodeBase()) 181f0ded5f3SAzat Khuzhin filep.write("};\n\n") 1823b345f3eSNiels Provos 183949cbd12SNiels Provos # Creation 184f0ded5f3SAzat Khuzhin filep.write( 185f0ded5f3SAzat Khuzhin """struct %(name)s * 186f0ded5f3SAzat Khuzhin%(name)s_new(void) 187f0ded5f3SAzat Khuzhin{ 188f0ded5f3SAzat Khuzhin return %(name)s_new_with_arg(NULL); 189f0ded5f3SAzat Khuzhin} 190f0ded5f3SAzat Khuzhin 191f0ded5f3SAzat Khuzhinstruct %(name)s * 192f0ded5f3SAzat Khuzhin%(name)s_new_with_arg(void *unused) 193f0ded5f3SAzat Khuzhin{ 194f0ded5f3SAzat Khuzhin struct %(name)s *tmp; 195f0ded5f3SAzat Khuzhin if ((tmp = malloc(sizeof(struct %(name)s))) == NULL) { 196f0ded5f3SAzat Khuzhin event_warn("%%s: malloc", __func__); 197f0ded5f3SAzat Khuzhin return (NULL); 198f0ded5f3SAzat Khuzhin } 199f0ded5f3SAzat Khuzhin tmp->base = &%(name)s_base__; 200f0ded5f3SAzat Khuzhin 201f0ded5f3SAzat Khuzhin""" 202f0ded5f3SAzat Khuzhin % {"name": self._name} 203f0ded5f3SAzat Khuzhin ) 2043c1a6a68SNiels Provos 205949cbd12SNiels Provos for entry in self._entries: 206f0ded5f3SAzat Khuzhin self.PrintIndented(filep, " ", entry.CodeInitialize("tmp")) 207f0ded5f3SAzat Khuzhin filep.write(" tmp->%s_set = 0;\n\n" % entry.Name()) 208949cbd12SNiels Provos 209f0ded5f3SAzat Khuzhin filep.write( 210f0ded5f3SAzat Khuzhin """ return (tmp); 211f0ded5f3SAzat Khuzhin} 212f0ded5f3SAzat Khuzhin 213f0ded5f3SAzat Khuzhin""" 214f0ded5f3SAzat Khuzhin ) 215949cbd12SNiels Provos 216b4ab56dcSNiels Provos # Adding 217b4ab56dcSNiels Provos for entry in self._entries: 218b4ab56dcSNiels Provos if entry.Array(): 219f0ded5f3SAzat Khuzhin self.PrintIndented(filep, "", entry.CodeAdd()) 220f0ded5f3SAzat Khuzhin filep.write("\n") 221b4ab56dcSNiels Provos 222949cbd12SNiels Provos # Assigning 223949cbd12SNiels Provos for entry in self._entries: 224f0ded5f3SAzat Khuzhin self.PrintIndented(filep, "", entry.CodeAssign()) 225f0ded5f3SAzat Khuzhin filep.write("\n") 226949cbd12SNiels Provos 227949cbd12SNiels Provos # Getting 228949cbd12SNiels Provos for entry in self._entries: 229f0ded5f3SAzat Khuzhin self.PrintIndented(filep, "", entry.CodeGet()) 230f0ded5f3SAzat Khuzhin filep.write("\n") 231949cbd12SNiels Provos 232949cbd12SNiels Provos # Clearing 233f0ded5f3SAzat Khuzhin filep.write( 234f0ded5f3SAzat Khuzhin """void 235f0ded5f3SAzat Khuzhin%(name)s_clear(struct %(name)s *tmp) 236f0ded5f3SAzat Khuzhin{ 237f0ded5f3SAzat Khuzhin""" 238f0ded5f3SAzat Khuzhin % {"name": self._name} 239f0ded5f3SAzat Khuzhin ) 240949cbd12SNiels Provos for entry in self._entries: 241f0ded5f3SAzat Khuzhin self.PrintIndented(filep, " ", entry.CodeClear("tmp")) 242949cbd12SNiels Provos 243f0ded5f3SAzat Khuzhin filep.write("}\n\n") 244949cbd12SNiels Provos 245949cbd12SNiels Provos # Freeing 246f0ded5f3SAzat Khuzhin filep.write( 247f0ded5f3SAzat Khuzhin """void 248f0ded5f3SAzat Khuzhin%(name)s_free(struct %(name)s *tmp) 249f0ded5f3SAzat Khuzhin{ 250f0ded5f3SAzat Khuzhin""" 251f0ded5f3SAzat Khuzhin % {"name": self._name} 252f0ded5f3SAzat Khuzhin ) 2533c1a6a68SNiels Provos 254949cbd12SNiels Provos for entry in self._entries: 255f0ded5f3SAzat Khuzhin self.PrintIndented(filep, " ", entry.CodeFree("tmp")) 256949cbd12SNiels Provos 257f0ded5f3SAzat Khuzhin filep.write( 258f0ded5f3SAzat Khuzhin """ free(tmp); 259f0ded5f3SAzat Khuzhin} 260f0ded5f3SAzat Khuzhin 261f0ded5f3SAzat Khuzhin""" 262f0ded5f3SAzat Khuzhin ) 263949cbd12SNiels Provos 264949cbd12SNiels Provos # Marshaling 265f0ded5f3SAzat Khuzhin filep.write( 266f0ded5f3SAzat Khuzhin """void 267f0ded5f3SAzat Khuzhin%(name)s_marshal(struct evbuffer *evbuf, const struct %(name)s *tmp) { 268f0ded5f3SAzat Khuzhin""" 269f0ded5f3SAzat Khuzhin % {"name": self._name} 270f0ded5f3SAzat Khuzhin ) 271949cbd12SNiels Provos for entry in self._entries: 272f0ded5f3SAzat Khuzhin indent = " " 273949cbd12SNiels Provos # Optional entries do not have to be set 274949cbd12SNiels Provos if entry.Optional(): 275f0ded5f3SAzat Khuzhin indent += " " 276f0ded5f3SAzat Khuzhin filep.write(" if (tmp->%s_set) {\n" % entry.Name()) 27768725dc8SNiels Provos self.PrintIndented( 278f0ded5f3SAzat Khuzhin filep, 279f0ded5f3SAzat Khuzhin indent, 280f0ded5f3SAzat Khuzhin entry.CodeMarshal( 281f0ded5f3SAzat Khuzhin "evbuf", 282f0ded5f3SAzat Khuzhin self.EntryTagName(entry), 283f0ded5f3SAzat Khuzhin entry.GetVarName("tmp"), 284f0ded5f3SAzat Khuzhin entry.GetVarLen("tmp"), 285f0ded5f3SAzat Khuzhin ), 286f0ded5f3SAzat Khuzhin ) 287949cbd12SNiels Provos if entry.Optional(): 288f0ded5f3SAzat Khuzhin filep.write(" }\n") 289949cbd12SNiels Provos 290f0ded5f3SAzat Khuzhin filep.write("}\n\n") 291949cbd12SNiels Provos 292949cbd12SNiels Provos # Unmarshaling 293f0ded5f3SAzat Khuzhin filep.write( 294f0ded5f3SAzat Khuzhin """int 295f0ded5f3SAzat Khuzhin%(name)s_unmarshal(struct %(name)s *tmp, struct evbuffer *evbuf) 296f0ded5f3SAzat Khuzhin{ 297f0ded5f3SAzat Khuzhin ev_uint32_t tag; 298f0ded5f3SAzat Khuzhin while (evbuffer_get_length(evbuf) > 0) { 299f0ded5f3SAzat Khuzhin if (evtag_peek(evbuf, &tag) == -1) 300f0ded5f3SAzat Khuzhin return (-1); 301f0ded5f3SAzat Khuzhin switch (tag) { 302f0ded5f3SAzat Khuzhin 303f0ded5f3SAzat Khuzhin""" 304f0ded5f3SAzat Khuzhin % {"name": self._name} 305f0ded5f3SAzat Khuzhin ) 306949cbd12SNiels Provos for entry in self._entries: 307f0ded5f3SAzat Khuzhin filep.write(" case %s:\n" % (self.EntryTagName(entry))) 308b4ab56dcSNiels Provos if not entry.Array(): 309f0ded5f3SAzat Khuzhin filep.write( 310f0ded5f3SAzat Khuzhin """ if (tmp->%s_set) 311f0ded5f3SAzat Khuzhin return (-1); 312f0ded5f3SAzat Khuzhin""" 313f0ded5f3SAzat Khuzhin % (entry.Name()) 314f0ded5f3SAzat Khuzhin ) 315b4ab56dcSNiels Provos 31668725dc8SNiels Provos self.PrintIndented( 317f0ded5f3SAzat Khuzhin filep, 318f0ded5f3SAzat Khuzhin " ", 319f0ded5f3SAzat Khuzhin entry.CodeUnmarshal( 320f0ded5f3SAzat Khuzhin "evbuf", 32168725dc8SNiels Provos self.EntryTagName(entry), 322f0ded5f3SAzat Khuzhin entry.GetVarName("tmp"), 323f0ded5f3SAzat Khuzhin entry.GetVarLen("tmp"), 324f0ded5f3SAzat Khuzhin ), 325f0ded5f3SAzat Khuzhin ) 326949cbd12SNiels Provos 327f0ded5f3SAzat Khuzhin filep.write( 328f0ded5f3SAzat Khuzhin """ tmp->%s_set = 1; 329f0ded5f3SAzat Khuzhin break; 330f0ded5f3SAzat Khuzhin""" 331f0ded5f3SAzat Khuzhin % (entry.Name()) 332f0ded5f3SAzat Khuzhin ) 333f0ded5f3SAzat Khuzhin filep.write( 334f0ded5f3SAzat Khuzhin """ default: 335f0ded5f3SAzat Khuzhin return -1; 336f0ded5f3SAzat Khuzhin } 337f0ded5f3SAzat Khuzhin } 338f0ded5f3SAzat Khuzhin 339f0ded5f3SAzat Khuzhin""" 340f0ded5f3SAzat Khuzhin ) 341949cbd12SNiels Provos # Check if it was decoded completely 342f0ded5f3SAzat Khuzhin filep.write( 343f0ded5f3SAzat Khuzhin """ if (%(name)s_complete(tmp) == -1) 344f0ded5f3SAzat Khuzhin return (-1); 345f0ded5f3SAzat Khuzhin return (0); 346f0ded5f3SAzat Khuzhin} 347f0ded5f3SAzat Khuzhin""" 348f0ded5f3SAzat Khuzhin % {"name": self._name} 349f0ded5f3SAzat Khuzhin ) 350949cbd12SNiels Provos 351949cbd12SNiels Provos # Checking if a structure has all the required data 352f0ded5f3SAzat Khuzhin filep.write( 353f0ded5f3SAzat Khuzhin """ 354f0ded5f3SAzat Khuzhinint 355f0ded5f3SAzat Khuzhin%(name)s_complete(struct %(name)s *msg) 356f0ded5f3SAzat Khuzhin{ 357f0ded5f3SAzat Khuzhin""" 358f0ded5f3SAzat Khuzhin % {"name": self._name} 359f0ded5f3SAzat Khuzhin ) 360949cbd12SNiels Provos for entry in self._entries: 36168725dc8SNiels Provos if not entry.Optional(): 36268725dc8SNiels Provos code = [ 363f0ded5f3SAzat Khuzhin """if (!msg->%(name)s_set) 364f0ded5f3SAzat Khuzhin return (-1);""" 365f0ded5f3SAzat Khuzhin ] 36668725dc8SNiels Provos code = TranslateList(code, entry.GetTranslation()) 367f0ded5f3SAzat Khuzhin self.PrintIndented(filep, " ", code) 36868725dc8SNiels Provos 36968725dc8SNiels Provos self.PrintIndented( 370f0ded5f3SAzat Khuzhin filep, " ", entry.CodeComplete("msg", entry.GetVarName("msg")) 371f0ded5f3SAzat Khuzhin ) 372f0ded5f3SAzat Khuzhin filep.write( 373f0ded5f3SAzat Khuzhin """ return (0); 374f0ded5f3SAzat Khuzhin} 375f0ded5f3SAzat Khuzhin""" 376f0ded5f3SAzat Khuzhin ) 377949cbd12SNiels Provos 378949cbd12SNiels Provos # Complete message unmarshaling 379f0ded5f3SAzat Khuzhin filep.write( 380f0ded5f3SAzat Khuzhin """ 381f0ded5f3SAzat Khuzhinint 382f0ded5f3SAzat Khuzhinevtag_unmarshal_%(name)s(struct evbuffer *evbuf, ev_uint32_t need_tag, 383f0ded5f3SAzat Khuzhin struct %(name)s *msg) 384f0ded5f3SAzat Khuzhin{ 385f0ded5f3SAzat Khuzhin ev_uint32_t tag; 386f0ded5f3SAzat Khuzhin int res = -1; 387f0ded5f3SAzat Khuzhin 388f0ded5f3SAzat Khuzhin struct evbuffer *tmp = evbuffer_new(); 389f0ded5f3SAzat Khuzhin 390f0ded5f3SAzat Khuzhin if (evtag_unmarshal(evbuf, &tag, tmp) == -1 || tag != need_tag) 391f0ded5f3SAzat Khuzhin goto error; 392f0ded5f3SAzat Khuzhin 393f0ded5f3SAzat Khuzhin if (%(name)s_unmarshal(msg, tmp) == -1) 394f0ded5f3SAzat Khuzhin goto error; 395f0ded5f3SAzat Khuzhin 396f0ded5f3SAzat Khuzhin res = 0; 397f0ded5f3SAzat Khuzhin 398f0ded5f3SAzat Khuzhin error: 399f0ded5f3SAzat Khuzhin evbuffer_free(tmp); 400f0ded5f3SAzat Khuzhin return (res); 401f0ded5f3SAzat Khuzhin} 402f0ded5f3SAzat Khuzhin""" 403f0ded5f3SAzat Khuzhin % {"name": self._name} 404f0ded5f3SAzat Khuzhin ) 405949cbd12SNiels Provos 406949cbd12SNiels Provos # Complete message marshaling 407f0ded5f3SAzat Khuzhin filep.write( 408f0ded5f3SAzat Khuzhin """ 409f0ded5f3SAzat Khuzhinvoid 410f0ded5f3SAzat Khuzhinevtag_marshal_%(name)s(struct evbuffer *evbuf, ev_uint32_t tag, 411f0ded5f3SAzat Khuzhin const struct %(name)s *msg) 412f0ded5f3SAzat Khuzhin{ 413f0ded5f3SAzat Khuzhin struct evbuffer *buf_ = evbuffer_new(); 414f0ded5f3SAzat Khuzhin assert(buf_ != NULL); 415f0ded5f3SAzat Khuzhin %(name)s_marshal(buf_, msg); 416f0ded5f3SAzat Khuzhin evtag_marshal_buffer(evbuf, tag, buf_); 417f0ded5f3SAzat Khuzhin evbuffer_free(buf_); 418f0ded5f3SAzat Khuzhin} 419f0ded5f3SAzat Khuzhin 420f0ded5f3SAzat Khuzhin""" 421f0ded5f3SAzat Khuzhin % {"name": self._name} 422f0ded5f3SAzat Khuzhin ) 423f0ded5f3SAzat Khuzhin 424949cbd12SNiels Provos 425*48e04887SEnji Cooperclass Entry(object): 426f0ded5f3SAzat Khuzhin def __init__(self, ent_type, name, tag): 427f0ded5f3SAzat Khuzhin self._type = ent_type 428949cbd12SNiels Provos self._name = name 429949cbd12SNiels Provos self._tag = int(tag) 430f0ded5f3SAzat Khuzhin self._ctype = ent_type 431f0ded5f3SAzat Khuzhin self._optional = False 432f0ded5f3SAzat Khuzhin self._can_be_array = False 433f0ded5f3SAzat Khuzhin self._array = False 434949cbd12SNiels Provos self._line_count = -1 435949cbd12SNiels Provos self._struct = None 4363c1a6a68SNiels Provos self._refname = None 4373c1a6a68SNiels Provos 43868725dc8SNiels Provos self._optpointer = True 43968725dc8SNiels Provos self._optaddarg = True 44068725dc8SNiels Provos 441f0ded5f3SAzat Khuzhin @staticmethod 442f0ded5f3SAzat Khuzhin def GetInitializer(): 443f0ded5f3SAzat Khuzhin raise NotImplementedError("Entry does not provide an initializer") 44468725dc8SNiels Provos 445949cbd12SNiels Provos def SetStruct(self, struct): 446949cbd12SNiels Provos self._struct = struct 447949cbd12SNiels Provos 448949cbd12SNiels Provos def LineCount(self): 449949cbd12SNiels Provos assert self._line_count != -1 450949cbd12SNiels Provos return self._line_count 451949cbd12SNiels Provos 452949cbd12SNiels Provos def SetLineCount(self, number): 453949cbd12SNiels Provos self._line_count = number 454949cbd12SNiels Provos 455b4ab56dcSNiels Provos def Array(self): 456b4ab56dcSNiels Provos return self._array 457b4ab56dcSNiels Provos 458949cbd12SNiels Provos def Optional(self): 459949cbd12SNiels Provos return self._optional 460949cbd12SNiels Provos 461949cbd12SNiels Provos def Tag(self): 462949cbd12SNiels Provos return self._tag 463949cbd12SNiels Provos 464949cbd12SNiels Provos def Name(self): 465949cbd12SNiels Provos return self._name 466949cbd12SNiels Provos 467949cbd12SNiels Provos def Type(self): 468949cbd12SNiels Provos return self._type 469949cbd12SNiels Provos 470f0ded5f3SAzat Khuzhin def MakeArray(self): 471f0ded5f3SAzat Khuzhin self._array = True 472949cbd12SNiels Provos 473949cbd12SNiels Provos def MakeOptional(self): 474f0ded5f3SAzat Khuzhin self._optional = True 475949cbd12SNiels Provos 476a7e39551SNiels Provos def Verify(self): 477a7e39551SNiels Provos if self.Array() and not self._can_be_array: 47837d3e16cSNiels Provos raise RpcGenError( 479a7e39551SNiels Provos 'Entry "%s" cannot be created as an array ' 480f0ded5f3SAzat Khuzhin "around line %d" % (self._name, self.LineCount()) 481f0ded5f3SAzat Khuzhin ) 482a7e39551SNiels Provos if not self._struct: 48337d3e16cSNiels Provos raise RpcGenError( 484a7e39551SNiels Provos 'Entry "%s" does not know which struct it belongs to ' 485f0ded5f3SAzat Khuzhin "around line %d" % (self._name, self.LineCount()) 486f0ded5f3SAzat Khuzhin ) 487a7e39551SNiels Provos if self._optional and self._array: 48837d3e16cSNiels Provos raise RpcGenError( 48937d3e16cSNiels Provos 'Entry "%s" has illegal combination of optional and array ' 490f0ded5f3SAzat Khuzhin "around line %d" % (self._name, self.LineCount()) 491f0ded5f3SAzat Khuzhin ) 492a7e39551SNiels Provos 493f0ded5f3SAzat Khuzhin def GetTranslation(self, extradict=None): 494f0ded5f3SAzat Khuzhin if extradict is None: 495f0ded5f3SAzat Khuzhin extradict = {} 496a7e39551SNiels Provos mapping = { 497a7e39551SNiels Provos "parent_name": self._struct.Name(), 498a7e39551SNiels Provos "name": self._name, 499a7e39551SNiels Provos "ctype": self._ctype, 500a7e39551SNiels Provos "refname": self._refname, 501a7e39551SNiels Provos "optpointer": self._optpointer and "*" or "", 502a7e39551SNiels Provos "optreference": self._optpointer and "&" or "", 503f0ded5f3SAzat Khuzhin "optaddarg": self._optaddarg and ", const %s value" % self._ctype or "", 504a7e39551SNiels Provos } 505532a8cc3SKiyoshi Aman for (k, v) in list(extradict.items()): 506a7e39551SNiels Provos mapping[k] = v 507a7e39551SNiels Provos 508a7e39551SNiels Provos return mapping 509a7e39551SNiels Provos 51068725dc8SNiels Provos def GetVarName(self, var): 511f0ded5f3SAzat Khuzhin return "%(var)s->%(name)s_data" % self.GetTranslation({"var": var}) 51268725dc8SNiels Provos 513f0ded5f3SAzat Khuzhin def GetVarLen(self, _var): 514f0ded5f3SAzat Khuzhin return "sizeof(%s)" % self._ctype 51568725dc8SNiels Provos 516949cbd12SNiels Provos def GetFuncName(self): 517f0ded5f3SAzat Khuzhin return "%s_%s_get" % (self._struct.Name(), self._name) 518949cbd12SNiels Provos 519949cbd12SNiels Provos def GetDeclaration(self, funcname): 520f0ded5f3SAzat Khuzhin code = [ 521f0ded5f3SAzat Khuzhin "int %s(struct %s *, %s *);" % (funcname, self._struct.Name(), self._ctype) 522f0ded5f3SAzat Khuzhin ] 523949cbd12SNiels Provos return code 524949cbd12SNiels Provos 525949cbd12SNiels Provos def CodeGet(self): 526f0ded5f3SAzat Khuzhin code = """int 527f0ded5f3SAzat Khuzhin%(parent_name)s_%(name)s_get(struct %(parent_name)s *msg, %(ctype)s *value) 528f0ded5f3SAzat Khuzhin{ 529f0ded5f3SAzat Khuzhin if (msg->%(name)s_set != 1) 530f0ded5f3SAzat Khuzhin return (-1); 531f0ded5f3SAzat Khuzhin *value = msg->%(name)s_data; 532f0ded5f3SAzat Khuzhin return (0); 533f0ded5f3SAzat Khuzhin}""" 5343c1a6a68SNiels Provos code = code % self.GetTranslation() 535f0ded5f3SAzat Khuzhin return code.split("\n") 536949cbd12SNiels Provos 537949cbd12SNiels Provos def AssignFuncName(self): 538f0ded5f3SAzat Khuzhin return "%s_%s_assign" % (self._struct.Name(), self._name) 539949cbd12SNiels Provos 540b4ab56dcSNiels Provos def AddFuncName(self): 541f0ded5f3SAzat Khuzhin return "%s_%s_add" % (self._struct.Name(), self._name) 542b4ab56dcSNiels Provos 543949cbd12SNiels Provos def AssignDeclaration(self, funcname): 544f0ded5f3SAzat Khuzhin code = [ 545f0ded5f3SAzat Khuzhin "int %s(struct %s *, const %s);" 546f0ded5f3SAzat Khuzhin % (funcname, self._struct.Name(), self._ctype) 547f0ded5f3SAzat Khuzhin ] 548949cbd12SNiels Provos return code 549949cbd12SNiels Provos 550949cbd12SNiels Provos def CodeAssign(self): 551f0ded5f3SAzat Khuzhin code = [ 552f0ded5f3SAzat Khuzhin "int", 553f0ded5f3SAzat Khuzhin "%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg," 554f0ded5f3SAzat Khuzhin " const %(ctype)s value)", 555f0ded5f3SAzat Khuzhin "{", 556f0ded5f3SAzat Khuzhin " msg->%(name)s_set = 1;", 557f0ded5f3SAzat Khuzhin " msg->%(name)s_data = value;", 558f0ded5f3SAzat Khuzhin " return (0);", 559f0ded5f3SAzat Khuzhin "}", 560f0ded5f3SAzat Khuzhin ] 561f0ded5f3SAzat Khuzhin code = "\n".join(code) 5623c1a6a68SNiels Provos code = code % self.GetTranslation() 563f0ded5f3SAzat Khuzhin return code.split("\n") 564949cbd12SNiels Provos 565949cbd12SNiels Provos def CodeClear(self, structname): 566f0ded5f3SAzat Khuzhin code = ["%s->%s_set = 0;" % (structname, self.Name())] 567949cbd12SNiels Provos 568949cbd12SNiels Provos return code 569949cbd12SNiels Provos 570f0ded5f3SAzat Khuzhin @staticmethod 571f0ded5f3SAzat Khuzhin def CodeComplete(_structname, _var_name): 572949cbd12SNiels Provos return [] 573949cbd12SNiels Provos 574f0ded5f3SAzat Khuzhin @staticmethod 575f0ded5f3SAzat Khuzhin def CodeFree(_name): 576949cbd12SNiels Provos return [] 577949cbd12SNiels Provos 5783b345f3eSNiels Provos def CodeBase(self): 579f0ded5f3SAzat Khuzhin code = ["%(parent_name)s_%(name)s_assign,", "%(parent_name)s_%(name)s_get,"] 580b4ab56dcSNiels Provos if self.Array(): 581f0ded5f3SAzat Khuzhin code.append("%(parent_name)s_%(name)s_add,") 5823c1a6a68SNiels Provos 583f0ded5f3SAzat Khuzhin code = "\n".join(code) 5843b345f3eSNiels Provos code = code % self.GetTranslation() 585f0ded5f3SAzat Khuzhin return code.split("\n") 586f0ded5f3SAzat Khuzhin 587949cbd12SNiels Provos 588949cbd12SNiels Provosclass EntryBytes(Entry): 589f0ded5f3SAzat Khuzhin def __init__(self, ent_type, name, tag, length): 590949cbd12SNiels Provos # Init base class 591f0ded5f3SAzat Khuzhin super(EntryBytes, self).__init__(ent_type, name, tag) 592949cbd12SNiels Provos 593949cbd12SNiels Provos self._length = length 594f0ded5f3SAzat Khuzhin self._ctype = "ev_uint8_t" 59568725dc8SNiels Provos 596f0ded5f3SAzat Khuzhin @staticmethod 597f0ded5f3SAzat Khuzhin def GetInitializer(): 59868725dc8SNiels Provos return "NULL" 59968725dc8SNiels Provos 600f0ded5f3SAzat Khuzhin def GetVarLen(self, _var): 601f0ded5f3SAzat Khuzhin return "(%s)" % self._length 60268725dc8SNiels Provos 603f0ded5f3SAzat Khuzhin @staticmethod 604f0ded5f3SAzat Khuzhin def CodeArrayAdd(varname, _value): 60568725dc8SNiels Provos # XXX: copy here 606f0ded5f3SAzat Khuzhin return ["%(varname)s = NULL;" % {"varname": varname}] 607949cbd12SNiels Provos 608949cbd12SNiels Provos def GetDeclaration(self, funcname): 609f0ded5f3SAzat Khuzhin code = [ 610f0ded5f3SAzat Khuzhin "int %s(struct %s *, %s **);" % (funcname, self._struct.Name(), self._ctype) 611f0ded5f3SAzat Khuzhin ] 612949cbd12SNiels Provos return code 613949cbd12SNiels Provos 614949cbd12SNiels Provos def AssignDeclaration(self, funcname): 615f0ded5f3SAzat Khuzhin code = [ 616f0ded5f3SAzat Khuzhin "int %s(struct %s *, const %s *);" 617f0ded5f3SAzat Khuzhin % (funcname, self._struct.Name(), self._ctype) 618f0ded5f3SAzat Khuzhin ] 619949cbd12SNiels Provos return code 620949cbd12SNiels Provos 621949cbd12SNiels Provos def Declaration(self): 622f0ded5f3SAzat Khuzhin dcl = ["ev_uint8_t %s_data[%s];" % (self._name, self._length)] 623949cbd12SNiels Provos 624949cbd12SNiels Provos return dcl 625949cbd12SNiels Provos 626949cbd12SNiels Provos def CodeGet(self): 627949cbd12SNiels Provos name = self._name 628f0ded5f3SAzat Khuzhin code = [ 629f0ded5f3SAzat Khuzhin "int", 630f0ded5f3SAzat Khuzhin "%s_%s_get(struct %s *msg, %s **value)" 631f0ded5f3SAzat Khuzhin % (self._struct.Name(), name, self._struct.Name(), self._ctype), 632f0ded5f3SAzat Khuzhin "{", 633f0ded5f3SAzat Khuzhin " if (msg->%s_set != 1)" % name, 634f0ded5f3SAzat Khuzhin " return (-1);", 635f0ded5f3SAzat Khuzhin " *value = msg->%s_data;" % name, 636f0ded5f3SAzat Khuzhin " return (0);", 637f0ded5f3SAzat Khuzhin "}", 638f0ded5f3SAzat Khuzhin ] 639949cbd12SNiels Provos return code 640949cbd12SNiels Provos 641949cbd12SNiels Provos def CodeAssign(self): 642949cbd12SNiels Provos name = self._name 643f0ded5f3SAzat Khuzhin code = [ 644f0ded5f3SAzat Khuzhin "int", 645f0ded5f3SAzat Khuzhin "%s_%s_assign(struct %s *msg, const %s *value)" 646f0ded5f3SAzat Khuzhin % (self._struct.Name(), name, self._struct.Name(), self._ctype), 647f0ded5f3SAzat Khuzhin "{", 648f0ded5f3SAzat Khuzhin " msg->%s_set = 1;" % name, 649f0ded5f3SAzat Khuzhin " memcpy(msg->%s_data, value, %s);" % (name, self._length), 650f0ded5f3SAzat Khuzhin " return (0);", 651f0ded5f3SAzat Khuzhin "}", 652f0ded5f3SAzat Khuzhin ] 653949cbd12SNiels Provos return code 654949cbd12SNiels Provos 65568725dc8SNiels Provos def CodeUnmarshal(self, buf, tag_name, var_name, var_len): 656f0ded5f3SAzat Khuzhin code = [ 657f0ded5f3SAzat Khuzhin "if (evtag_unmarshal_fixed(%(buf)s, %(tag)s, " 658f0ded5f3SAzat Khuzhin "%(var)s, %(varlen)s) == -1) {", 65968725dc8SNiels Provos ' event_warnx("%%s: failed to unmarshal %(name)s", __func__);', 660f0ded5f3SAzat Khuzhin " return (-1);", 661f0ded5f3SAzat Khuzhin "}", 66232acc283SNiels Provos ] 663f0ded5f3SAzat Khuzhin return TranslateList( 664f0ded5f3SAzat Khuzhin code, 665f0ded5f3SAzat Khuzhin self.GetTranslation( 666f0ded5f3SAzat Khuzhin {"var": var_name, "varlen": var_len, "buf": buf, "tag": tag_name} 667f0ded5f3SAzat Khuzhin ), 668f0ded5f3SAzat Khuzhin ) 669949cbd12SNiels Provos 670f0ded5f3SAzat Khuzhin @staticmethod 671f0ded5f3SAzat Khuzhin def CodeMarshal(buf, tag_name, var_name, var_len): 672f0ded5f3SAzat Khuzhin code = ["evtag_marshal(%s, %s, %s, %s);" % (buf, tag_name, var_name, var_len)] 673949cbd12SNiels Provos return code 674949cbd12SNiels Provos 675949cbd12SNiels Provos def CodeClear(self, structname): 676f0ded5f3SAzat Khuzhin code = [ 677f0ded5f3SAzat Khuzhin "%s->%s_set = 0;" % (structname, self.Name()), 678f0ded5f3SAzat Khuzhin "memset(%s->%s_data, 0, sizeof(%s->%s_data));" 679f0ded5f3SAzat Khuzhin % (structname, self._name, structname, self._name), 680f0ded5f3SAzat Khuzhin ] 681949cbd12SNiels Provos 682949cbd12SNiels Provos return code 683949cbd12SNiels Provos 68468725dc8SNiels Provos def CodeInitialize(self, name): 685f0ded5f3SAzat Khuzhin code = [ 686f0ded5f3SAzat Khuzhin "memset(%s->%s_data, 0, sizeof(%s->%s_data));" 687f0ded5f3SAzat Khuzhin % (name, self._name, name, self._name) 688f0ded5f3SAzat Khuzhin ] 689949cbd12SNiels Provos return code 690949cbd12SNiels Provos 691949cbd12SNiels Provos def Verify(self): 692949cbd12SNiels Provos if not self._length: 69337d3e16cSNiels Provos raise RpcGenError( 69437d3e16cSNiels Provos 'Entry "%s" needs a length ' 695f0ded5f3SAzat Khuzhin "around line %d" % (self._name, self.LineCount()) 696f0ded5f3SAzat Khuzhin ) 697949cbd12SNiels Provos 698f0ded5f3SAzat Khuzhin super(EntryBytes, self).Verify() 699f0ded5f3SAzat Khuzhin 700949cbd12SNiels Provos 701949cbd12SNiels Provosclass EntryInt(Entry): 702f0ded5f3SAzat Khuzhin def __init__(self, ent_type, name, tag, bits=32): 703949cbd12SNiels Provos # Init base class 704f0ded5f3SAzat Khuzhin super(EntryInt, self).__init__(ent_type, name, tag) 705949cbd12SNiels Provos 706f0ded5f3SAzat Khuzhin self._can_be_array = True 70799a1063eSNiels Provos if bits == 32: 708f0ded5f3SAzat Khuzhin self._ctype = "ev_uint32_t" 709f0ded5f3SAzat Khuzhin self._marshal_type = "int" 71099a1063eSNiels Provos if bits == 64: 711f0ded5f3SAzat Khuzhin self._ctype = "ev_uint64_t" 712f0ded5f3SAzat Khuzhin self._marshal_type = "int64" 713949cbd12SNiels Provos 714f0ded5f3SAzat Khuzhin @staticmethod 715f0ded5f3SAzat Khuzhin def GetInitializer(): 71668725dc8SNiels Provos return "0" 71768725dc8SNiels Provos 718f0ded5f3SAzat Khuzhin @staticmethod 719f0ded5f3SAzat Khuzhin def CodeArrayFree(_var): 7207e3a7af7SNiels Provos return [] 72168725dc8SNiels Provos 722f0ded5f3SAzat Khuzhin @staticmethod 723f0ded5f3SAzat Khuzhin def CodeArrayAssign(varname, srcvar): 724f0ded5f3SAzat Khuzhin return ["%(varname)s = %(srcvar)s;" % {"varname": varname, "srcvar": srcvar}] 72568725dc8SNiels Provos 726f0ded5f3SAzat Khuzhin @staticmethod 727f0ded5f3SAzat Khuzhin def CodeArrayAdd(varname, value): 72868725dc8SNiels Provos """Returns a new entry of this type.""" 729f0ded5f3SAzat Khuzhin return ["%(varname)s = %(value)s;" % {"varname": varname, "value": value}] 73068725dc8SNiels Provos 731f0ded5f3SAzat Khuzhin def CodeUnmarshal(self, buf, tag_name, var_name, _var_len): 73299a1063eSNiels Provos code = [ 733f0ded5f3SAzat Khuzhin "if (evtag_unmarshal_%(ma)s(%(buf)s, %(tag)s, &%(var)s) == -1) {", 73468725dc8SNiels Provos ' event_warnx("%%s: failed to unmarshal %(name)s", __func__);', 735f0ded5f3SAzat Khuzhin " return (-1);", 736f0ded5f3SAzat Khuzhin "}", 737f0ded5f3SAzat Khuzhin ] 738f0ded5f3SAzat Khuzhin code = "\n".join(code) % self.GetTranslation( 739f0ded5f3SAzat Khuzhin {"ma": self._marshal_type, "buf": buf, "tag": tag_name, "var": var_name} 740f0ded5f3SAzat Khuzhin ) 741f0ded5f3SAzat Khuzhin return code.split("\n") 742949cbd12SNiels Provos 743f0ded5f3SAzat Khuzhin def CodeMarshal(self, buf, tag_name, var_name, _var_len): 74499a1063eSNiels Provos code = [ 745f0ded5f3SAzat Khuzhin "evtag_marshal_%s(%s, %s, %s);" 746f0ded5f3SAzat Khuzhin % (self._marshal_type, buf, tag_name, var_name) 747f0ded5f3SAzat Khuzhin ] 748949cbd12SNiels Provos return code 749949cbd12SNiels Provos 750949cbd12SNiels Provos def Declaration(self): 751f0ded5f3SAzat Khuzhin dcl = ["%s %s_data;" % (self._ctype, self._name)] 752949cbd12SNiels Provos 753949cbd12SNiels Provos return dcl 754949cbd12SNiels Provos 75568725dc8SNiels Provos def CodeInitialize(self, name): 756f0ded5f3SAzat Khuzhin code = ["%s->%s_data = 0;" % (name, self._name)] 75785053473SNiels Provos return code 75885053473SNiels Provos 759f0ded5f3SAzat Khuzhin 760949cbd12SNiels Provosclass EntryString(Entry): 761f0ded5f3SAzat Khuzhin def __init__(self, ent_type, name, tag): 762949cbd12SNiels Provos # Init base class 763f0ded5f3SAzat Khuzhin super(EntryString, self).__init__(ent_type, name, tag) 764949cbd12SNiels Provos 765f0ded5f3SAzat Khuzhin self._can_be_array = True 766f0ded5f3SAzat Khuzhin self._ctype = "char *" 767949cbd12SNiels Provos 768f0ded5f3SAzat Khuzhin @staticmethod 769f0ded5f3SAzat Khuzhin def GetInitializer(): 77068725dc8SNiels Provos return "NULL" 77168725dc8SNiels Provos 772f0ded5f3SAzat Khuzhin @staticmethod 773f0ded5f3SAzat Khuzhin def CodeArrayFree(varname): 774f0ded5f3SAzat Khuzhin code = ["if (%(var)s != NULL) free(%(var)s);"] 7757e3a7af7SNiels Provos 776f0ded5f3SAzat Khuzhin return TranslateList(code, {"var": varname}) 7777e3a7af7SNiels Provos 778f0ded5f3SAzat Khuzhin @staticmethod 779f0ded5f3SAzat Khuzhin def CodeArrayAssign(varname, srcvar): 7807e3a7af7SNiels Provos code = [ 781f0ded5f3SAzat Khuzhin "if (%(var)s != NULL)", 782f0ded5f3SAzat Khuzhin " free(%(var)s);", 783f0ded5f3SAzat Khuzhin "%(var)s = strdup(%(srcvar)s);", 784f0ded5f3SAzat Khuzhin "if (%(var)s == NULL) {", 7857e3a7af7SNiels Provos ' event_warnx("%%s: strdup", __func__);', 786f0ded5f3SAzat Khuzhin " return (-1);", 787f0ded5f3SAzat Khuzhin "}", 788f0ded5f3SAzat Khuzhin ] 7897e3a7af7SNiels Provos 790f0ded5f3SAzat Khuzhin return TranslateList(code, {"var": varname, "srcvar": srcvar}) 7917e3a7af7SNiels Provos 792f0ded5f3SAzat Khuzhin @staticmethod 793f0ded5f3SAzat Khuzhin def CodeArrayAdd(varname, value): 7947e3a7af7SNiels Provos code = [ 795f0ded5f3SAzat Khuzhin "if (%(value)s != NULL) {", 796f0ded5f3SAzat Khuzhin " %(var)s = strdup(%(value)s);", 797f0ded5f3SAzat Khuzhin " if (%(var)s == NULL) {", 798f0ded5f3SAzat Khuzhin " goto error;", 799f0ded5f3SAzat Khuzhin " }", 800f0ded5f3SAzat Khuzhin "} else {", 801f0ded5f3SAzat Khuzhin " %(var)s = NULL;", 802f0ded5f3SAzat Khuzhin "}", 803f0ded5f3SAzat Khuzhin ] 8047e3a7af7SNiels Provos 805f0ded5f3SAzat Khuzhin return TranslateList(code, {"var": varname, "value": value}) 8067e3a7af7SNiels Provos 80768725dc8SNiels Provos def GetVarLen(self, var): 808f0ded5f3SAzat Khuzhin return "strlen(%s)" % self.GetVarName(var) 80968725dc8SNiels Provos 810f0ded5f3SAzat Khuzhin @staticmethod 811f0ded5f3SAzat Khuzhin def CodeMakeInitalize(varname): 812f0ded5f3SAzat Khuzhin return "%(varname)s = NULL;" % {"varname": varname} 81368725dc8SNiels Provos 814949cbd12SNiels Provos def CodeAssign(self): 8153c1a6a68SNiels Provos code = """int 8163c1a6a68SNiels Provos%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg, 8173c1a6a68SNiels Provos const %(ctype)s value) 8183c1a6a68SNiels Provos{ 8193c1a6a68SNiels Provos if (msg->%(name)s_data != NULL) 8203c1a6a68SNiels Provos free(msg->%(name)s_data); 8213c1a6a68SNiels Provos if ((msg->%(name)s_data = strdup(value)) == NULL) 8223c1a6a68SNiels Provos return (-1); 8233c1a6a68SNiels Provos msg->%(name)s_set = 1; 8243c1a6a68SNiels Provos return (0); 825f0ded5f3SAzat Khuzhin}""" % ( 826f0ded5f3SAzat Khuzhin self.GetTranslation() 827f0ded5f3SAzat Khuzhin ) 8283c1a6a68SNiels Provos 829f0ded5f3SAzat Khuzhin return code.split("\n") 830949cbd12SNiels Provos 831f0ded5f3SAzat Khuzhin def CodeUnmarshal(self, buf, tag_name, var_name, _var_len): 832f0ded5f3SAzat Khuzhin code = [ 833f0ded5f3SAzat Khuzhin "if (evtag_unmarshal_string(%(buf)s, %(tag)s, &%(var)s) == -1) {", 83468725dc8SNiels Provos ' event_warnx("%%s: failed to unmarshal %(name)s", __func__);', 835f0ded5f3SAzat Khuzhin " return (-1);", 836f0ded5f3SAzat Khuzhin "}", 83732acc283SNiels Provos ] 838f0ded5f3SAzat Khuzhin code = "\n".join(code) % self.GetTranslation( 839f0ded5f3SAzat Khuzhin {"buf": buf, "tag": tag_name, "var": var_name} 840f0ded5f3SAzat Khuzhin ) 841f0ded5f3SAzat Khuzhin return code.split("\n") 842949cbd12SNiels Provos 843f0ded5f3SAzat Khuzhin @staticmethod 844f0ded5f3SAzat Khuzhin def CodeMarshal(buf, tag_name, var_name, _var_len): 845f0ded5f3SAzat Khuzhin code = ["evtag_marshal_string(%s, %s, %s);" % (buf, tag_name, var_name)] 846949cbd12SNiels Provos return code 847949cbd12SNiels Provos 848949cbd12SNiels Provos def CodeClear(self, structname): 849f0ded5f3SAzat Khuzhin code = [ 850f0ded5f3SAzat Khuzhin "if (%s->%s_set == 1) {" % (structname, self.Name()), 851f0ded5f3SAzat Khuzhin " free(%s->%s_data);" % (structname, self.Name()), 852f0ded5f3SAzat Khuzhin " %s->%s_data = NULL;" % (structname, self.Name()), 853f0ded5f3SAzat Khuzhin " %s->%s_set = 0;" % (structname, self.Name()), 854f0ded5f3SAzat Khuzhin "}", 855949cbd12SNiels Provos ] 856949cbd12SNiels Provos 857949cbd12SNiels Provos return code 858949cbd12SNiels Provos 85968725dc8SNiels Provos def CodeInitialize(self, name): 860f0ded5f3SAzat Khuzhin code = ["%s->%s_data = NULL;" % (name, self._name)] 861949cbd12SNiels Provos return code 862949cbd12SNiels Provos 863949cbd12SNiels Provos def CodeFree(self, name): 864f0ded5f3SAzat Khuzhin code = [ 865f0ded5f3SAzat Khuzhin "if (%s->%s_data != NULL)" % (name, self._name), 866f0ded5f3SAzat Khuzhin " free (%s->%s_data);" % (name, self._name), 867f0ded5f3SAzat Khuzhin ] 868949cbd12SNiels Provos 869949cbd12SNiels Provos return code 870949cbd12SNiels Provos 871949cbd12SNiels Provos def Declaration(self): 872f0ded5f3SAzat Khuzhin dcl = ["char *%s_data;" % self._name] 873949cbd12SNiels Provos 874949cbd12SNiels Provos return dcl 875949cbd12SNiels Provos 876f0ded5f3SAzat Khuzhin 877949cbd12SNiels Provosclass EntryStruct(Entry): 878f0ded5f3SAzat Khuzhin def __init__(self, ent_type, name, tag, refname): 879949cbd12SNiels Provos # Init base class 880f0ded5f3SAzat Khuzhin super(EntryStruct, self).__init__(ent_type, name, tag) 881949cbd12SNiels Provos 88268725dc8SNiels Provos self._optpointer = False 883f0ded5f3SAzat Khuzhin self._can_be_array = True 884949cbd12SNiels Provos self._refname = refname 885f0ded5f3SAzat Khuzhin self._ctype = "struct %s*" % refname 88668725dc8SNiels Provos self._optaddarg = False 88768725dc8SNiels Provos 88868725dc8SNiels Provos def GetInitializer(self): 88968725dc8SNiels Provos return "NULL" 89068725dc8SNiels Provos 891f0ded5f3SAzat Khuzhin def GetVarLen(self, _var): 892f0ded5f3SAzat Khuzhin return "-1" 89368725dc8SNiels Provos 894f0ded5f3SAzat Khuzhin def CodeArrayAdd(self, varname, _value): 8957e3a7af7SNiels Provos code = [ 896f0ded5f3SAzat Khuzhin "%(varname)s = %(refname)s_new();", 897f0ded5f3SAzat Khuzhin "if (%(varname)s == NULL)", 898f0ded5f3SAzat Khuzhin " goto error;", 899f0ded5f3SAzat Khuzhin ] 9007e3a7af7SNiels Provos 901f0ded5f3SAzat Khuzhin return TranslateList(code, self.GetTranslation({"varname": varname})) 90268725dc8SNiels Provos 90368725dc8SNiels Provos def CodeArrayFree(self, var): 904f0ded5f3SAzat Khuzhin code = ["%(refname)s_free(%(var)s);" % self.GetTranslation({"var": var})] 90568725dc8SNiels Provos return code 90668725dc8SNiels Provos 90768725dc8SNiels Provos def CodeArrayAssign(self, var, srcvar): 9087e3a7af7SNiels Provos code = [ 909f0ded5f3SAzat Khuzhin "int had_error = 0;", 910f0ded5f3SAzat Khuzhin "struct evbuffer *tmp = NULL;", 911f0ded5f3SAzat Khuzhin "%(refname)s_clear(%(var)s);", 912f0ded5f3SAzat Khuzhin "if ((tmp = evbuffer_new()) == NULL) {", 9137e3a7af7SNiels Provos ' event_warn("%%s: evbuffer_new()", __func__);', 914f0ded5f3SAzat Khuzhin " had_error = 1;", 915f0ded5f3SAzat Khuzhin " goto done;", 916f0ded5f3SAzat Khuzhin "}", 917f0ded5f3SAzat Khuzhin "%(refname)s_marshal(tmp, %(srcvar)s);", 918f0ded5f3SAzat Khuzhin "if (%(refname)s_unmarshal(%(var)s, tmp) == -1) {", 9197e3a7af7SNiels Provos ' event_warnx("%%s: %(refname)s_unmarshal", __func__);', 920f0ded5f3SAzat Khuzhin " had_error = 1;", 921f0ded5f3SAzat Khuzhin " goto done;", 922f0ded5f3SAzat Khuzhin "}", 923f0ded5f3SAzat Khuzhin "done:", 924f0ded5f3SAzat Khuzhin "if (tmp != NULL)", 925f0ded5f3SAzat Khuzhin " evbuffer_free(tmp);", 926f0ded5f3SAzat Khuzhin "if (had_error) {", 927f0ded5f3SAzat Khuzhin " %(refname)s_clear(%(var)s);", 928f0ded5f3SAzat Khuzhin " return (-1);", 929f0ded5f3SAzat Khuzhin "}", 930f0ded5f3SAzat Khuzhin ] 9317e3a7af7SNiels Provos 932f0ded5f3SAzat Khuzhin return TranslateList(code, self.GetTranslation({"var": var, "srcvar": srcvar})) 933949cbd12SNiels Provos 934949cbd12SNiels Provos def CodeGet(self): 935949cbd12SNiels Provos name = self._name 936f0ded5f3SAzat Khuzhin code = [ 937f0ded5f3SAzat Khuzhin "int", 938f0ded5f3SAzat Khuzhin "%s_%s_get(struct %s *msg, %s *value)" 939f0ded5f3SAzat Khuzhin % (self._struct.Name(), name, self._struct.Name(), self._ctype), 940f0ded5f3SAzat Khuzhin "{", 941f0ded5f3SAzat Khuzhin " if (msg->%s_set != 1) {" % name, 942f0ded5f3SAzat Khuzhin " msg->%s_data = %s_new();" % (name, self._refname), 943f0ded5f3SAzat Khuzhin " if (msg->%s_data == NULL)" % name, 944f0ded5f3SAzat Khuzhin " return (-1);", 945f0ded5f3SAzat Khuzhin " msg->%s_set = 1;" % name, 946f0ded5f3SAzat Khuzhin " }", 947f0ded5f3SAzat Khuzhin " *value = msg->%s_data;" % name, 948f0ded5f3SAzat Khuzhin " return (0);", 949f0ded5f3SAzat Khuzhin "}", 950f0ded5f3SAzat Khuzhin ] 951949cbd12SNiels Provos return code 952949cbd12SNiels Provos 953949cbd12SNiels Provos def CodeAssign(self): 954f0ded5f3SAzat Khuzhin code = ( 955f0ded5f3SAzat Khuzhin """int 9563c1a6a68SNiels Provos%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg, 9573c1a6a68SNiels Provos const %(ctype)s value) 9583c1a6a68SNiels Provos{ 9593c1a6a68SNiels Provos struct evbuffer *tmp = NULL; 9603c1a6a68SNiels Provos if (msg->%(name)s_set) { 9613c1a6a68SNiels Provos %(refname)s_clear(msg->%(name)s_data); 9623c1a6a68SNiels Provos msg->%(name)s_set = 0; 9633c1a6a68SNiels Provos } else { 9643c1a6a68SNiels Provos msg->%(name)s_data = %(refname)s_new(); 9653c1a6a68SNiels Provos if (msg->%(name)s_data == NULL) { 9663c1a6a68SNiels Provos event_warn("%%s: %(refname)s_new()", __func__); 9673c1a6a68SNiels Provos goto error; 9683c1a6a68SNiels Provos } 9693c1a6a68SNiels Provos } 9703c1a6a68SNiels Provos if ((tmp = evbuffer_new()) == NULL) { 9713c1a6a68SNiels Provos event_warn("%%s: evbuffer_new()", __func__); 9723c1a6a68SNiels Provos goto error; 9733c1a6a68SNiels Provos } 9743c1a6a68SNiels Provos %(refname)s_marshal(tmp, value); 9753c1a6a68SNiels Provos if (%(refname)s_unmarshal(msg->%(name)s_data, tmp) == -1) { 9763c1a6a68SNiels Provos event_warnx("%%s: %(refname)s_unmarshal", __func__); 9773c1a6a68SNiels Provos goto error; 9783c1a6a68SNiels Provos } 9793c1a6a68SNiels Provos msg->%(name)s_set = 1; 9803c1a6a68SNiels Provos evbuffer_free(tmp); 9813c1a6a68SNiels Provos return (0); 9823c1a6a68SNiels Provos error: 9833c1a6a68SNiels Provos if (tmp != NULL) 9843c1a6a68SNiels Provos evbuffer_free(tmp); 9853c1a6a68SNiels Provos if (msg->%(name)s_data != NULL) { 9863c1a6a68SNiels Provos %(refname)s_free(msg->%(name)s_data); 9873c1a6a68SNiels Provos msg->%(name)s_data = NULL; 9883c1a6a68SNiels Provos } 9893c1a6a68SNiels Provos return (-1); 990f0ded5f3SAzat Khuzhin}""" 991f0ded5f3SAzat Khuzhin % self.GetTranslation() 992f0ded5f3SAzat Khuzhin ) 993f0ded5f3SAzat Khuzhin return code.split("\n") 994949cbd12SNiels Provos 99568725dc8SNiels Provos def CodeComplete(self, structname, var_name): 996f0ded5f3SAzat Khuzhin code = [ 997f0ded5f3SAzat Khuzhin "if (%(structname)s->%(name)s_set && " 998f0ded5f3SAzat Khuzhin "%(refname)s_complete(%(var)s) == -1)", 999f0ded5f3SAzat Khuzhin " return (-1);", 100032acc283SNiels Provos ] 1001949cbd12SNiels Provos 1002f0ded5f3SAzat Khuzhin return TranslateList( 1003f0ded5f3SAzat Khuzhin code, self.GetTranslation({"structname": structname, "var": var_name}) 1004f0ded5f3SAzat Khuzhin ) 1005f0ded5f3SAzat Khuzhin 1006f0ded5f3SAzat Khuzhin def CodeUnmarshal(self, buf, tag_name, var_name, _var_len): 1007f0ded5f3SAzat Khuzhin code = [ 1008f0ded5f3SAzat Khuzhin "%(var)s = %(refname)s_new();", 1009f0ded5f3SAzat Khuzhin "if (%(var)s == NULL)", 1010f0ded5f3SAzat Khuzhin " return (-1);", 1011f0ded5f3SAzat Khuzhin "if (evtag_unmarshal_%(refname)s(%(buf)s, %(tag)s, ", 1012f0ded5f3SAzat Khuzhin " %(var)s) == -1) {", 1013f0ded5f3SAzat Khuzhin ' event_warnx("%%s: failed to unmarshal %(name)s", __func__);', 1014f0ded5f3SAzat Khuzhin " return (-1);", 1015f0ded5f3SAzat Khuzhin "}", 1016f0ded5f3SAzat Khuzhin ] 1017f0ded5f3SAzat Khuzhin code = "\n".join(code) % self.GetTranslation( 1018f0ded5f3SAzat Khuzhin {"buf": buf, "tag": tag_name, "var": var_name} 1019f0ded5f3SAzat Khuzhin ) 1020f0ded5f3SAzat Khuzhin return code.split("\n") 1021f0ded5f3SAzat Khuzhin 1022f0ded5f3SAzat Khuzhin def CodeMarshal(self, buf, tag_name, var_name, _var_len): 1023f0ded5f3SAzat Khuzhin code = [ 1024f0ded5f3SAzat Khuzhin "evtag_marshal_%s(%s, %s, %s);" % (self._refname, buf, tag_name, var_name) 1025f0ded5f3SAzat Khuzhin ] 1026949cbd12SNiels Provos return code 1027949cbd12SNiels Provos 1028949cbd12SNiels Provos def CodeClear(self, structname): 1029f0ded5f3SAzat Khuzhin code = [ 1030f0ded5f3SAzat Khuzhin "if (%s->%s_set == 1) {" % (structname, self.Name()), 1031f0ded5f3SAzat Khuzhin " %s_free(%s->%s_data);" % (self._refname, structname, self.Name()), 1032f0ded5f3SAzat Khuzhin " %s->%s_data = NULL;" % (structname, self.Name()), 1033f0ded5f3SAzat Khuzhin " %s->%s_set = 0;" % (structname, self.Name()), 1034f0ded5f3SAzat Khuzhin "}", 1035949cbd12SNiels Provos ] 1036949cbd12SNiels Provos 1037949cbd12SNiels Provos return code 1038949cbd12SNiels Provos 103968725dc8SNiels Provos def CodeInitialize(self, name): 1040f0ded5f3SAzat Khuzhin code = ["%s->%s_data = NULL;" % (name, self._name)] 1041949cbd12SNiels Provos return code 1042949cbd12SNiels Provos 1043949cbd12SNiels Provos def CodeFree(self, name): 1044f0ded5f3SAzat Khuzhin code = [ 1045f0ded5f3SAzat Khuzhin "if (%s->%s_data != NULL)" % (name, self._name), 1046f0ded5f3SAzat Khuzhin " %s_free(%s->%s_data);" % (self._refname, name, self._name), 1047f0ded5f3SAzat Khuzhin ] 1048949cbd12SNiels Provos 1049949cbd12SNiels Provos return code 1050949cbd12SNiels Provos 1051949cbd12SNiels Provos def Declaration(self): 1052f0ded5f3SAzat Khuzhin dcl = ["%s %s_data;" % (self._ctype, self._name)] 1053949cbd12SNiels Provos 1054949cbd12SNiels Provos return dcl 1055949cbd12SNiels Provos 1056f0ded5f3SAzat Khuzhin 1057949cbd12SNiels Provosclass EntryVarBytes(Entry): 1058f0ded5f3SAzat Khuzhin def __init__(self, ent_type, name, tag): 1059949cbd12SNiels Provos # Init base class 1060f0ded5f3SAzat Khuzhin super(EntryVarBytes, self).__init__(ent_type, name, tag) 1061949cbd12SNiels Provos 1062f0ded5f3SAzat Khuzhin self._ctype = "ev_uint8_t *" 1063949cbd12SNiels Provos 1064f0ded5f3SAzat Khuzhin @staticmethod 1065f0ded5f3SAzat Khuzhin def GetInitializer(): 106668725dc8SNiels Provos return "NULL" 106768725dc8SNiels Provos 106868725dc8SNiels Provos def GetVarLen(self, var): 1069f0ded5f3SAzat Khuzhin return "%(var)s->%(name)s_length" % self.GetTranslation({"var": var}) 107068725dc8SNiels Provos 1071f0ded5f3SAzat Khuzhin @staticmethod 1072f0ded5f3SAzat Khuzhin def CodeArrayAdd(varname, _value): 107368725dc8SNiels Provos # xxx: copy 1074f0ded5f3SAzat Khuzhin return ["%(varname)s = NULL;" % {"varname": varname}] 107568725dc8SNiels Provos 1076aaf56fb6SNiels Provos def GetDeclaration(self, funcname): 1077f0ded5f3SAzat Khuzhin code = [ 1078f0ded5f3SAzat Khuzhin "int %s(struct %s *, %s *, ev_uint32_t *);" 1079f0ded5f3SAzat Khuzhin % (funcname, self._struct.Name(), self._ctype) 1080f0ded5f3SAzat Khuzhin ] 1081aaf56fb6SNiels Provos return code 1082aaf56fb6SNiels Provos 1083949cbd12SNiels Provos def AssignDeclaration(self, funcname): 1084f0ded5f3SAzat Khuzhin code = [ 1085f0ded5f3SAzat Khuzhin "int %s(struct %s *, const %s, ev_uint32_t);" 1086f0ded5f3SAzat Khuzhin % (funcname, self._struct.Name(), self._ctype) 1087f0ded5f3SAzat Khuzhin ] 1088949cbd12SNiels Provos return code 1089949cbd12SNiels Provos 1090949cbd12SNiels Provos def CodeAssign(self): 1091949cbd12SNiels Provos name = self._name 1092f0ded5f3SAzat Khuzhin code = [ 1093f0ded5f3SAzat Khuzhin "int", 1094f0ded5f3SAzat Khuzhin "%s_%s_assign(struct %s *msg, " 1095f0ded5f3SAzat Khuzhin "const %s value, ev_uint32_t len)" 1096f0ded5f3SAzat Khuzhin % (self._struct.Name(), name, self._struct.Name(), self._ctype), 1097f0ded5f3SAzat Khuzhin "{", 1098f0ded5f3SAzat Khuzhin " if (msg->%s_data != NULL)" % name, 1099f0ded5f3SAzat Khuzhin " free (msg->%s_data);" % name, 1100f0ded5f3SAzat Khuzhin " msg->%s_data = malloc(len);" % name, 1101f0ded5f3SAzat Khuzhin " if (msg->%s_data == NULL)" % name, 1102f0ded5f3SAzat Khuzhin " return (-1);", 1103f0ded5f3SAzat Khuzhin " msg->%s_set = 1;" % name, 1104f0ded5f3SAzat Khuzhin " msg->%s_length = len;" % name, 1105f0ded5f3SAzat Khuzhin " memcpy(msg->%s_data, value, len);" % name, 1106f0ded5f3SAzat Khuzhin " return (0);", 1107f0ded5f3SAzat Khuzhin "}", 1108f0ded5f3SAzat Khuzhin ] 1109949cbd12SNiels Provos return code 1110949cbd12SNiels Provos 1111aaf56fb6SNiels Provos def CodeGet(self): 1112aaf56fb6SNiels Provos name = self._name 1113f0ded5f3SAzat Khuzhin code = [ 1114f0ded5f3SAzat Khuzhin "int", 1115f0ded5f3SAzat Khuzhin "%s_%s_get(struct %s *msg, %s *value, ev_uint32_t *plen)" 1116f0ded5f3SAzat Khuzhin % (self._struct.Name(), name, self._struct.Name(), self._ctype), 1117f0ded5f3SAzat Khuzhin "{", 1118f0ded5f3SAzat Khuzhin " if (msg->%s_set != 1)" % name, 1119f0ded5f3SAzat Khuzhin " return (-1);", 1120f0ded5f3SAzat Khuzhin " *value = msg->%s_data;" % name, 1121f0ded5f3SAzat Khuzhin " *plen = msg->%s_length;" % name, 1122f0ded5f3SAzat Khuzhin " return (0);", 1123f0ded5f3SAzat Khuzhin "}", 1124f0ded5f3SAzat Khuzhin ] 1125aaf56fb6SNiels Provos return code 1126aaf56fb6SNiels Provos 112768725dc8SNiels Provos def CodeUnmarshal(self, buf, tag_name, var_name, var_len): 1128f0ded5f3SAzat Khuzhin code = [ 1129f0ded5f3SAzat Khuzhin "if (evtag_payload_length(%(buf)s, &%(varlen)s) == -1)", 1130f0ded5f3SAzat Khuzhin " return (-1);", 11317000fe66SNiels Provos # We do not want DoS opportunities 1132f0ded5f3SAzat Khuzhin "if (%(varlen)s > evbuffer_get_length(%(buf)s))", 1133f0ded5f3SAzat Khuzhin " return (-1);", 1134f0ded5f3SAzat Khuzhin "if ((%(var)s = malloc(%(varlen)s)) == NULL)", 1135f0ded5f3SAzat Khuzhin " return (-1);", 1136f0ded5f3SAzat Khuzhin "if (evtag_unmarshal_fixed(%(buf)s, %(tag)s, %(var)s, " 1137f0ded5f3SAzat Khuzhin "%(varlen)s) == -1) {", 113868725dc8SNiels Provos ' event_warnx("%%s: failed to unmarshal %(name)s", __func__);', 1139f0ded5f3SAzat Khuzhin " return (-1);", 1140f0ded5f3SAzat Khuzhin "}", 114132acc283SNiels Provos ] 1142f0ded5f3SAzat Khuzhin code = "\n".join(code) % self.GetTranslation( 1143f0ded5f3SAzat Khuzhin {"buf": buf, "tag": tag_name, "var": var_name, "varlen": var_len} 1144f0ded5f3SAzat Khuzhin ) 1145f0ded5f3SAzat Khuzhin return code.split("\n") 1146949cbd12SNiels Provos 1147f0ded5f3SAzat Khuzhin @staticmethod 1148f0ded5f3SAzat Khuzhin def CodeMarshal(buf, tag_name, var_name, var_len): 1149f0ded5f3SAzat Khuzhin code = ["evtag_marshal(%s, %s, %s, %s);" % (buf, tag_name, var_name, var_len)] 1150949cbd12SNiels Provos return code 1151949cbd12SNiels Provos 1152949cbd12SNiels Provos def CodeClear(self, structname): 1153f0ded5f3SAzat Khuzhin code = [ 1154f0ded5f3SAzat Khuzhin "if (%s->%s_set == 1) {" % (structname, self.Name()), 1155f0ded5f3SAzat Khuzhin " free (%s->%s_data);" % (structname, self.Name()), 1156f0ded5f3SAzat Khuzhin " %s->%s_data = NULL;" % (structname, self.Name()), 1157f0ded5f3SAzat Khuzhin " %s->%s_length = 0;" % (structname, self.Name()), 1158f0ded5f3SAzat Khuzhin " %s->%s_set = 0;" % (structname, self.Name()), 1159f0ded5f3SAzat Khuzhin "}", 1160949cbd12SNiels Provos ] 1161949cbd12SNiels Provos 1162949cbd12SNiels Provos return code 1163949cbd12SNiels Provos 116468725dc8SNiels Provos def CodeInitialize(self, name): 1165f0ded5f3SAzat Khuzhin code = [ 1166f0ded5f3SAzat Khuzhin "%s->%s_data = NULL;" % (name, self._name), 1167f0ded5f3SAzat Khuzhin "%s->%s_length = 0;" % (name, self._name), 1168f0ded5f3SAzat Khuzhin ] 1169949cbd12SNiels Provos return code 1170949cbd12SNiels Provos 1171949cbd12SNiels Provos def CodeFree(self, name): 1172f0ded5f3SAzat Khuzhin code = [ 1173f0ded5f3SAzat Khuzhin "if (%s->%s_data != NULL)" % (name, self._name), 1174f0ded5f3SAzat Khuzhin " free(%s->%s_data);" % (name, self._name), 1175f0ded5f3SAzat Khuzhin ] 1176949cbd12SNiels Provos 1177949cbd12SNiels Provos return code 1178949cbd12SNiels Provos 1179949cbd12SNiels Provos def Declaration(self): 1180f0ded5f3SAzat Khuzhin dcl = [ 1181f0ded5f3SAzat Khuzhin "ev_uint8_t *%s_data;" % self._name, 1182f0ded5f3SAzat Khuzhin "ev_uint32_t %s_length;" % self._name, 1183f0ded5f3SAzat Khuzhin ] 1184949cbd12SNiels Provos 1185949cbd12SNiels Provos return dcl 1186949cbd12SNiels Provos 1187f0ded5f3SAzat Khuzhin 1188b4ab56dcSNiels Provosclass EntryArray(Entry): 1189f0ded5f3SAzat Khuzhin _index = None 1190f0ded5f3SAzat Khuzhin 1191b4ab56dcSNiels Provos def __init__(self, entry): 1192b4ab56dcSNiels Provos # Init base class 1193f0ded5f3SAzat Khuzhin super(EntryArray, self).__init__(entry._type, entry._name, entry._tag) 1194b4ab56dcSNiels Provos 1195b4ab56dcSNiels Provos self._entry = entry 1196b4ab56dcSNiels Provos self._refname = entry._refname 119768725dc8SNiels Provos self._ctype = self._entry._ctype 119868725dc8SNiels Provos self._optional = True 119968725dc8SNiels Provos self._optpointer = self._entry._optpointer 120068725dc8SNiels Provos self._optaddarg = self._entry._optaddarg 120168725dc8SNiels Provos 120268725dc8SNiels Provos # provide a new function for accessing the variable name 120368725dc8SNiels Provos def GetVarName(var_name): 1204f0ded5f3SAzat Khuzhin return "%(var)s->%(name)s_data[%(index)s]" % self._entry.GetTranslation( 1205f0ded5f3SAzat Khuzhin {"var": var_name, "index": self._index} 1206f0ded5f3SAzat Khuzhin ) 1207f0ded5f3SAzat Khuzhin 120868725dc8SNiels Provos self._entry.GetVarName = GetVarName 120968725dc8SNiels Provos 121068725dc8SNiels Provos def GetInitializer(self): 121168725dc8SNiels Provos return "NULL" 121268725dc8SNiels Provos 1213f0ded5f3SAzat Khuzhin def GetVarName(self, var): 1214f0ded5f3SAzat Khuzhin return var 121568725dc8SNiels Provos 1216f0ded5f3SAzat Khuzhin def GetVarLen(self, _var_name): 1217f0ded5f3SAzat Khuzhin return "-1" 1218b4ab56dcSNiels Provos 1219b4ab56dcSNiels Provos def GetDeclaration(self, funcname): 1220b4ab56dcSNiels Provos """Allows direct access to elements of the array.""" 12213c1a6a68SNiels Provos code = [ 1222f0ded5f3SAzat Khuzhin "int %(funcname)s(struct %(parent_name)s *, int, %(ctype)s *);" 1223f0ded5f3SAzat Khuzhin % self.GetTranslation({"funcname": funcname}) 1224f0ded5f3SAzat Khuzhin ] 1225b4ab56dcSNiels Provos return code 1226b4ab56dcSNiels Provos 1227b4ab56dcSNiels Provos def AssignDeclaration(self, funcname): 1228f0ded5f3SAzat Khuzhin code = [ 1229f0ded5f3SAzat Khuzhin "int %s(struct %s *, int, const %s);" 1230f0ded5f3SAzat Khuzhin % (funcname, self._struct.Name(), self._ctype) 1231f0ded5f3SAzat Khuzhin ] 1232b4ab56dcSNiels Provos return code 1233b4ab56dcSNiels Provos 1234b4ab56dcSNiels Provos def AddDeclaration(self, funcname): 123568725dc8SNiels Provos code = [ 1236f0ded5f3SAzat Khuzhin "%(ctype)s %(optpointer)s " 1237f0ded5f3SAzat Khuzhin "%(funcname)s(struct %(parent_name)s *msg%(optaddarg)s);" 1238f0ded5f3SAzat Khuzhin % self.GetTranslation({"funcname": funcname}) 1239f0ded5f3SAzat Khuzhin ] 1240b4ab56dcSNiels Provos return code 1241b4ab56dcSNiels Provos 1242b4ab56dcSNiels Provos def CodeGet(self): 12433c1a6a68SNiels Provos code = """int 12443c1a6a68SNiels Provos%(parent_name)s_%(name)s_get(struct %(parent_name)s *msg, int offset, 12453c1a6a68SNiels Provos %(ctype)s *value) 12463c1a6a68SNiels Provos{ 12473c1a6a68SNiels Provos if (!msg->%(name)s_set || offset < 0 || offset >= msg->%(name)s_length) 12483c1a6a68SNiels Provos return (-1); 12493c1a6a68SNiels Provos *value = msg->%(name)s_data[offset]; 12503c1a6a68SNiels Provos return (0); 1251f0ded5f3SAzat Khuzhin} 1252f0ded5f3SAzat Khuzhin""" % ( 1253f0ded5f3SAzat Khuzhin self.GetTranslation() 1254f0ded5f3SAzat Khuzhin ) 12553c1a6a68SNiels Provos 1256f0ded5f3SAzat Khuzhin return code.splitlines() 1257b4ab56dcSNiels Provos 1258b4ab56dcSNiels Provos def CodeAssign(self): 12597e3a7af7SNiels Provos code = [ 1260f0ded5f3SAzat Khuzhin "int", 1261f0ded5f3SAzat Khuzhin "%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg, int off,", 1262f0ded5f3SAzat Khuzhin " const %(ctype)s value)", 1263f0ded5f3SAzat Khuzhin "{", 1264f0ded5f3SAzat Khuzhin " if (!msg->%(name)s_set || off < 0 || off >= msg->%(name)s_length)", 1265f0ded5f3SAzat Khuzhin " return (-1);", 1266f0ded5f3SAzat Khuzhin "", 1267f0ded5f3SAzat Khuzhin " {", 1268f0ded5f3SAzat Khuzhin ] 12697e3a7af7SNiels Provos code = TranslateList(code, self.GetTranslation()) 12707e3a7af7SNiels Provos 127168725dc8SNiels Provos codearrayassign = self._entry.CodeArrayAssign( 1272f0ded5f3SAzat Khuzhin "msg->%(name)s_data[off]" % self.GetTranslation(), "value" 1273f0ded5f3SAzat Khuzhin ) 1274f0ded5f3SAzat Khuzhin code += [" " + x for x in codearrayassign] 12753c1a6a68SNiels Provos 1276f0ded5f3SAzat Khuzhin code += TranslateList([" }", " return (0);", "}"], self.GetTranslation()) 12777e3a7af7SNiels Provos 12787e3a7af7SNiels Provos return code 1279b4ab56dcSNiels Provos 1280b4ab56dcSNiels Provos def CodeAdd(self): 128168725dc8SNiels Provos codearrayadd = self._entry.CodeArrayAdd( 1282f0ded5f3SAzat Khuzhin "msg->%(name)s_data[msg->%(name)s_length - 1]" % self.GetTranslation(), 1283f0ded5f3SAzat Khuzhin "value", 1284f0ded5f3SAzat Khuzhin ) 12857e3a7af7SNiels Provos code = [ 1286f0ded5f3SAzat Khuzhin "static int", 1287f0ded5f3SAzat Khuzhin "%(parent_name)s_%(name)s_expand_to_hold_more(" 1288f0ded5f3SAzat Khuzhin "struct %(parent_name)s *msg)", 1289f0ded5f3SAzat Khuzhin "{", 1290f0ded5f3SAzat Khuzhin " int tobe_allocated = msg->%(name)s_num_allocated;", 1291f0ded5f3SAzat Khuzhin " %(ctype)s* new_data = NULL;", 1292f0ded5f3SAzat Khuzhin " tobe_allocated = !tobe_allocated ? 1 : tobe_allocated << 1;", 1293f0ded5f3SAzat Khuzhin " new_data = (%(ctype)s*) realloc(msg->%(name)s_data,", 1294f0ded5f3SAzat Khuzhin " tobe_allocated * sizeof(%(ctype)s));", 1295f0ded5f3SAzat Khuzhin " if (new_data == NULL)", 1296f0ded5f3SAzat Khuzhin " return -1;", 1297f0ded5f3SAzat Khuzhin " msg->%(name)s_data = new_data;", 1298f0ded5f3SAzat Khuzhin " msg->%(name)s_num_allocated = tobe_allocated;", 1299f0ded5f3SAzat Khuzhin " return 0;", 1300f0ded5f3SAzat Khuzhin "}", 1301f0ded5f3SAzat Khuzhin "", 1302f0ded5f3SAzat Khuzhin "%(ctype)s %(optpointer)s", 1303f0ded5f3SAzat Khuzhin "%(parent_name)s_%(name)s_add(struct %(parent_name)s *msg%(optaddarg)s)", 1304f0ded5f3SAzat Khuzhin "{", 1305f0ded5f3SAzat Khuzhin " if (++msg->%(name)s_length >= msg->%(name)s_num_allocated) {", 1306f0ded5f3SAzat Khuzhin " if (%(parent_name)s_%(name)s_expand_to_hold_more(msg)<0)", 1307f0ded5f3SAzat Khuzhin " goto error;", 1308f0ded5f3SAzat Khuzhin " }", 1309f0ded5f3SAzat Khuzhin ] 13103c1a6a68SNiels Provos 13117e3a7af7SNiels Provos code = TranslateList(code, self.GetTranslation()) 13127e3a7af7SNiels Provos 1313f0ded5f3SAzat Khuzhin code += [" " + x for x in codearrayadd] 13147e3a7af7SNiels Provos 1315f0ded5f3SAzat Khuzhin code += TranslateList( 1316f0ded5f3SAzat Khuzhin [ 1317f0ded5f3SAzat Khuzhin " msg->%(name)s_set = 1;", 1318f0ded5f3SAzat Khuzhin " return %(optreference)s(msg->%(name)s_data[" 1319f0ded5f3SAzat Khuzhin "msg->%(name)s_length - 1]);", 1320f0ded5f3SAzat Khuzhin "error:", 1321f0ded5f3SAzat Khuzhin " --msg->%(name)s_length;", 1322f0ded5f3SAzat Khuzhin " return (NULL);", 1323f0ded5f3SAzat Khuzhin "}", 1324f0ded5f3SAzat Khuzhin ], 1325f0ded5f3SAzat Khuzhin self.GetTranslation(), 1326f0ded5f3SAzat Khuzhin ) 13277e3a7af7SNiels Provos 13287e3a7af7SNiels Provos return code 1329b4ab56dcSNiels Provos 133068725dc8SNiels Provos def CodeComplete(self, structname, var_name): 1331f0ded5f3SAzat Khuzhin self._index = "i" 133268725dc8SNiels Provos tmp = self._entry.CodeComplete(structname, self._entry.GetVarName(var_name)) 133368725dc8SNiels Provos # skip the whole loop if there is nothing to check 133468725dc8SNiels Provos if not tmp: 133568725dc8SNiels Provos return [] 1336b4ab56dcSNiels Provos 1337f0ded5f3SAzat Khuzhin translate = self.GetTranslation({"structname": structname}) 133868725dc8SNiels Provos code = [ 1339f0ded5f3SAzat Khuzhin "{", 1340f0ded5f3SAzat Khuzhin " int i;", 1341f0ded5f3SAzat Khuzhin " for (i = 0; i < %(structname)s->%(name)s_length; ++i) {", 1342f0ded5f3SAzat Khuzhin ] 13433c1a6a68SNiels Provos 134468725dc8SNiels Provos code = TranslateList(code, translate) 134568725dc8SNiels Provos 1346f0ded5f3SAzat Khuzhin code += [" " + x for x in tmp] 134768725dc8SNiels Provos 1348f0ded5f3SAzat Khuzhin code += [" }", "}"] 1349b4ab56dcSNiels Provos 1350b4ab56dcSNiels Provos return code 1351b4ab56dcSNiels Provos 1352f0ded5f3SAzat Khuzhin def CodeUnmarshal(self, buf, tag_name, var_name, _var_len): 1353f0ded5f3SAzat Khuzhin translate = self.GetTranslation( 1354f0ded5f3SAzat Khuzhin { 1355f0ded5f3SAzat Khuzhin "var": var_name, 1356f0ded5f3SAzat Khuzhin "buf": buf, 1357f0ded5f3SAzat Khuzhin "tag": tag_name, 1358f0ded5f3SAzat Khuzhin "init": self._entry.GetInitializer(), 1359f0ded5f3SAzat Khuzhin } 1360f0ded5f3SAzat Khuzhin ) 136168725dc8SNiels Provos code = [ 1362f0ded5f3SAzat Khuzhin "if (%(var)s->%(name)s_length >= %(var)s->%(name)s_num_allocated &&", 1363f0ded5f3SAzat Khuzhin " %(parent_name)s_%(name)s_expand_to_hold_more(%(var)s) < 0) {", 1364f6ab2a28SNick Mathewson ' puts("HEY NOW");', 1365f0ded5f3SAzat Khuzhin " return (-1);", 1366f0ded5f3SAzat Khuzhin "}", 1367f0ded5f3SAzat Khuzhin ] 13683c1a6a68SNiels Provos 136968725dc8SNiels Provos # the unmarshal code directly returns 137068725dc8SNiels Provos code = TranslateList(code, translate) 1371b4ab56dcSNiels Provos 1372f0ded5f3SAzat Khuzhin self._index = "%(var)s->%(name)s_length" % translate 1373f0ded5f3SAzat Khuzhin code += self._entry.CodeUnmarshal( 1374f0ded5f3SAzat Khuzhin buf, 1375f0ded5f3SAzat Khuzhin tag_name, 137668725dc8SNiels Provos self._entry.GetVarName(var_name), 1377f0ded5f3SAzat Khuzhin self._entry.GetVarLen(var_name), 1378f0ded5f3SAzat Khuzhin ) 137968725dc8SNiels Provos 1380f0ded5f3SAzat Khuzhin code += ["++%(var)s->%(name)s_length;" % translate] 138168725dc8SNiels Provos 138268725dc8SNiels Provos return code 138368725dc8SNiels Provos 1384f0ded5f3SAzat Khuzhin def CodeMarshal(self, buf, tag_name, var_name, _var_len): 1385f0ded5f3SAzat Khuzhin code = ["{", " int i;", " for (i = 0; i < %(var)s->%(name)s_length; ++i) {"] 138668725dc8SNiels Provos 1387f0ded5f3SAzat Khuzhin self._index = "i" 1388f0ded5f3SAzat Khuzhin code += self._entry.CodeMarshal( 1389f0ded5f3SAzat Khuzhin buf, 1390f0ded5f3SAzat Khuzhin tag_name, 139168725dc8SNiels Provos self._entry.GetVarName(var_name), 1392f0ded5f3SAzat Khuzhin self._entry.GetVarLen(var_name), 1393f0ded5f3SAzat Khuzhin ) 1394f0ded5f3SAzat Khuzhin code += [" }", "}"] 139568725dc8SNiels Provos 1396f0ded5f3SAzat Khuzhin code = "\n".join(code) % self.GetTranslation({"var": var_name}) 139768725dc8SNiels Provos 1398f0ded5f3SAzat Khuzhin return code.split("\n") 1399b4ab56dcSNiels Provos 1400b4ab56dcSNiels Provos def CodeClear(self, structname): 1401f0ded5f3SAzat Khuzhin translate = self.GetTranslation({"structname": structname}) 140268725dc8SNiels Provos codearrayfree = self._entry.CodeArrayFree( 1403f0ded5f3SAzat Khuzhin "%(structname)s->%(name)s_data[i]" 1404f0ded5f3SAzat Khuzhin % self.GetTranslation({"structname": structname}) 1405f0ded5f3SAzat Khuzhin ) 14067e3a7af7SNiels Provos 1407f0ded5f3SAzat Khuzhin code = ["if (%(structname)s->%(name)s_set == 1) {"] 14087e3a7af7SNiels Provos 14097e3a7af7SNiels Provos if codearrayfree: 14107e3a7af7SNiels Provos code += [ 1411f0ded5f3SAzat Khuzhin " int i;", 1412f0ded5f3SAzat Khuzhin " for (i = 0; i < %(structname)s->%(name)s_length; ++i) {", 1413f0ded5f3SAzat Khuzhin ] 14147e3a7af7SNiels Provos 14157e3a7af7SNiels Provos code = TranslateList(code, translate) 14167e3a7af7SNiels Provos 14177e3a7af7SNiels Provos if codearrayfree: 1418f0ded5f3SAzat Khuzhin code += [" " + x for x in codearrayfree] 1419f0ded5f3SAzat Khuzhin code += [" }"] 14207e3a7af7SNiels Provos 1421f0ded5f3SAzat Khuzhin code += TranslateList( 1422f0ded5f3SAzat Khuzhin [ 1423f0ded5f3SAzat Khuzhin " free(%(structname)s->%(name)s_data);", 1424f0ded5f3SAzat Khuzhin " %(structname)s->%(name)s_data = NULL;", 1425f0ded5f3SAzat Khuzhin " %(structname)s->%(name)s_set = 0;", 1426f0ded5f3SAzat Khuzhin " %(structname)s->%(name)s_length = 0;", 1427f0ded5f3SAzat Khuzhin " %(structname)s->%(name)s_num_allocated = 0;", 1428f0ded5f3SAzat Khuzhin "}", 1429f0ded5f3SAzat Khuzhin ], 1430f0ded5f3SAzat Khuzhin translate, 1431f0ded5f3SAzat Khuzhin ) 143268725dc8SNiels Provos 1433b4ab56dcSNiels Provos return code 1434b4ab56dcSNiels Provos 143568725dc8SNiels Provos def CodeInitialize(self, name): 1436f0ded5f3SAzat Khuzhin code = [ 1437f0ded5f3SAzat Khuzhin "%s->%s_data = NULL;" % (name, self._name), 1438f0ded5f3SAzat Khuzhin "%s->%s_length = 0;" % (name, self._name), 1439f0ded5f3SAzat Khuzhin "%s->%s_num_allocated = 0;" % (name, self._name), 1440f0ded5f3SAzat Khuzhin ] 1441b4ab56dcSNiels Provos return code 1442b4ab56dcSNiels Provos 144368725dc8SNiels Provos def CodeFree(self, structname): 1444f0ded5f3SAzat Khuzhin code = self.CodeClear(structname) 144568725dc8SNiels Provos 1446f0ded5f3SAzat Khuzhin code += TranslateList( 1447f0ded5f3SAzat Khuzhin ["free(%(structname)s->%(name)s_data);"], 1448f0ded5f3SAzat Khuzhin self.GetTranslation({"structname": structname}), 1449f0ded5f3SAzat Khuzhin ) 145068725dc8SNiels Provos 14517e3a7af7SNiels Provos return code 1452b4ab56dcSNiels Provos 1453b4ab56dcSNiels Provos def Declaration(self): 1454f0ded5f3SAzat Khuzhin dcl = [ 1455f0ded5f3SAzat Khuzhin "%s *%s_data;" % (self._ctype, self._name), 1456f0ded5f3SAzat Khuzhin "int %s_length;" % self._name, 1457f0ded5f3SAzat Khuzhin "int %s_num_allocated;" % self._name, 1458f0ded5f3SAzat Khuzhin ] 1459b4ab56dcSNiels Provos 1460b4ab56dcSNiels Provos return dcl 1461b4ab56dcSNiels Provos 1462949cbd12SNiels Provos 1463f0ded5f3SAzat Khuzhindef NormalizeLine(line): 1464f0ded5f3SAzat Khuzhin 1465f0ded5f3SAzat Khuzhin line = CPPCOMMENT_RE.sub("", line) 1466226fd50aSNiels Provos line = line.strip() 1467f0ded5f3SAzat Khuzhin line = WHITESPACE_RE.sub(" ", line) 1468949cbd12SNiels Provos 1469949cbd12SNiels Provos return line 1470949cbd12SNiels Provos 1471f0ded5f3SAzat Khuzhin 1472f0ded5f3SAzat KhuzhinENTRY_NAME_RE = re.compile(r"(?P<name>[^\[\]]+)(\[(?P<fixed_length>.*)\])?") 1473f0ded5f3SAzat KhuzhinENTRY_TAG_NUMBER_RE = re.compile(r"(0x)?\d+", re.I) 1474f0ded5f3SAzat Khuzhin 1475f0ded5f3SAzat Khuzhin 1476a7e39551SNiels Provosdef ProcessOneEntry(factory, newstruct, entry): 1477f0ded5f3SAzat Khuzhin optional = False 1478f0ded5f3SAzat Khuzhin array = False 1479f0ded5f3SAzat Khuzhin entry_type = "" 1480f0ded5f3SAzat Khuzhin name = "" 1481f0ded5f3SAzat Khuzhin tag = "" 1482949cbd12SNiels Provos tag_set = None 1483f0ded5f3SAzat Khuzhin separator = "" 1484f0ded5f3SAzat Khuzhin fixed_length = "" 1485949cbd12SNiels Provos 1486f0ded5f3SAzat Khuzhin for token in entry.split(" "): 1487226fd50aSNiels Provos if not entry_type: 1488f0ded5f3SAzat Khuzhin if not optional and token == "optional": 1489f0ded5f3SAzat Khuzhin optional = True 1490949cbd12SNiels Provos continue 1491949cbd12SNiels Provos 1492f0ded5f3SAzat Khuzhin if not array and token == "array": 1493f0ded5f3SAzat Khuzhin array = True 1494949cbd12SNiels Provos continue 1495949cbd12SNiels Provos 1496226fd50aSNiels Provos if not entry_type: 1497226fd50aSNiels Provos entry_type = token 1498949cbd12SNiels Provos continue 1499949cbd12SNiels Provos 1500949cbd12SNiels Provos if not name: 1501f0ded5f3SAzat Khuzhin res = ENTRY_NAME_RE.match(token) 1502949cbd12SNiels Provos if not res: 150337d3e16cSNiels Provos raise RpcGenError( 1504f0ded5f3SAzat Khuzhin r"""Cannot parse name: "%s" around line %d""" % (entry, LINE_COUNT) 1505f0ded5f3SAzat Khuzhin ) 1506f0ded5f3SAzat Khuzhin name = res.group("name") 1507f0ded5f3SAzat Khuzhin fixed_length = res.group("fixed_length") 1508949cbd12SNiels Provos continue 1509949cbd12SNiels Provos 1510949cbd12SNiels Provos if not separator: 1511949cbd12SNiels Provos separator = token 1512f0ded5f3SAzat Khuzhin if separator != "=": 1513f0ded5f3SAzat Khuzhin raise RpcGenError( 1514f0ded5f3SAzat Khuzhin r'''Expected "=" after name "%s" got "%s"''' % (name, token) 1515f0ded5f3SAzat Khuzhin ) 1516949cbd12SNiels Provos continue 1517949cbd12SNiels Provos 1518949cbd12SNiels Provos if not tag_set: 1519949cbd12SNiels Provos tag_set = 1 1520f0ded5f3SAzat Khuzhin if not ENTRY_TAG_NUMBER_RE.match(token): 1521f0ded5f3SAzat Khuzhin raise RpcGenError(r'''Expected tag number: "%s"''' % (entry)) 1522ba487199SNiels Provos tag = int(token, 0) 1523949cbd12SNiels Provos continue 1524949cbd12SNiels Provos 1525f0ded5f3SAzat Khuzhin raise RpcGenError(r'''Cannot parse "%s"''' % (entry)) 1526949cbd12SNiels Provos 1527949cbd12SNiels Provos if not tag_set: 1528f0ded5f3SAzat Khuzhin raise RpcGenError(r'''Need tag number: "%s"''' % (entry)) 1529949cbd12SNiels Provos 1530949cbd12SNiels Provos # Create the right entry 1531f0ded5f3SAzat Khuzhin if entry_type == "bytes": 1532949cbd12SNiels Provos if fixed_length: 1533a7e39551SNiels Provos newentry = factory.EntryBytes(entry_type, name, tag, fixed_length) 1534949cbd12SNiels Provos else: 1535a7e39551SNiels Provos newentry = factory.EntryVarBytes(entry_type, name, tag) 1536f0ded5f3SAzat Khuzhin elif entry_type == "int" and not fixed_length: 1537a7e39551SNiels Provos newentry = factory.EntryInt(entry_type, name, tag) 1538f0ded5f3SAzat Khuzhin elif entry_type == "int64" and not fixed_length: 153999a1063eSNiels Provos newentry = factory.EntryInt(entry_type, name, tag, bits=64) 1540f0ded5f3SAzat Khuzhin elif entry_type == "string" and not fixed_length: 1541a7e39551SNiels Provos newentry = factory.EntryString(entry_type, name, tag) 1542949cbd12SNiels Provos else: 1543f0ded5f3SAzat Khuzhin res = STRUCT_REF_RE.match(entry_type) 1544949cbd12SNiels Provos if res: 1545949cbd12SNiels Provos # References another struct defined in our file 1546f0ded5f3SAzat Khuzhin newentry = factory.EntryStruct(entry_type, name, tag, res.group("name")) 1547949cbd12SNiels Provos else: 154837d3e16cSNiels Provos raise RpcGenError('Bad type: "%s" in "%s"' % (entry_type, entry)) 1549949cbd12SNiels Provos 1550b4ab56dcSNiels Provos structs = [] 1551b4ab56dcSNiels Provos 1552949cbd12SNiels Provos if optional: 1553949cbd12SNiels Provos newentry.MakeOptional() 1554949cbd12SNiels Provos if array: 1555949cbd12SNiels Provos newentry.MakeArray() 1556949cbd12SNiels Provos 1557949cbd12SNiels Provos newentry.SetStruct(newstruct) 1558f0ded5f3SAzat Khuzhin newentry.SetLineCount(LINE_COUNT) 1559949cbd12SNiels Provos newentry.Verify() 1560949cbd12SNiels Provos 1561b4ab56dcSNiels Provos if array: 1562b4ab56dcSNiels Provos # We need to encapsulate this entry into a struct 1563812d2fd8SNiels Provos newentry = factory.EntryArray(newentry) 1564b4ab56dcSNiels Provos newentry.SetStruct(newstruct) 1565f0ded5f3SAzat Khuzhin newentry.SetLineCount(LINE_COUNT) 1566b4ab56dcSNiels Provos newentry.MakeArray() 1567b4ab56dcSNiels Provos 1568949cbd12SNiels Provos newstruct.AddEntry(newentry) 1569949cbd12SNiels Provos 1570b4ab56dcSNiels Provos return structs 1571b4ab56dcSNiels Provos 1572f0ded5f3SAzat Khuzhin 1573a7e39551SNiels Provosdef ProcessStruct(factory, data): 1574f0ded5f3SAzat Khuzhin tokens = data.split(" ") 1575949cbd12SNiels Provos 1576949cbd12SNiels Provos # First three tokens are: 'struct' 'name' '{' 1577a7e39551SNiels Provos newstruct = factory.Struct(tokens[1]) 1578949cbd12SNiels Provos 1579f0ded5f3SAzat Khuzhin inside = " ".join(tokens[3:-1]) 1580949cbd12SNiels Provos 1581f0ded5f3SAzat Khuzhin tokens = inside.split(";") 1582949cbd12SNiels Provos 1583b4ab56dcSNiels Provos structs = [] 1584b4ab56dcSNiels Provos 1585949cbd12SNiels Provos for entry in tokens: 1586949cbd12SNiels Provos entry = NormalizeLine(entry) 1587949cbd12SNiels Provos if not entry: 1588949cbd12SNiels Provos continue 1589949cbd12SNiels Provos 1590b4ab56dcSNiels Provos # It's possible that new structs get defined in here 1591a7e39551SNiels Provos structs.extend(ProcessOneEntry(factory, newstruct, entry)) 1592949cbd12SNiels Provos 1593b4ab56dcSNiels Provos structs.append(newstruct) 1594b4ab56dcSNiels Provos return structs 1595949cbd12SNiels Provos 1596949cbd12SNiels Provos 1597f0ded5f3SAzat KhuzhinC_COMMENT_START = "/*" 1598f0ded5f3SAzat KhuzhinC_COMMENT_END = "*/" 1599949cbd12SNiels Provos 1600f0ded5f3SAzat KhuzhinC_COMMENT_START_RE = re.compile(re.escape(C_COMMENT_START)) 1601f0ded5f3SAzat KhuzhinC_COMMENT_END_RE = re.compile(re.escape(C_COMMENT_END)) 1602c4e60994SNiels Provos 1603f0ded5f3SAzat KhuzhinC_COMMENT_START_SUB_RE = re.compile(r"%s.*$" % (re.escape(C_COMMENT_START))) 1604f0ded5f3SAzat KhuzhinC_COMMENT_END_SUB_RE = re.compile(r"%s.*$" % (re.escape(C_COMMENT_END))) 1605f0ded5f3SAzat Khuzhin 1606f0ded5f3SAzat KhuzhinC_MULTILINE_COMMENT_SUB_RE = re.compile( 1607f0ded5f3SAzat Khuzhin r"%s.*?%s" % (re.escape(C_COMMENT_START), re.escape(C_COMMENT_END)) 1608f0ded5f3SAzat Khuzhin) 1609f0ded5f3SAzat KhuzhinCPP_CONDITIONAL_BLOCK_RE = re.compile(r"#(if( |def)|endif)") 1610f0ded5f3SAzat KhuzhinINCLUDE_RE = re.compile(r'#include (".+"|<.+>)') 1611f0ded5f3SAzat Khuzhin 1612f0ded5f3SAzat Khuzhin 1613f0ded5f3SAzat Khuzhindef GetNextStruct(filep): 1614f0ded5f3SAzat Khuzhin global CPP_DIRECT 1615f0ded5f3SAzat Khuzhin global LINE_COUNT 1616f0ded5f3SAzat Khuzhin 1617f0ded5f3SAzat Khuzhin got_struct = False 1618f0ded5f3SAzat Khuzhin have_c_comment = False 1619f0ded5f3SAzat Khuzhin 1620f0ded5f3SAzat Khuzhin data = "" 1621f0ded5f3SAzat Khuzhin 1622f0ded5f3SAzat Khuzhin while True: 1623f0ded5f3SAzat Khuzhin line = filep.readline() 16243a15f7d4SNiels Provos if not line: 16253a15f7d4SNiels Provos break 16263a15f7d4SNiels Provos 1627f0ded5f3SAzat Khuzhin LINE_COUNT += 1 1628949cbd12SNiels Provos line = line[:-1] 1629c4e60994SNiels Provos 1630f0ded5f3SAzat Khuzhin if not have_c_comment and C_COMMENT_START_RE.search(line): 1631f0ded5f3SAzat Khuzhin if C_MULTILINE_COMMENT_SUB_RE.search(line): 1632f0ded5f3SAzat Khuzhin line = C_MULTILINE_COMMENT_SUB_RE.sub("", line) 1633c4e60994SNiels Provos else: 1634f0ded5f3SAzat Khuzhin line = C_COMMENT_START_SUB_RE.sub("", line) 1635f0ded5f3SAzat Khuzhin have_c_comment = True 1636c4e60994SNiels Provos 1637c4e60994SNiels Provos if have_c_comment: 1638f0ded5f3SAzat Khuzhin if not C_COMMENT_END_RE.search(line): 1639c4e60994SNiels Provos continue 1640f0ded5f3SAzat Khuzhin have_c_comment = False 1641f0ded5f3SAzat Khuzhin line = C_COMMENT_END_SUB_RE.sub("", line) 1642c4e60994SNiels Provos 1643949cbd12SNiels Provos line = NormalizeLine(line) 1644949cbd12SNiels Provos 1645949cbd12SNiels Provos if not line: 1646949cbd12SNiels Provos continue 1647949cbd12SNiels Provos 1648949cbd12SNiels Provos if not got_struct: 1649f0ded5f3SAzat Khuzhin if INCLUDE_RE.match(line): 1650f0ded5f3SAzat Khuzhin CPP_DIRECT.append(line) 1651f0ded5f3SAzat Khuzhin elif CPP_CONDITIONAL_BLOCK_RE.match(line): 1652f0ded5f3SAzat Khuzhin CPP_DIRECT.append(line) 1653f0ded5f3SAzat Khuzhin elif PREPROCESSOR_DEF_RE.match(line): 1654f0ded5f3SAzat Khuzhin HEADER_DIRECT.append(line) 1655f0ded5f3SAzat Khuzhin elif not STRUCT_DEF_RE.match(line): 1656f0ded5f3SAzat Khuzhin raise RpcGenError("Missing struct on line %d: %s" % (LINE_COUNT, line)) 1657949cbd12SNiels Provos else: 1658f0ded5f3SAzat Khuzhin got_struct = True 1659949cbd12SNiels Provos data += line 1660949cbd12SNiels Provos continue 1661949cbd12SNiels Provos 1662949cbd12SNiels Provos # We are inside the struct 1663f0ded5f3SAzat Khuzhin tokens = line.split("}") 1664949cbd12SNiels Provos if len(tokens) == 1: 1665f0ded5f3SAzat Khuzhin data += " " + line 1666949cbd12SNiels Provos continue 1667949cbd12SNiels Provos 1668f0ded5f3SAzat Khuzhin if tokens[1]: 1669f0ded5f3SAzat Khuzhin raise RpcGenError("Trailing garbage after struct on line %d" % LINE_COUNT) 1670949cbd12SNiels Provos 1671949cbd12SNiels Provos # We found the end of the struct 1672f0ded5f3SAzat Khuzhin data += " %s}" % tokens[0] 1673949cbd12SNiels Provos break 1674949cbd12SNiels Provos 1675949cbd12SNiels Provos # Remove any comments, that might be in there 1676f0ded5f3SAzat Khuzhin data = re.sub(r"/\*.*\*/", "", data) 1677949cbd12SNiels Provos 1678949cbd12SNiels Provos return data 1679949cbd12SNiels Provos 1680949cbd12SNiels Provos 1681f0ded5f3SAzat Khuzhindef Parse(factory, filep): 16823a15f7d4SNiels Provos """ 16833a15f7d4SNiels Provos Parses the input file and returns C code and corresponding header file. 16843a15f7d4SNiels Provos """ 1685949cbd12SNiels Provos 1686949cbd12SNiels Provos entities = [] 1687949cbd12SNiels Provos 1688949cbd12SNiels Provos while 1: 1689949cbd12SNiels Provos # Just gets the whole struct nicely formatted 1690f0ded5f3SAzat Khuzhin data = GetNextStruct(filep) 1691949cbd12SNiels Provos 1692949cbd12SNiels Provos if not data: 1693949cbd12SNiels Provos break 1694949cbd12SNiels Provos 1695a7e39551SNiels Provos entities.extend(ProcessStruct(factory, data)) 1696949cbd12SNiels Provos 1697949cbd12SNiels Provos return entities 1698949cbd12SNiels Provos 1699f0ded5f3SAzat Khuzhin 1700*48e04887SEnji Cooperclass CCodeGenerator(object): 1701a7e39551SNiels Provos def __init__(self): 1702a7e39551SNiels Provos pass 1703a7e39551SNiels Provos 1704f0ded5f3SAzat Khuzhin @staticmethod 1705f0ded5f3SAzat Khuzhin def GuardName(name): 1706bbcc54efSNiels Provos # Use the complete provided path to the input file, with all 1707bbcc54efSNiels Provos # non-identifier characters replaced with underscores, to 1708bbcc54efSNiels Provos # reduce the chance of a collision between guard macros. 1709f0ded5f3SAzat Khuzhin return "EVENT_RPCOUT_%s_" % (NONIDENT_RE.sub("_", name).upper()) 1710949cbd12SNiels Provos 1711a7e39551SNiels Provos def HeaderPreamble(self, name): 1712a7e39551SNiels Provos guard = self.GuardName(name) 1713f0ded5f3SAzat Khuzhin pre = """ 1714f0ded5f3SAzat Khuzhin/* 1715f0ded5f3SAzat Khuzhin * Automatically generated from %s 1716f0ded5f3SAzat Khuzhin */ 1717c1aa5480SNiels Provos 1718f0ded5f3SAzat Khuzhin#ifndef %s 1719f0ded5f3SAzat Khuzhin#define %s 1720c1aa5480SNiels Provos 1721f0ded5f3SAzat Khuzhin""" % ( 1722f0ded5f3SAzat Khuzhin name, 1723f0ded5f3SAzat Khuzhin guard, 1724f0ded5f3SAzat Khuzhin guard, 1725bbcc54efSNiels Provos ) 1726949cbd12SNiels Provos 1727f0ded5f3SAzat Khuzhin if HEADER_DIRECT: 1728f0ded5f3SAzat Khuzhin for statement in HEADER_DIRECT: 1729f0ded5f3SAzat Khuzhin pre += "%s\n" % statement 1730f0ded5f3SAzat Khuzhin pre += "\n" 1731f0ded5f3SAzat Khuzhin 1732f0ded5f3SAzat Khuzhin pre += """ 1733f0ded5f3SAzat Khuzhin#include <event2/util.h> /* for ev_uint*_t */ 1734f0ded5f3SAzat Khuzhin#include <event2/rpc.h> 1735f0ded5f3SAzat Khuzhin""" 1736f0ded5f3SAzat Khuzhin 1737949cbd12SNiels Provos return pre 1738949cbd12SNiels Provos 1739a7e39551SNiels Provos def HeaderPostamble(self, name): 1740a7e39551SNiels Provos guard = self.GuardName(name) 1741f0ded5f3SAzat Khuzhin return "#endif /* %s */" % (guard) 1742949cbd12SNiels Provos 1743f0ded5f3SAzat Khuzhin @staticmethod 1744f0ded5f3SAzat Khuzhin def BodyPreamble(name, header_file): 1745949cbd12SNiels Provos global _NAME 1746949cbd12SNiels Provos global _VERSION 1747949cbd12SNiels Provos 1748f0ded5f3SAzat Khuzhin slash = header_file.rfind("/") 1749bbcc54efSNiels Provos if slash != -1: 1750bbcc54efSNiels Provos header_file = header_file[slash + 1 :] 1751949cbd12SNiels Provos 1752f0ded5f3SAzat Khuzhin pre = """ 1753f0ded5f3SAzat Khuzhin/* 1754f0ded5f3SAzat Khuzhin * Automatically generated from %(name)s 1755f0ded5f3SAzat Khuzhin * by %(script_name)s/%(script_version)s. DO NOT EDIT THIS FILE. 1756f0ded5f3SAzat Khuzhin */ 1757949cbd12SNiels Provos 1758f0ded5f3SAzat Khuzhin#include <stdlib.h> 1759f0ded5f3SAzat Khuzhin#include <string.h> 1760f0ded5f3SAzat Khuzhin#include <assert.h> 1761f0ded5f3SAzat Khuzhin#include <event2/event-config.h> 1762f0ded5f3SAzat Khuzhin#include <event2/event.h> 1763f0ded5f3SAzat Khuzhin#include <event2/buffer.h> 1764f0ded5f3SAzat Khuzhin#include <event2/tag.h> 1765f0ded5f3SAzat Khuzhin 1766f0ded5f3SAzat Khuzhin#if defined(EVENT__HAVE___func__) 1767f0ded5f3SAzat Khuzhin# ifndef __func__ 1768f0ded5f3SAzat Khuzhin# define __func__ __func__ 1769f0ded5f3SAzat Khuzhin# endif 1770f0ded5f3SAzat Khuzhin#elif defined(EVENT__HAVE___FUNCTION__) 1771f0ded5f3SAzat Khuzhin# define __func__ __FUNCTION__ 1772f0ded5f3SAzat Khuzhin#else 1773f0ded5f3SAzat Khuzhin# define __func__ __FILE__ 1774f0ded5f3SAzat Khuzhin#endif 1775f0ded5f3SAzat Khuzhin 1776f0ded5f3SAzat Khuzhin""" % { 1777f0ded5f3SAzat Khuzhin "name": name, 1778f0ded5f3SAzat Khuzhin "script_name": _NAME, 1779f0ded5f3SAzat Khuzhin "script_version": _VERSION, 1780f0ded5f3SAzat Khuzhin } 1781f0ded5f3SAzat Khuzhin 1782f0ded5f3SAzat Khuzhin for statement in CPP_DIRECT: 1783f0ded5f3SAzat Khuzhin pre += "%s\n" % statement 1784949cbd12SNiels Provos 1785949cbd12SNiels Provos pre += '\n#include "%s"\n\n' % header_file 1786949cbd12SNiels Provos 1787f0ded5f3SAzat Khuzhin pre += "void event_warn(const char *fmt, ...);\n" 1788f0ded5f3SAzat Khuzhin pre += "void event_warnx(const char *fmt, ...);\n\n" 1789e5ab86a7SNiels Provos 1790949cbd12SNiels Provos return pre 1791949cbd12SNiels Provos 1792f0ded5f3SAzat Khuzhin @staticmethod 1793f0ded5f3SAzat Khuzhin def HeaderFilename(filename): 1794f0ded5f3SAzat Khuzhin return ".".join(filename.split(".")[:-1]) + ".h" 1795226fd50aSNiels Provos 1796f0ded5f3SAzat Khuzhin @staticmethod 1797f0ded5f3SAzat Khuzhin def CodeFilename(filename): 1798f0ded5f3SAzat Khuzhin return ".".join(filename.split(".")[:-1]) + ".gen.c" 1799949cbd12SNiels Provos 1800f0ded5f3SAzat Khuzhin @staticmethod 1801f0ded5f3SAzat Khuzhin def Struct(name): 1802a7e39551SNiels Provos return StructCCode(name) 1803a7e39551SNiels Provos 1804f0ded5f3SAzat Khuzhin @staticmethod 1805f0ded5f3SAzat Khuzhin def EntryBytes(entry_type, name, tag, fixed_length): 1806a7e39551SNiels Provos return EntryBytes(entry_type, name, tag, fixed_length) 1807a7e39551SNiels Provos 1808f0ded5f3SAzat Khuzhin @staticmethod 1809f0ded5f3SAzat Khuzhin def EntryVarBytes(entry_type, name, tag): 1810a7e39551SNiels Provos return EntryVarBytes(entry_type, name, tag) 1811a7e39551SNiels Provos 1812f0ded5f3SAzat Khuzhin @staticmethod 1813f0ded5f3SAzat Khuzhin def EntryInt(entry_type, name, tag, bits=32): 181499a1063eSNiels Provos return EntryInt(entry_type, name, tag, bits) 1815a7e39551SNiels Provos 1816f0ded5f3SAzat Khuzhin @staticmethod 1817f0ded5f3SAzat Khuzhin def EntryString(entry_type, name, tag): 1818a7e39551SNiels Provos return EntryString(entry_type, name, tag) 1819a7e39551SNiels Provos 1820f0ded5f3SAzat Khuzhin @staticmethod 1821f0ded5f3SAzat Khuzhin def EntryStruct(entry_type, name, tag, struct_name): 1822a7e39551SNiels Provos return EntryStruct(entry_type, name, tag, struct_name) 1823a7e39551SNiels Provos 1824f0ded5f3SAzat Khuzhin @staticmethod 1825f0ded5f3SAzat Khuzhin def EntryArray(entry): 1826812d2fd8SNiels Provos return EntryArray(entry) 1827812d2fd8SNiels Provos 1828fbb181d1SNiels Provos 1829*48e04887SEnji Cooperclass CommandLine(object): 1830f0ded5f3SAzat Khuzhin def __init__(self, argv=None): 1831f1250eb6SNick Mathewson """Initialize a command-line to launch event_rpcgen, as if 1832f1250eb6SNick Mathewson from a command-line with CommandLine(sys.argv). If you're 1833f1250eb6SNick Mathewson calling this directly, remember to provide a dummy value 1834f1250eb6SNick Mathewson for sys.argv[0] 1835f1250eb6SNick Mathewson """ 1836f0ded5f3SAzat Khuzhin global QUIETLY 1837f0ded5f3SAzat Khuzhin 1838fbb181d1SNiels Provos self.filename = None 1839fbb181d1SNiels Provos self.header_file = None 1840fbb181d1SNiels Provos self.impl_file = None 1841fbb181d1SNiels Provos self.factory = CCodeGenerator() 1842fbb181d1SNiels Provos 1843f0ded5f3SAzat Khuzhin parser = argparse.ArgumentParser( 1844f0ded5f3SAzat Khuzhin usage="%(prog)s [options] rpc-file [[h-file] c-file]" 1845f0ded5f3SAzat Khuzhin ) 1846f0ded5f3SAzat Khuzhin parser.add_argument("--quiet", action="store_true", default=False) 1847f0ded5f3SAzat Khuzhin parser.add_argument("rpc_file", type=argparse.FileType("r")) 1848aa59c1e9SNick Mathewson 1849f0ded5f3SAzat Khuzhin args, extra_args = parser.parse_known_args(args=argv) 1850fbb181d1SNiels Provos 1851f0ded5f3SAzat Khuzhin QUIETLY = args.quiet 1852fbb181d1SNiels Provos 1853f0ded5f3SAzat Khuzhin if extra_args: 1854f0ded5f3SAzat Khuzhin if len(extra_args) == 1: 1855f0ded5f3SAzat Khuzhin self.impl_file = extra_args[0].replace("\\", "/") 1856f0ded5f3SAzat Khuzhin elif len(extra_args) == 2: 1857f0ded5f3SAzat Khuzhin self.header_file = extra_args[0].replace("\\", "/") 1858f0ded5f3SAzat Khuzhin self.impl_file = extra_args[1].replace("\\", "/") 1859f0ded5f3SAzat Khuzhin else: 1860f0ded5f3SAzat Khuzhin parser.error("Spurious arguments provided") 1861f0ded5f3SAzat Khuzhin 1862f0ded5f3SAzat Khuzhin self.rpc_file = args.rpc_file 1863fbb181d1SNiels Provos 1864fbb181d1SNiels Provos if not self.impl_file: 1865f0ded5f3SAzat Khuzhin self.impl_file = self.factory.CodeFilename(self.rpc_file.name) 1866fbb181d1SNiels Provos 1867fbb181d1SNiels Provos if not self.header_file: 1868fbb181d1SNiels Provos self.header_file = self.factory.HeaderFilename(self.impl_file) 1869fbb181d1SNiels Provos 1870f0ded5f3SAzat Khuzhin if not self.impl_file.endswith(".c"): 1871f0ded5f3SAzat Khuzhin parser.error("can only generate C implementation files") 1872f0ded5f3SAzat Khuzhin if not self.header_file.endswith(".h"): 1873f0ded5f3SAzat Khuzhin parser.error("can only generate C header files") 1874fbb181d1SNiels Provos 1875fbb181d1SNiels Provos def run(self): 1876f0ded5f3SAzat Khuzhin filename = self.rpc_file.name 1877fbb181d1SNiels Provos header_file = self.header_file 1878fbb181d1SNiels Provos impl_file = self.impl_file 1879fbb181d1SNiels Provos factory = self.factory 1880949cbd12SNiels Provos 1881f0ded5f3SAzat Khuzhin declare('Reading "%s"' % filename) 1882949cbd12SNiels Provos 1883f0ded5f3SAzat Khuzhin with self.rpc_file: 1884f0ded5f3SAzat Khuzhin entities = Parse(factory, self.rpc_file) 1885949cbd12SNiels Provos 1886aa59c1e9SNick Mathewson declare('... creating "%s"' % header_file) 1887f0ded5f3SAzat Khuzhin with open(header_file, "w") as header_fp: 1888532a8cc3SKiyoshi Aman header_fp.write(factory.HeaderPreamble(filename)) 1889949cbd12SNiels Provos 1890949cbd12SNiels Provos # Create forward declarations: allows other structs to reference 1891949cbd12SNiels Provos # each other 1892949cbd12SNiels Provos for entry in entities: 1893949cbd12SNiels Provos entry.PrintForwardDeclaration(header_fp) 1894f0ded5f3SAzat Khuzhin header_fp.write("\n") 1895949cbd12SNiels Provos 1896949cbd12SNiels Provos for entry in entities: 1897949cbd12SNiels Provos entry.PrintTags(header_fp) 1898949cbd12SNiels Provos entry.PrintDeclaration(header_fp) 1899532a8cc3SKiyoshi Aman header_fp.write(factory.HeaderPostamble(filename)) 1900949cbd12SNiels Provos 1901aa59c1e9SNick Mathewson declare('... creating "%s"' % impl_file) 1902f0ded5f3SAzat Khuzhin with open(impl_file, "w") as impl_fp: 1903532a8cc3SKiyoshi Aman impl_fp.write(factory.BodyPreamble(filename, header_file)) 1904949cbd12SNiels Provos for entry in entities: 1905949cbd12SNiels Provos entry.PrintCode(impl_fp) 1906949cbd12SNiels Provos 1907f0ded5f3SAzat Khuzhin 1908f0ded5f3SAzat Khuzhindef main(argv=None): 190937d3e16cSNiels Provos try: 1910f0ded5f3SAzat Khuzhin CommandLine(argv=argv).run() 1911f0ded5f3SAzat Khuzhin return 0 1912532a8cc3SKiyoshi Aman except RpcGenError as e: 1913532a8cc3SKiyoshi Aman sys.stderr.write(e) 1914532a8cc3SKiyoshi Aman except EnvironmentError as e: 1915fbb181d1SNiels Provos if e.filename and e.strerror: 1916532a8cc3SKiyoshi Aman sys.stderr.write("%s: %s" % (e.filename, e.strerror)) 1917fbb181d1SNiels Provos elif e.strerror: 1918532a8cc3SKiyoshi Aman sys.stderr.write(e.strerror) 1919fbb181d1SNiels Provos else: 1920fbb181d1SNiels Provos raise 1921f0ded5f3SAzat Khuzhin return 1 1922f0ded5f3SAzat Khuzhin 1923f0ded5f3SAzat Khuzhin 1924f0ded5f3SAzat Khuzhinif __name__ == "__main__": 1925f0ded5f3SAzat Khuzhin sys.exit(main(argv=sys.argv[1:])) 1926