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