15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/usr/bin/env python
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2005 Niels Provos <provos@citi.umich.edu>
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# All rights reserved.
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Generates marshaling code based on libevent.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import sys
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import re
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_NAME = "event_rpcgen.py"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_VERSION = "0.1"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_STRUCT_RE = '[a-z][a-z_0-9]*'
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Globals
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)line_count = 0
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)white = re.compile(r'^\s+')
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)cppcomment = re.compile(r'\/\/.*$')
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)headerdirect = []
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)cppdirect = []
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Holds everything that makes a struct
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Struct:
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def __init__(self, name):
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._name = name
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._entries = []
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._tags = {}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>sys.stderr, '  Created struct: %s' % name
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def AddEntry(self, entry):
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if self._tags.has_key(entry.Tag()):
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            print >>sys.stderr, ( 'Entry "%s" duplicates tag number '
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  '%d from "%s" around line %d' ) % (
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                entry.Name(), entry.Tag(),
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                self._tags[entry.Tag()], line_count)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sys.exit(1)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._entries.append(entry)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._tags[entry.Tag()] = entry.Name()
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>sys.stderr, '    Added entry: %s' % entry.Name()
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def Name(self):
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return self._name
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def EntryTagName(self, entry):
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        """Creates the name inside an enumeration for distinguishing data
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        types."""
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name = "%s_%s" % (self._name, entry.Name())
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return name.upper()
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def PrintIdented(self, file, ident, code):
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        """Takes an array, add indentation to each entry and prints it."""
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for entry in code:
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            print >>file, '%s%s' % (ident, entry)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def PrintTags(self, file):
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        """Prints the tag definitions for a structure."""
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, '/* Tag definition for %s */' % self._name
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, 'enum %s_ {' % self._name.lower()
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for entry in self._entries:
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            print >>file, '  %s=%d,' % (self.EntryTagName(entry),
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        entry.Tag())
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, '  %s_MAX_TAGS' % (self._name.upper())
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, '};\n'
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def PrintForwardDeclaration(self, file):
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, 'struct %s;' % self._name
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def PrintDeclaration(self, file):
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, '/* Structure declaration for %s */' % self._name
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, 'struct %s_access_ {' % self._name
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for entry in self._entries:
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            dcl = entry.AssignDeclaration('(*%s_assign)' % entry.Name())
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            dcl.extend(
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                entry.GetDeclaration('(*%s_get)' % entry.Name()))
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if entry.Array():
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                dcl.extend(
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    entry.AddDeclaration('(*%s_add)' % entry.Name()))
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self.PrintIdented(file, '  ', dcl)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, '};\n'
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, 'struct %s {' % self._name
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, '  struct %s_access_ *base;\n' % self._name
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for entry in self._entries:
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            dcl = entry.Declaration()
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self.PrintIdented(file, '  ', dcl)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, ''
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for entry in self._entries:
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            print >>file, '  ev_uint8_t %s_set;' % entry.Name()
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, '};\n'
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, \
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""struct %(name)s *%(name)s_new(void);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void %(name)s_free(struct %(name)s *);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void %(name)s_clear(struct %(name)s *);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void %(name)s_marshal(struct evbuffer *, const struct %(name)s *);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int %(name)s_unmarshal(struct %(name)s *, struct evbuffer *);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int %(name)s_complete(struct %(name)s *);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void evtag_marshal_%(name)s(struct evbuffer *, ev_uint32_t,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const struct %(name)s *);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    struct %(name)s *);""" % { 'name' : self._name }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Write a setting function of every variable
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for entry in self._entries:
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self.PrintIdented(file, '', entry.AssignDeclaration(
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                entry.AssignFuncName()))
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self.PrintIdented(file, '', entry.GetDeclaration(
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                entry.GetFuncName()))
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if entry.Array():
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                self.PrintIdented(file, '', entry.AddDeclaration(
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    entry.AddFuncName()))
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, '/* --- %s done --- */\n' % self._name
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def PrintCode(self, file):
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, ('/*\n'
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       ' * Implementation of %s\n'
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       ' */\n') % self._name
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, \
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              'static struct %(name)s_access_ __%(name)s_base = {' % \
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              { 'name' : self._name }
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for entry in self._entries:
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self.PrintIdented(file, '  ', entry.CodeBase())
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, '};\n'
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Creation
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, (
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            'struct %(name)s *\n'
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '%(name)s_new(void)\n'
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '{\n'
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '  struct %(name)s *tmp;\n'
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '  if ((tmp = malloc(sizeof(struct %(name)s))) == NULL) {\n'
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '    event_warn("%%s: malloc", __func__);\n'
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '    return (NULL);\n'
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '  }\n'
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '  tmp->base = &__%(name)s_base;\n') % { 'name' : self._name }
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for entry in self._entries:
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self.PrintIdented(file, '  ', entry.CodeNew('tmp'))
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            print >>file, '  tmp->%s_set = 0;\n' % entry.Name()
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, (
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '  return (tmp);\n'
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '}\n')
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Adding
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for entry in self._entries:
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if entry.Array():
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                self.PrintIdented(file, '', entry.CodeAdd())
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            print >>file, ''
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Assigning
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for entry in self._entries:
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self.PrintIdented(file, '', entry.CodeAssign())
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            print >>file, ''
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Getting
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for entry in self._entries:
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self.PrintIdented(file, '', entry.CodeGet())
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            print >>file, ''
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Clearing
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, ( 'void\n'
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        '%(name)s_clear(struct %(name)s *tmp)\n'
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        '{'
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        ) % { 'name' : self._name }
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for entry in self._entries:
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self.PrintIdented(file, '  ', entry.CodeClear('tmp'))
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, '}\n'
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Freeing
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, ( 'void\n'
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        '%(name)s_free(struct %(name)s *tmp)\n'
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        '{'
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        ) % { 'name' : self._name }
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for entry in self._entries:
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self.PrintIdented(file, '  ', entry.CodeFree('tmp'))
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, ('  free(tmp);\n'
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       '}\n')
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Marshaling
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, ('void\n'
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       '%(name)s_marshal(struct evbuffer *evbuf, '
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       'const struct %(name)s *tmp)'
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       '{') % { 'name' : self._name }
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for entry in self._entries:
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            indent = '  '
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            # Optional entries do not have to be set
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if entry.Optional():
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                indent += '  '
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                print >>file, '  if (tmp->%s_set) {' % entry.Name()
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self.PrintIdented(
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                file, indent,
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                entry.CodeMarshal('evbuf', self.EntryTagName(entry), 'tmp'))
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if entry.Optional():
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                print >>file, '  }'
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, '}\n'
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Unmarshaling
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, ('int\n'
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       '%(name)s_unmarshal(struct %(name)s *tmp, '
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       ' struct evbuffer *evbuf)\n'
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       '{\n'
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       '  ev_uint32_t tag;\n'
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       '  while (EVBUFFER_LENGTH(evbuf) > 0) {\n'
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       '    if (evtag_peek(evbuf, &tag) == -1)\n'
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       '      return (-1);\n'
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       '    switch (tag) {\n'
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       ) % { 'name' : self._name }
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for entry in self._entries:
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            print >>file, '      case %s:\n' % self.EntryTagName(entry)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if not entry.Array():
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                print >>file, (
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    '        if (tmp->%s_set)\n'
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    '          return (-1);'
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    ) % (entry.Name())
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self.PrintIdented(
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                file, '        ',
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                entry.CodeUnmarshal('evbuf',
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    self.EntryTagName(entry), 'tmp'))
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            print >>file, ( '        tmp->%s_set = 1;\n' % entry.Name() +
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            '        break;\n' )
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, ( '      default:\n'
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        '        return -1;\n'
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        '    }\n'
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        '  }\n' )
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Check if it was decoded completely
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, ( '  if (%(name)s_complete(tmp) == -1)\n'
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        '    return (-1);'
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        ) % { 'name' : self._name }
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Successfully decoded
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, ( '  return (0);\n'
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        '}\n')
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Checking if a structure has all the required data
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, (
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            'int\n'
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '%(name)s_complete(struct %(name)s *msg)\n'
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '{' ) % { 'name' : self._name }
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for entry in self._entries:
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self.PrintIdented(
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                file, '  ',
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                entry.CodeComplete('msg'))
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, (
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '  return (0);\n'
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '}\n' )
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Complete message unmarshaling
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, (
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            'int\n'
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            'evtag_unmarshal_%(name)s(struct evbuffer *evbuf, '
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            'ev_uint32_t need_tag, struct %(name)s *msg)\n'
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '{\n'
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '  ev_uint32_t tag;\n'
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '  int res = -1;\n'
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '\n'
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '  struct evbuffer *tmp = evbuffer_new();\n'
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '\n'
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '  if (evtag_unmarshal(evbuf, &tag, tmp) == -1'
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ' || tag != need_tag)\n'
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '    goto error;\n'
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '\n'
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '  if (%(name)s_unmarshal(msg, tmp) == -1)\n'
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '    goto error;\n'
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '\n'
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '  res = 0;\n'
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '\n'
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ' error:\n'
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '  evbuffer_free(tmp);\n'
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '  return (res);\n'
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '}\n' ) % { 'name' : self._name }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Complete message marshaling
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>file, (
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            'void\n'
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            'evtag_marshal_%(name)s(struct evbuffer *evbuf, ev_uint32_t tag, '
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            'const struct %(name)s *msg)\n'
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '{\n'
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '  struct evbuffer *_buf = evbuffer_new();\n'
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '  assert(_buf != NULL);\n'
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '  evbuffer_drain(_buf, -1);\n'
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '  %(name)s_marshal(_buf, msg);\n'
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '  evtag_marshal(evbuf, tag, EVBUFFER_DATA(_buf), '
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            'EVBUFFER_LENGTH(_buf));\n'
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '  evbuffer_free(_buf);\n'
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '}\n' ) % { 'name' : self._name }
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Entry:
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def __init__(self, type, name, tag):
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._type = type
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._name = name
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._tag = int(tag)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._ctype = type
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._optional = 0
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._can_be_array = 0
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._array = 0
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._line_count = -1
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._struct = None
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._refname = None
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def GetTranslation(self):
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return { "parent_name" : self._struct.Name(),
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 "name" : self._name,
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 "ctype" : self._ctype,
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 "refname" : self._refname
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 }
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def SetStruct(self, struct):
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._struct = struct
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def LineCount(self):
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        assert self._line_count != -1
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return self._line_count
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def SetLineCount(self, number):
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._line_count = number
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def Array(self):
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return self._array
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def Optional(self):
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return self._optional
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def Tag(self):
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return self._tag
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def Name(self):
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return self._name
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def Type(self):
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return self._type
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def MakeArray(self, yes=1):
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._array = yes
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def MakeOptional(self):
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._optional = 1
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def GetFuncName(self):
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return '%s_%s_get' % (self._struct.Name(), self._name)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def GetDeclaration(self, funcname):
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [ 'int %s(struct %s *, %s *);' % (
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            funcname, self._struct.Name(), self._ctype ) ]
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeGet(self):
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = (
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            'int',
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '%(parent_name)s_%(name)s_get(struct %(parent_name)s *msg, '
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '%(ctype)s *value)',
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '{',
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '  if (msg->%(name)s_set != 1)',
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '    return (-1);',
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '  *value = msg->%(name)s_data;',
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '  return (0);',
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '}' )
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = '\n'.join(code)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = code % self.GetTranslation()
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code.split('\n')
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def AssignFuncName(self):
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return '%s_%s_assign' % (self._struct.Name(), self._name)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def AddFuncName(self):
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return '%s_%s_add' % (self._struct.Name(), self._name)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def AssignDeclaration(self, funcname):
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [ 'int %s(struct %s *, const %s);' % (
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            funcname, self._struct.Name(), self._ctype ) ]
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeAssign(self):
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [ 'int',
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg,'
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 ' const %(ctype)s value)',
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '{',
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  msg->%(name)s_set = 1;',
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  msg->%(name)s_data = value;',
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  return (0);',
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '}' ]
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = '\n'.join(code)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = code % self.GetTranslation()
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code.split('\n')
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeClear(self, structname):
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [ '%s->%s_set = 0;' % (structname, self.Name()) ]
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeComplete(self, structname):
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if self.Optional():
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return []
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [ 'if (!%s->%s_set)' % (structname, self.Name()),
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  return (-1);' ]
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeFree(self, name):
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return []
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeBase(self):
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '%(parent_name)s_%(name)s_assign,',
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            '%(parent_name)s_%(name)s_get,'
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ]
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if self.Array():
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            code.append('%(parent_name)s_%(name)s_add,')
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = '\n'.join(code)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = code % self.GetTranslation()
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code.split('\n')
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def Verify(self):
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if self.Array() and not self._can_be_array:
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            print >>sys.stderr, (
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                'Entry "%s" cannot be created as an array '
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                'around line %d' ) % (self._name, self.LineCount())
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sys.exit(1)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if not self._struct:
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            print >>sys.stderr, (
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                'Entry "%s" does not know which struct it belongs to '
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                'around line %d' ) % (self._name, self.LineCount())
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sys.exit(1)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if self._optional and self._array:
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            print >>sys.stderr,  ( 'Entry "%s" has illegal combination of '
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   'optional and array around line %d' ) % (
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                self._name, self.LineCount() )
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sys.exit(1)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EntryBytes(Entry):
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def __init__(self, type, name, tag, length):
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Init base class
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Entry.__init__(self, type, name, tag)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._length = length
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._ctype = 'ev_uint8_t'
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def GetDeclaration(self, funcname):
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [ 'int %s(struct %s *, %s **);' % (
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            funcname, self._struct.Name(), self._ctype ) ]
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def AssignDeclaration(self, funcname):
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [ 'int %s(struct %s *, const %s *);' % (
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            funcname, self._struct.Name(), self._ctype ) ]
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def Declaration(self):
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dcl  = ['ev_uint8_t %s_data[%s];' % (self._name, self._length)]
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return dcl
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeGet(self):
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name = self._name
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [ 'int',
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '%s_%s_get(struct %s *msg, %s **value)' % (
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self._struct.Name(), name,
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self._struct.Name(), self._ctype),
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '{',
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  if (msg->%s_set != 1)' % name,
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '    return (-1);',
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  *value = msg->%s_data;' % name,
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  return (0);',
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '}' ]
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeAssign(self):
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name = self._name
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [ 'int',
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '%s_%s_assign(struct %s *msg, const %s *value)' % (
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self._struct.Name(), name,
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self._struct.Name(), self._ctype),
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '{',
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  msg->%s_set = 1;' % name,
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  memcpy(msg->%s_data, value, %s);' % (
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            name, self._length),
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  return (0);',
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '}' ]
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeUnmarshal(self, buf, tag_name, var_name):
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [  'if (evtag_unmarshal_fixed(%s, %s, ' % (buf, tag_name) +
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  '%s->%s_data, ' % (var_name, self._name) +
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  'sizeof(%s->%s_data)) == -1) {' % (
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            var_name, self._name),
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  '  event_warnx("%%s: failed to unmarshal %s", __func__);' % (
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self._name ),
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  '  return (-1);',
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  '}'
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  ]
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeMarshal(self, buf, tag_name, var_name):
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = ['evtag_marshal(%s, %s, %s->%s_data, sizeof(%s->%s_data));' % (
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            buf, tag_name, var_name, self._name, var_name, self._name )]
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeClear(self, structname):
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [ '%s->%s_set = 0;' % (structname, self.Name()),
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 'memset(%s->%s_data, 0, sizeof(%s->%s_data));' % (
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            structname, self._name, structname, self._name)]
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeNew(self, name):
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code  = ['memset(%s->%s_data, 0, sizeof(%s->%s_data));' % (
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            name, self._name, name, self._name)]
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def Verify(self):
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if not self._length:
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            print >>sys.stderr, 'Entry "%s" needs a length around line %d' % (
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                self._name, self.LineCount() )
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sys.exit(1)
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Entry.Verify(self)
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EntryInt(Entry):
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def __init__(self, type, name, tag):
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Init base class
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Entry.__init__(self, type, name, tag)
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._ctype = 'ev_uint32_t'
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeUnmarshal(self, buf, tag_name, var_name):
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = ['if (evtag_unmarshal_int(%s, %s, &%s->%s_data) == -1) {' % (
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            buf, tag_name, var_name, self._name),
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  '  event_warnx("%%s: failed to unmarshal %s", __func__);' % (
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self._name ),
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                '  return (-1);',
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                '}' ]
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeMarshal(self, buf, tag_name, var_name):
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = ['evtag_marshal_int(%s, %s, %s->%s_data);' % (
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            buf, tag_name, var_name, self._name)]
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def Declaration(self):
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dcl  = ['ev_uint32_t %s_data;' % self._name]
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return dcl
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeNew(self, name):
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = ['%s->%s_data = 0;' % (name, self._name)]
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EntryString(Entry):
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def __init__(self, type, name, tag):
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Init base class
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Entry.__init__(self, type, name, tag)
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._ctype = 'char *'
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeAssign(self):
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name = self._name
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = """int
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg,
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const %(ctype)s value)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (msg->%(name)s_data != NULL)
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    free(msg->%(name)s_data);
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((msg->%(name)s_data = strdup(value)) == NULL)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (-1);
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  msg->%(name)s_set = 1;
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (0);
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}""" % self.GetTranslation()
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code.split('\n')
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeUnmarshal(self, buf, tag_name, var_name):
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = ['if (evtag_unmarshal_string(%s, %s, &%s->%s_data) == -1) {' % (
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            buf, tag_name, var_name, self._name),
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                '  event_warnx("%%s: failed to unmarshal %s", __func__);' % (
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self._name ),
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                '  return (-1);',
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                '}'
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ]
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeMarshal(self, buf, tag_name, var_name):
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = ['evtag_marshal_string(%s, %s, %s->%s_data);' % (
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            buf, tag_name, var_name, self._name)]
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeClear(self, structname):
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [ 'if (%s->%s_set == 1) {' % (structname, self.Name()),
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  free (%s->%s_data);' % (structname, self.Name()),
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  %s->%s_data = NULL;' % (structname, self.Name()),
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  %s->%s_set = 0;' % (structname, self.Name()),
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '}'
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 ]
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeNew(self, name):
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code  = ['%s->%s_data = NULL;' % (name, self._name)]
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeFree(self, name):
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code  = ['if (%s->%s_data != NULL)' % (name, self._name),
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '    free (%s->%s_data); ' % (name, self._name)]
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def Declaration(self):
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dcl  = ['char *%s_data;' % self._name]
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return dcl
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EntryStruct(Entry):
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def __init__(self, type, name, tag, refname):
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Init base class
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Entry.__init__(self, type, name, tag)
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._can_be_array = 1
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._refname = refname
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._ctype = 'struct %s*' % refname
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeGet(self):
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name = self._name
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [ 'int',
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '%s_%s_get(struct %s *msg, %s *value)' % (
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self._struct.Name(), name,
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self._struct.Name(), self._ctype),
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '{',
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  if (msg->%s_set != 1) {' % name,
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '    msg->%s_data = %s_new();' % (name, self._refname),
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '    if (msg->%s_data == NULL)' % name,
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '      return (-1);',
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '    msg->%s_set = 1;' % name,
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  }',
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  *value = msg->%s_data;' % name,
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  return (0);',
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '}' ]
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeAssign(self):
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name = self._name
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = """int
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg,
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const %(ctype)s value)
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   struct evbuffer *tmp = NULL;
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (msg->%(name)s_set) {
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     %(refname)s_clear(msg->%(name)s_data);
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     msg->%(name)s_set = 0;
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   } else {
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     msg->%(name)s_data = %(refname)s_new();
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     if (msg->%(name)s_data == NULL) {
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       event_warn("%%s: %(refname)s_new()", __func__);
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       goto error;
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     }
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if ((tmp = evbuffer_new()) == NULL) {
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     event_warn("%%s: evbuffer_new()", __func__);
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     goto error;
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   %(refname)s_marshal(tmp, value);
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (%(refname)s_unmarshal(msg->%(name)s_data, tmp) == -1) {
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     event_warnx("%%s: %(refname)s_unmarshal", __func__);
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     goto error;
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   msg->%(name)s_set = 1;
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   evbuffer_free(tmp);
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   return (0);
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error:
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (tmp != NULL)
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     evbuffer_free(tmp);
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (msg->%(name)s_data != NULL) {
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     %(refname)s_free(msg->%(name)s_data);
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     msg->%(name)s_data = NULL;
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   }
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   return (-1);
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}""" % self.GetTranslation()
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code.split('\n')
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeComplete(self, structname):
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if self.Optional():
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            code = [ 'if (%s->%s_set && %s_complete(%s->%s_data) == -1)' % (
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                structname, self.Name(),
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                self._refname, structname, self.Name()),
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     '  return (-1);' ]
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else:
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            code = [ 'if (%s_complete(%s->%s_data) == -1)' % (
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                self._refname, structname, self.Name()),
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     '  return (-1);' ]
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeUnmarshal(self, buf, tag_name, var_name):
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = ['%s->%s_data = %s_new();' % (
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            var_name, self._name, self._refname),
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                'if (%s->%s_data == NULL)' % (var_name, self._name),
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                '  return (-1);',
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                'if (evtag_unmarshal_%s(%s, %s, %s->%s_data) == -1) {' % (
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self._refname, buf, tag_name, var_name, self._name),
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  '  event_warnx("%%s: failed to unmarshal %s", __func__);' % (
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self._name ),
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                '  return (-1);',
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                '}'
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ]
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeMarshal(self, buf, tag_name, var_name):
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = ['evtag_marshal_%s(%s, %s, %s->%s_data);' % (
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self._refname, buf, tag_name, var_name, self._name)]
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeClear(self, structname):
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [ 'if (%s->%s_set == 1) {' % (structname, self.Name()),
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  %s_free(%s->%s_data);' % (
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self._refname, structname, self.Name()),
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  %s->%s_data = NULL;' % (structname, self.Name()),
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  %s->%s_set = 0;' % (structname, self.Name()),
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '}'
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 ]
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeNew(self, name):
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code  = ['%s->%s_data = NULL;' % (name, self._name)]
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeFree(self, name):
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code  = ['if (%s->%s_data != NULL)' % (name, self._name),
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '    %s_free(%s->%s_data); ' % (
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self._refname, name, self._name)]
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def Declaration(self):
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dcl  = ['%s %s_data;' % (self._ctype, self._name)]
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return dcl
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EntryVarBytes(Entry):
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def __init__(self, type, name, tag):
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Init base class
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Entry.__init__(self, type, name, tag)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._ctype = 'ev_uint8_t *'
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def GetDeclaration(self, funcname):
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [ 'int %s(struct %s *, %s *, ev_uint32_t *);' % (
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            funcname, self._struct.Name(), self._ctype ) ]
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def AssignDeclaration(self, funcname):
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [ 'int %s(struct %s *, const %s, ev_uint32_t);' % (
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            funcname, self._struct.Name(), self._ctype ) ]
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeAssign(self):
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name = self._name
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [ 'int',
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '%s_%s_assign(struct %s *msg, '
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 'const %s value, ev_uint32_t len)' % (
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self._struct.Name(), name,
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self._struct.Name(), self._ctype),
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '{',
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  if (msg->%s_data != NULL)' % name,
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '    free (msg->%s_data);' % name,
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  msg->%s_data = malloc(len);' % name,
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  if (msg->%s_data == NULL)' % name,
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '    return (-1);',
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  msg->%s_set = 1;' % name,
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  msg->%s_length = len;' % name,
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  memcpy(msg->%s_data, value, len);' % name,
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  return (0);',
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '}' ]
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeGet(self):
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name = self._name
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [ 'int',
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '%s_%s_get(struct %s *msg, %s *value, ev_uint32_t *plen)' % (
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self._struct.Name(), name,
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self._struct.Name(), self._ctype),
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '{',
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  if (msg->%s_set != 1)' % name,
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '    return (-1);',
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  *value = msg->%s_data;' % name,
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  *plen = msg->%s_length;' % name,
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  return (0);',
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '}' ]
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeUnmarshal(self, buf, tag_name, var_name):
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = ['if (evtag_payload_length(%s, &%s->%s_length) == -1)' % (
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            buf, var_name, self._name),
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                '  return (-1);',
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                # We do not want DoS opportunities
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                'if (%s->%s_length > EVBUFFER_LENGTH(%s))' % (
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            var_name, self._name, buf),
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                '  return (-1);',
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                'if ((%s->%s_data = malloc(%s->%s_length)) == NULL)' % (
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            var_name, self._name, var_name, self._name),
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                '  return (-1);',
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                'if (evtag_unmarshal_fixed(%s, %s, %s->%s_data, '
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                '%s->%s_length) == -1) {' % (
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            buf, tag_name, var_name, self._name, var_name, self._name),
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                '  event_warnx("%%s: failed to unmarshal %s", __func__);' % (
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self._name ),
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                '  return (-1);',
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                '}'
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ]
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeMarshal(self, buf, tag_name, var_name):
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = ['evtag_marshal(%s, %s, %s->%s_data, %s->%s_length);' % (
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            buf, tag_name, var_name, self._name, var_name, self._name)]
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeClear(self, structname):
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [ 'if (%s->%s_set == 1) {' % (structname, self.Name()),
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  free (%s->%s_data);' % (structname, self.Name()),
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  %s->%s_data = NULL;' % (structname, self.Name()),
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  %s->%s_length = 0;' % (structname, self.Name()),
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  %s->%s_set = 0;' % (structname, self.Name()),
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '}'
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 ]
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeNew(self, name):
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code  = ['%s->%s_data = NULL;' % (name, self._name),
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '%s->%s_length = 0;' % (name, self._name) ]
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeFree(self, name):
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code  = ['if (%s->%s_data != NULL)' % (name, self._name),
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '    free (%s->%s_data); ' % (name, self._name)]
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def Declaration(self):
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dcl  = ['ev_uint8_t *%s_data;' % self._name,
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                'ev_uint32_t %s_length;' % self._name]
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return dcl
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EntryArray(Entry):
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def __init__(self, entry):
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Init base class
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Entry.__init__(self, entry._type, entry._name, entry._tag)
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._entry = entry
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._refname = entry._refname
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._ctype = 'struct %s *' % self._refname
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def GetDeclaration(self, funcname):
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        """Allows direct access to elements of the array."""
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        translate = self.GetTranslation()
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        translate["funcname"] = funcname
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            'int %(funcname)s(struct %(parent_name)s *, int, %(ctype)s *);' %
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            translate ]
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def AssignDeclaration(self, funcname):
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [ 'int %s(struct %s *, int, const %s);' % (
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            funcname, self._struct.Name(), self._ctype ) ]
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def AddDeclaration(self, funcname):
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [ '%s %s(struct %s *);' % (
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self._ctype, funcname, self._struct.Name() ) ]
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeGet(self):
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = """int
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)%(parent_name)s_%(name)s_get(struct %(parent_name)s *msg, int offset,
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    %(ctype)s *value)
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!msg->%(name)s_set || offset < 0 || offset >= msg->%(name)s_length)
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (-1);
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *value = msg->%(name)s_data[offset];
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (0);
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}""" % self.GetTranslation()
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code.split('\n')
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeAssign(self):
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = """int
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg, int off,
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const %(ctype)s value)
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct evbuffer *tmp = NULL;
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!msg->%(name)s_set || off < 0 || off >= msg->%(name)s_length)
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (-1);
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  %(refname)s_clear(msg->%(name)s_data[off]);
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((tmp = evbuffer_new()) == NULL) {
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    event_warn("%%s: evbuffer_new()", __func__);
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    goto error;
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  %(refname)s_marshal(tmp, value);
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (%(refname)s_unmarshal(msg->%(name)s_data[off], tmp) == -1) {
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    event_warnx("%%s: %(refname)s_unmarshal", __func__);
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    goto error;
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  evbuffer_free(tmp);
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (0);
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error:
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (tmp != NULL)
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    evbuffer_free(tmp);
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  %(refname)s_clear(msg->%(name)s_data[off]);
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (-1);
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}""" % self.GetTranslation()
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code.split('\n')
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeAdd(self):
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = \
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""%(ctype)s
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)%(parent_name)s_%(name)s_add(struct %(parent_name)s *msg)
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (++msg->%(name)s_length >= msg->%(name)s_num_allocated) {
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int tobe_allocated = msg->%(name)s_num_allocated;
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    %(ctype)s* new_data = NULL;
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tobe_allocated = !tobe_allocated ? 1 : tobe_allocated << 1;
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_data = (%(ctype)s*) realloc(msg->%(name)s_data,
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tobe_allocated * sizeof(%(ctype)s));
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (new_data == NULL)
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      goto error;
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    msg->%(name)s_data = new_data;
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    msg->%(name)s_num_allocated = tobe_allocated;
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  msg->%(name)s_data[msg->%(name)s_length - 1] = %(refname)s_new();
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (msg->%(name)s_data[msg->%(name)s_length - 1] == NULL)
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    goto error;
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  msg->%(name)s_set = 1;
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (msg->%(name)s_data[msg->%(name)s_length - 1]);
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error:
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --msg->%(name)s_length;
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (NULL);
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        """ % self.GetTranslation()
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code.split('\n')
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeComplete(self, structname):
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = []
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        translate = self.GetTranslation()
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if self.Optional():
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            code.append( 'if (%(structname)s->%(name)s_set)'  % translate)
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        translate["structname"] = structname
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tmp = """{
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (i = 0; i < %(structname)s->%(name)s_length; ++i) {
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (%(refname)s_complete(%(structname)s->%(name)s_data[i]) == -1)
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return (-1);
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}""" % translate
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code.extend(tmp.split('\n'))
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeUnmarshal(self, buf, tag_name, var_name):
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        translate = self.GetTranslation()
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        translate["var_name"] = var_name
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        translate["buf"] = buf
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        translate["tag_name"] = tag_name
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = """if (%(parent_name)s_%(name)s_add(%(var_name)s) == NULL)
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (-1);
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if (evtag_unmarshal_%(refname)s(%(buf)s, %(tag_name)s,
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  %(var_name)s->%(name)s_data[%(var_name)s->%(name)s_length - 1]) == -1) {
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --%(var_name)s->%(name)s_length;
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event_warnx("%%s: failed to unmarshal %(name)s", __func__);
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (-1);
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}""" % translate
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code.split('\n')
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeMarshal(self, buf, tag_name, var_name):
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = ['{',
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                '  int i;',
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                '  for (i = 0; i < %s->%s_length; ++i) {' % (
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            var_name, self._name),
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                '    evtag_marshal_%s(%s, %s, %s->%s_data[i]);' % (
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self._refname, buf, tag_name, var_name, self._name),
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                '  }',
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                '}'
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ]
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeClear(self, structname):
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code = [ 'if (%s->%s_set == 1) {' % (structname, self.Name()),
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  int i;',
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  for (i = 0; i < %s->%s_length; ++i) {' % (
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            structname, self.Name()),
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '    %s_free(%s->%s_data[i]);' % (
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self._refname, structname, self.Name()),
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  }',
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  free(%s->%s_data);' % (structname, self.Name()),
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  %s->%s_data = NULL;' % (structname, self.Name()),
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  %s->%s_set = 0;' % (structname, self.Name()),
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  %s->%s_length = 0;' % (structname, self.Name()),
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  %s->%s_num_allocated = 0;' % (structname, self.Name()),
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '}'
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 ]
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeNew(self, name):
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code  = ['%s->%s_data = NULL;' % (name, self._name),
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '%s->%s_length = 0;' % (name, self._name),
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '%s->%s_num_allocated = 0;' % (name, self._name)]
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def CodeFree(self, name):
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        code  = ['if (%s->%s_data != NULL) {' % (name, self._name),
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  int i;',
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  for (i = 0; i < %s->%s_length; ++i) {' % (
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            name, self._name),
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '    %s_free(%s->%s_data[i]); ' % (
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self._refname, name, self._name),
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '    %s->%s_data[i] = NULL;' % (name, self._name),
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  }',
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  free(%s->%s_data);' % (name, self._name),
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  %s->%s_data = NULL;' % (name, self._name),
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  %s->%s_length = 0;' % (name, self._name),
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '  %s->%s_num_allocated = 0;' % (name, self._name),
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 '}'
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 ]
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return code
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def Declaration(self):
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dcl  = ['struct %s **%s_data;' % (self._refname, self._name),
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                'int %s_length;' % self._name,
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                'int %s_num_allocated;' % self._name ]
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return dcl
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def NormalizeLine(line):
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global white
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global cppcomment
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    line = cppcomment.sub('', line)
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    line = line.strip()
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    line = white.sub(' ', line)
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return line
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def ProcessOneEntry(newstruct, entry):
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    optional = 0
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    array = 0
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry_type = ''
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    name = ''
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tag = ''
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tag_set = None
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    separator = ''
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fixed_length = ''
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tokens = entry.split(' ')
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while tokens:
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        token = tokens[0]
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tokens = tokens[1:]
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if not entry_type:
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if not optional and token == 'optional':
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                optional = 1
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                continue
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if not array and token == 'array':
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                array = 1
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                continue
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if not entry_type:
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            entry_type = token
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            continue
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if not name:
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            res = re.match(r'^([^\[\]]+)(\[.*\])?$', token)
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if not res:
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                print >>sys.stderr, 'Cannot parse name: \"%s\" around %d' % (
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    entry, line_count)
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                sys.exit(1)
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            name = res.group(1)
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fixed_length = res.group(2)
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if fixed_length:
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                fixed_length = fixed_length[1:-1]
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            continue
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if not separator:
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            separator = token
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if separator != '=':
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                print >>sys.stderr, 'Expected "=" after name \"%s\" got %s' % (
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    name, token)
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                sys.exit(1)
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            continue
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if not tag_set:
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            tag_set = 1
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if not re.match(r'^(0x)?[0-9]+$', token):
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                print >>sys.stderr, 'Expected tag number: \"%s\"' % entry
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                sys.exit(1)
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            tag = int(token, 0)
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            continue
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>sys.stderr, 'Cannot parse \"%s\"' % entry
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sys.exit(1)
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not tag_set:
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>sys.stderr, 'Need tag number: \"%s\"' % entry
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sys.exit(1)
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Create the right entry
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if entry_type == 'bytes':
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if fixed_length:
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            newentry = EntryBytes(entry_type, name, tag, fixed_length)
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else:
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            newentry = EntryVarBytes(entry_type, name, tag)
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    elif entry_type == 'int' and not fixed_length:
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        newentry = EntryInt(entry_type, name, tag)
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    elif entry_type == 'string' and not fixed_length:
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        newentry = EntryString(entry_type, name, tag)
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else:
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        res = re.match(r'^struct\[(%s)\]$' % _STRUCT_RE,
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       entry_type, re.IGNORECASE)
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if res:
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            # References another struct defined in our file
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            newentry = EntryStruct(entry_type, name, tag, res.group(1))
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else:
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            print >>sys.stderr, 'Bad type: "%s" in "%s"' % (entry_type, entry)
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sys.exit(1)
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    structs = []
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if optional:
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        newentry.MakeOptional()
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if array:
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        newentry.MakeArray()
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    newentry.SetStruct(newstruct)
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    newentry.SetLineCount(line_count)
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    newentry.Verify()
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if array:
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # We need to encapsulate this entry into a struct
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        newname = newentry.Name()+ '_array'
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Now borgify the new entry.
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        newentry = EntryArray(newentry)
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        newentry.SetStruct(newstruct)
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        newentry.SetLineCount(line_count)
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        newentry.MakeArray()
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    newstruct.AddEntry(newentry)
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return structs
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def ProcessStruct(data):
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tokens = data.split(' ')
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # First three tokens are: 'struct' 'name' '{'
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    newstruct = Struct(tokens[1])
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inside = ' '.join(tokens[3:-1])
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tokens = inside.split(';')
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    structs = []
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for entry in tokens:
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entry = NormalizeLine(entry)
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if not entry:
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            continue
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # It's possible that new structs get defined in here
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        structs.extend(ProcessOneEntry(newstruct, entry))
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    structs.append(newstruct)
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return structs
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def GetNextStruct(file):
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global line_count
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global cppdirect
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    got_struct = 0
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    processed_lines = []
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    have_c_comment = 0
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data = ''
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while 1:
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        line = file.readline()
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if not line:
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        line_count += 1
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        line = line[:-1]
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if not have_c_comment and re.search(r'/\*', line):
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if re.search(r'/\*.*\*/', line):
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                line = re.sub(r'/\*.*\*/', '', line)
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else:
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                line = re.sub(r'/\*.*$', '', line)
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                have_c_comment = 1
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if have_c_comment:
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if not re.search(r'\*/', line):
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                continue
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            have_c_comment = 0
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            line = re.sub(r'^.*\*/', '', line)
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        line = NormalizeLine(line)
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if not line:
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            continue
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if not got_struct:
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if re.match(r'#include ["<].*[>"]', line):
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                cppdirect.append(line)
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                continue
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if re.match(r'^#(if( |def)|endif)', line):
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                cppdirect.append(line)
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                continue
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if re.match(r'^#define', line):
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                headerdirect.append(line)
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                continue
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if not re.match(r'^struct %s {$' % _STRUCT_RE,
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            line, re.IGNORECASE):
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                print >>sys.stderr, 'Missing struct on line %d: %s' % (
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    line_count, line)
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                sys.exit(1)
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else:
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                got_struct = 1
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                data += line
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            continue
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # We are inside the struct
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tokens = line.split('}')
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if len(tokens) == 1:
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            data += ' ' + line
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            continue
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if len(tokens[1]):
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            print >>sys.stderr, 'Trailing garbage after struct on line %d' % (
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                line_count )
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sys.exit(1)
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # We found the end of the struct
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        data += ' %s}' % tokens[0]
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Remove any comments, that might be in there
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data = re.sub(r'/\*.*\*/', '', data)
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return data
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def Parse(file):
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Parses the input file and returns C code and corresponding header file.
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entities = []
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while 1:
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Just gets the whole struct nicely formatted
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        data = GetNextStruct(file)
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if not data:
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entities.extend(ProcessStruct(data))
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return entities
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def GuardName(name):
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    name = '_'.join(name.split('.'))
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    name = '_'.join(name.split('/'))
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    guard = '_'+name.upper()+'_'
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return guard
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def HeaderPreamble(name):
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    guard = GuardName(name)
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pre = (
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        '/*\n'
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ' * Automatically generated from %s\n'
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ' */\n\n'
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        '#ifndef %s\n'
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        '#define %s\n\n' ) % (
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name, guard, guard)
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # insert stdint.h - let's hope everyone has it
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pre += (
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        '#include <event-config.h>\n'
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        '#ifdef _EVENT_HAVE_STDINT_H\n'
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        '#include <stdint.h>\n'
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        '#endif\n' )
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for statement in headerdirect:
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pre += '%s\n' % statement
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if headerdirect:
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pre += '\n'
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pre += (
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        '#define EVTAG_HAS(msg, member) ((msg)->member##_set == 1)\n'
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        '#ifdef __GNUC__\n'
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        '#define EVTAG_ASSIGN(msg, member, args...) '
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        '(*(msg)->base->member##_assign)(msg, ## args)\n'
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        '#define EVTAG_GET(msg, member, args...) '
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        '(*(msg)->base->member##_get)(msg, ## args)\n'
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        '#else\n'
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        '#define EVTAG_ASSIGN(msg, member, ...) '
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        '(*(msg)->base->member##_assign)(msg, ## __VA_ARGS__)\n'
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        '#define EVTAG_GET(msg, member, ...) '
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        '(*(msg)->base->member##_get)(msg, ## __VA_ARGS__)\n'
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        '#endif\n'
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        '#define EVTAG_ADD(msg, member) (*(msg)->base->member##_add)(msg)\n'
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        '#define EVTAG_LEN(msg, member) ((msg)->member##_length)\n'
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        )
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return pre
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def HeaderPostamble(name):
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    guard = GuardName(name)
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return '#endif  /* %s */' % guard
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def BodyPreamble(name):
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global _NAME
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    global _VERSION
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    header_file = '.'.join(name.split('.')[:-1]) + '.gen.h'
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pre = ( '/*\n'
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ' * Automatically generated from %s\n'
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ' * by %s/%s.  DO NOT EDIT THIS FILE.\n'
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ' */\n\n' ) % (name, _NAME, _VERSION)
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pre += ( '#include <sys/types.h>\n'
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             '#ifdef _EVENT_HAVE_SYS_TIME_H\n'
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             '#include <sys/time.h>\n'
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             '#endif\n'
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             '#include <stdlib.h>\n'
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             '#include <string.h>\n'
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             '#include <assert.h>\n'
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             '#define EVENT_NO_STRUCT\n'
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             '#include <event.h>\n\n'
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             '#ifdef _EVENT___func__\n'
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             '#define __func__ _EVENT___func__\n'
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             '#endif\n' )
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for statement in cppdirect:
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pre += '%s\n' % statement
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pre += '\n#include "%s"\n\n' % header_file
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pre += 'void event_err(int eval, const char *fmt, ...);\n'
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pre += 'void event_warn(const char *fmt, ...);\n'
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pre += 'void event_errx(int eval, const char *fmt, ...);\n'
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pre += 'void event_warnx(const char *fmt, ...);\n\n'
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return pre
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def main(argv):
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if len(argv) < 2 or not argv[1]:
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>sys.stderr, 'Need RPC description file as first argument.'
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sys.exit(1)
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filename = argv[1]
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ext = filename.split('.')[-1]
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ext != 'rpc':
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        print >>sys.stderr, 'Unrecognized file extension: %s' % ext
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sys.exit(1)
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    print >>sys.stderr, 'Reading \"%s\"' % filename
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fp = open(filename, 'r')
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entities = Parse(fp)
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fp.close()
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    header_file = '.'.join(filename.split('.')[:-1]) + '.gen.h'
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    impl_file = '.'.join(filename.split('.')[:-1]) + '.gen.c'
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    print >>sys.stderr, '... creating "%s"' % header_file
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    header_fp = open(header_file, 'w')
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    print >>header_fp, HeaderPreamble(filename)
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Create forward declarations: allows other structs to reference
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # each other
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for entry in entities:
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entry.PrintForwardDeclaration(header_fp)
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    print >>header_fp, ''
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for entry in entities:
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entry.PrintTags(header_fp)
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entry.PrintDeclaration(header_fp)
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    print >>header_fp, HeaderPostamble(filename)
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    header_fp.close()
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    print >>sys.stderr, '... creating "%s"' % impl_file
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    impl_fp = open(impl_file, 'w')
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    print >>impl_fp, BodyPreamble(filename)
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for entry in entities:
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entry.PrintCode(impl_fp)
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    impl_fp.close()
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if __name__ == '__main__':
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    main(sys.argv)
1424