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