12 _NAME = 
"event_rpcgen.py" 
   14 _STRUCT_RE = 
'[a-z][a-z_0-9]*' 
   19 white = re.compile(
r'^\s+')
 
   20 cppcomment = re.compile(
r'\/\/.*$')
 
   26     def __init__(self, name):
 
   30         print >>sys.stderr, 
'  Created struct: %s' % name
 
   32     def AddEntry(self, entry):
 
   33         if self._tags.has_key(entry.Tag()):
 
   34             print >>sys.stderr, ( 
'Entry "%s" duplicates tag number ' 
   35                                   '%d from "%s" around line %d' ) % (
 
   36                 entry.Name(), entry.Tag(),
 
   37                 self.
_tags[entry.Tag()], line_count)
 
   39         self._entries.append(entry)
 
   40         self.
_tags[entry.Tag()] = entry.Name()
 
   41         print >>sys.stderr, 
'    Added entry: %s' % entry.Name()
 
   47         """Creates the name inside an enumeration for distinguishing data 
   49         name = 
"%s_%s" % (self.
_name, entry.Name())
 
   53         """Takes an array, add indentation to each entry and prints it.""" 
   55             print >>file, 
'%s%s' % (ident, entry)
 
   58         """Prints the tag definitions for a structure.""" 
   59         print >>file, 
'/* Tag definition for %s */' % self.
_name 
   60         print >>file, 
'enum %s_ {' % self._name.lower()
 
   64         print >>file, 
'  %s_MAX_TAGS' % (self._name.upper())
 
   67     def PrintForwardDeclaration(self, file):
 
   68         print >>file, 
'struct %s;' % self.
_name 
   70     def PrintDeclaration(self, file):
 
   71         print >>file, 
'/* Structure declaration for %s */' % self.
_name 
   72         print >>file, 
'struct %s_access_ {' % self.
_name 
   74             dcl = entry.AssignDeclaration(
'(*%s_assign)' % entry.Name())
 
   76                 entry.GetDeclaration(
'(*%s_get)' % entry.Name()))
 
   79                     entry.AddDeclaration(
'(*%s_add)' % entry.Name()))
 
   83         print >>file, 
'struct %s {' % self.
_name 
   84         print >>file, 
'  struct %s_access_ *base;\n' % self.
_name 
   86             dcl = entry.Declaration()
 
   90             print >>file, 
'  uint8_t %s_set;' % entry.Name()
 
   94 """struct %(name)s *%(name)s_new(void); 
   95 void %(name)s_free(struct %(name)s *); 
   96 void %(name)s_clear(struct %(name)s *); 
   97 void %(name)s_marshal(struct evbuffer *, const struct %(name)s *); 
   98 int %(name)s_unmarshal(struct %(name)s *, struct evbuffer *); 
   99 int %(name)s_complete(struct %(name)s *); 
  100 void evtag_marshal_%(name)s(struct evbuffer *, uint32_t,  
  101     const struct %(name)s *); 
  102 int evtag_unmarshal_%(name)s(struct evbuffer *, uint32_t, 
  103     struct %(name)s *);""" % { 
'name' : self.
_name }
 
  109                 entry.AssignFuncName()))
 
  111                 entry.GetFuncName()))
 
  114                     entry.AddFuncName()))
 
  116         print >>file, 
'/* --- %s done --- */\n' % self.
_name 
  118     def PrintCode(self, file):
 
  119         print >>file, (
'/*\n' 
  120                        ' * Implementation of %s\n' 
  121                        ' */\n') % self.
_name 
  124               'static struct %(name)s_access_ __%(name)s_base = {' % \
 
  125               { 
'name' : self.
_name }
 
  132             'struct %(name)s *\n' 
  133             '%(name)s_new(void)\n' 
  135             '  struct %(name)s *tmp;\n' 
  136             '  if ((tmp = malloc(sizeof(struct %(name)s))) == NULL) {\n' 
  137             '    event_warn("%%s: malloc", __func__);\n' 
  140             '  tmp->base = &__%(name)s_base;\n') % { 
'name' : self.
_name }
 
  144             print >>file, 
'  tmp->%s_set = 0;\n' % entry.Name()
 
  167         print >>file, ( 
'void\n' 
  168                         '%(name)s_clear(struct %(name)s *tmp)\n' 
  170                         ) % { 
'name' : self.
_name }
 
  177         print >>file, ( 
'void\n' 
  178                         '%(name)s_free(struct %(name)s *tmp)\n' 
  180                         ) % { 
'name' : self.
_name }
 
  185         print >>file, (
'  free(tmp);\n' 
  189         print >>file, (
'void\n' 
  190                        '%(name)s_marshal(struct evbuffer *evbuf, ' 
  191                        'const struct %(name)s *tmp)' 
  192                        '{') % { 
'name' : self.
_name }
 
  198                 print >>file, 
'  if (tmp->%s_set) {' % entry.Name()
 
  201                 entry.CodeMarshal(
'evbuf', self.
EntryTagName(entry), 
'tmp'))
 
  208         print >>file, (
'int\n' 
  209                        '%(name)s_unmarshal(struct %(name)s *tmp, ' 
  210                        ' struct evbuffer *evbuf)\n' 
  213                        '  while (EVBUFFER_LENGTH(evbuf) > 0) {\n' 
  214                        '    if (evtag_peek(evbuf, &tag) == -1)\n' 
  217                        ) % { 
'name' : self.
_name }
 
  220             if not entry.Array():
 
  222                     '        if (tmp->%s_set)\n' 
  228                 entry.CodeUnmarshal(
'evbuf',
 
  231             print >>file, ( 
'        tmp->%s_set = 1;\n' % entry.Name() +
 
  233         print >>file, ( 
'      default:\n' 
  238         print >>file, ( 
'  if (%(name)s_complete(tmp) == -1)\n' 
  240                         ) % { 
'name' : self.
_name }
 
  243         print >>file, ( 
'  return (0);\n' 
  249             '%(name)s_complete(struct %(name)s *msg)\n' 
  250             '{' ) % { 
'name' : self.
_name }
 
  254                 entry.CodeComplete(
'msg'))
 
  262             'evtag_unmarshal_%(name)s(struct evbuffer *evbuf, ' 
  263             'uint32_t need_tag, struct %(name)s *msg)\n' 
  268             '  struct evbuffer *tmp = evbuffer_new();\n' 
  270             '  if (evtag_unmarshal(evbuf, &tag, tmp) == -1' 
  271             ' || tag != need_tag)\n' 
  274             '  if (%(name)s_unmarshal(msg, tmp) == -1)\n' 
  280             '  evbuffer_free(tmp);\n' 
  282             '}\n' ) % { 
'name' : self.
_name }
 
  287             'evtag_marshal_%(name)s(struct evbuffer *evbuf, uint32_t tag, ' 
  288             'const struct %(name)s *msg)\n' 
  290             '  struct evbuffer *_buf = evbuffer_new();\n' 
  291             '  assert(_buf != NULL);\n' 
  292             '  evbuffer_drain(_buf, -1);\n' 
  293             '  %(name)s_marshal(_buf, msg);\n' 
  294             '  evtag_marshal(evbuf, tag, EVBUFFER_DATA(_buf), ' 
  295             'EVBUFFER_LENGTH(_buf));\n' 
  296             '  evbuffer_free(_buf);\n' 
  297             '}\n' ) % { 
'name' : self.
_name }
 
  300     def __init__(self, type, name, tag):
 
  312     def GetTranslation(self):
 
  313         return { 
"parent_name" : self._struct.Name(),
 
  319     def SetStruct(self, struct):
 
  326     def SetLineCount(self, number):
 
  344     def MakeArray(self, yes=1):
 
  347     def MakeOptional(self):
 
  350     def GetFuncName(self):
 
  351         return '%s_%s_get' % (self._struct.Name(), self.
_name)
 
  353     def GetDeclaration(self, funcname):
 
  354         code = [ 
'int %s(struct %s *, %s *);' % (
 
  355             funcname, self._struct.Name(), self.
_ctype ) ]
 
  361             '%(parent_name)s_%(name)s_get(struct %(parent_name)s *msg, ' 
  364             '  if (msg->%(name)s_set != 1)',
 
  366             '  *value = msg->%(name)s_data;',
 
  369         code = 
'\n'.join(code)
 
  371         return code.split(
'\n')
 
  373     def AssignFuncName(self):
 
  374         return '%s_%s_assign' % (self._struct.Name(), self.
_name)
 
  376     def AddFuncName(self):
 
  377         return '%s_%s_add' % (self._struct.Name(), self.
_name)
 
  379     def AssignDeclaration(self, funcname):
 
  380         code = [ 
'int %s(struct %s *, const %s);' % (
 
  381             funcname, self._struct.Name(), self.
_ctype ) ]
 
  384     def CodeAssign(self):
 
  386                  '%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg,' 
  387                  ' const %(ctype)s value)',
 
  389                  '  msg->%(name)s_set = 1;',
 
  390                  '  msg->%(name)s_data = value;',
 
  393         code = 
'\n'.join(code)
 
  395         return code.split(
'\n')
 
  397     def CodeClear(self, structname):
 
  398         code = [ 
'%s->%s_set = 0;' % (structname, self.
Name()) ]
 
  402     def CodeComplete(self, structname):
 
  406         code = [ 
'if (!%s->%s_set)' % (structname, self.
Name()),
 
  411     def CodeFree(self, name):
 
  416             '%(parent_name)s_%(name)s_assign,',
 
  417             '%(parent_name)s_%(name)s_get,' 
  420             code.append(
'%(parent_name)s_%(name)s_add,')
 
  422         code = 
'\n'.join(code)
 
  424         return code.split(
'\n')
 
  428             print >>sys.stderr, (
 
  429                 'Entry "%s" cannot be created as an array ' 
  433             print >>sys.stderr, (
 
  434                 'Entry "%s" does not know which struct it belongs to ' 
  438             print >>sys.stderr,  ( 
'Entry "%s" has illegal combination of ' 
  439                                    'optional and array around line %d' ) % (
 
  444     def __init__(self, type, name, tag, length):
 
  446         Entry.__init__(self, type, name, tag)
 
  451     def GetDeclaration(self, funcname):
 
  452         code = [ 
'int %s(struct %s *, %s **);' % (
 
  453             funcname, self._struct.Name(), self.
_ctype ) ]
 
  456     def AssignDeclaration(self, funcname):
 
  457         code = [ 
'int %s(struct %s *, const %s *);' % (
 
  458             funcname, self._struct.Name(), self.
_ctype ) ]
 
  461     def Declaration(self):
 
  462         dcl  = [
'uint8_t %s_data[%s];' % (self.
_name, self.
_length)]
 
  469                  '%s_%s_get(struct %s *msg, %s **value)' % (
 
  470             self._struct.Name(), name,
 
  471             self._struct.Name(), self.
_ctype),
 
  473                  '  if (msg->%s_set != 1)' % name,
 
  475                  '  *value = msg->%s_data;' % name,
 
  480     def CodeAssign(self):
 
  483                  '%s_%s_assign(struct %s *msg, const %s *value)' % (
 
  484             self._struct.Name(), name,
 
  485             self._struct.Name(), self.
_ctype),
 
  487                  '  msg->%s_set = 1;' % name,
 
  488                  '  memcpy(msg->%s_data, value, %s);' % (
 
  494     def CodeUnmarshal(self, buf, tag_name, var_name):
 
  495         code = [  
'if (evtag_unmarshal_fixed(%s, %s, ' % (buf, tag_name) +
 
  496                   '%s->%s_data, ' % (var_name, self.
_name) +
 
  497                   'sizeof(%s->%s_data)) == -1) {' % (
 
  498             var_name, self.
_name),
 
  499                   '  event_warnx("%%s: failed to unmarshal %s", __func__);' % (
 
  506     def CodeMarshal(self, buf, tag_name, var_name):
 
  507         code = [
'evtag_marshal(%s, %s, %s->%s_data, sizeof(%s->%s_data));' % (
 
  508             buf, tag_name, var_name, self.
_name, var_name, self.
_name )]
 
  511     def CodeClear(self, structname):
 
  512         code = [ 
'%s->%s_set = 0;' % (structname, self.
Name()),
 
  513                  'memset(%s->%s_data, 0, sizeof(%s->%s_data));' % (
 
  514             structname, self.
_name, structname, self.
_name)]
 
  518     def CodeNew(self, name):
 
  519         code  = [
'memset(%s->%s_data, 0, sizeof(%s->%s_data));' % (
 
  525             print >>sys.stderr, 
'Entry "%s" needs a length around line %d' % (
 
  532     def __init__(self, type, name, tag):
 
  534         Entry.__init__(self, type, name, tag)
 
  538     def CodeUnmarshal(self, buf, tag_name, var_name):
 
  539         code = [
'if (evtag_unmarshal_int(%s, %s, &%s->%s_data) == -1) {' % (
 
  540             buf, tag_name, var_name, self.
_name),
 
  541                   '  event_warnx("%%s: failed to unmarshal %s", __func__);' % (
 
  547     def CodeMarshal(self, buf, tag_name, var_name):
 
  548         code = [
'evtag_marshal_int(%s, %s, %s->%s_data);' % (
 
  549             buf, tag_name, var_name, self.
_name)]
 
  552     def Declaration(self):
 
  553         dcl  = [
'uint32_t %s_data;' % self.
_name]
 
  557     def CodeNew(self, name):
 
  558         code = [
'%s->%s_data = 0;' % (name, self.
_name)]
 
  562     def __init__(self, type, name, tag):
 
  564         Entry.__init__(self, type, name, tag)
 
  568     def CodeAssign(self):
 
  571 %(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg, 
  572     const %(ctype)s value) 
  574   if (msg->%(name)s_data != NULL) 
  575     free(msg->%(name)s_data); 
  576   if ((msg->%(name)s_data = strdup(value)) == NULL) 
  578   msg->%(name)s_set = 1; 
  582         return code.split(
'\n')
 
  584     def CodeUnmarshal(self, buf, tag_name, var_name):
 
  585         code = [
'if (evtag_unmarshal_string(%s, %s, &%s->%s_data) == -1) {' % (
 
  586             buf, tag_name, var_name, self.
_name),
 
  587                 '  event_warnx("%%s: failed to unmarshal %s", __func__);' % (
 
  594     def CodeMarshal(self, buf, tag_name, var_name):
 
  595         code = [
'evtag_marshal_string(%s, %s, %s->%s_data);' % (
 
  596             buf, tag_name, var_name, self.
_name)]
 
  599     def CodeClear(self, structname):
 
  600         code = [ 
'if (%s->%s_set == 1) {' % (structname, self.
Name()),
 
  601                  '  free (%s->%s_data);' % (structname, self.
Name()),
 
  602                  '  %s->%s_data = NULL;' % (structname, self.
Name()),
 
  603                  '  %s->%s_set = 0;' % (structname, self.
Name()),
 
  609     def CodeNew(self, name):
 
  610         code  = [
'%s->%s_data = NULL;' % (name, self.
_name)]
 
  613     def CodeFree(self, name):
 
  614         code  = [
'if (%s->%s_data != NULL)' % (name, self.
_name),
 
  615                  '    free (%s->%s_data); ' % (name, self.
_name)]
 
  619     def Declaration(self):
 
  620         dcl  = [
'char *%s_data;' % self.
_name]
 
  625     def __init__(self, type, name, tag, refname):
 
  627         Entry.__init__(self, type, name, tag)
 
  631         self.
_ctype = 
'struct %s*' % refname
 
  636                  '%s_%s_get(struct %s *msg, %s *value)' % (
 
  637             self._struct.Name(), name,
 
  638             self._struct.Name(), self.
_ctype),
 
  640                  '  if (msg->%s_set != 1) {' % name,
 
  641                  '    msg->%s_data = %s_new();' % (name, self.
_refname),
 
  642                  '    if (msg->%s_data == NULL)' % name,
 
  644                  '    msg->%s_set = 1;' % name,
 
  646                  '  *value = msg->%s_data;' % name,
 
  651     def CodeAssign(self):
 
  654 %(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg, 
  655     const %(ctype)s value) 
  657    struct evbuffer *tmp = NULL; 
  658    if (msg->%(name)s_set) { 
  659      %(refname)s_clear(msg->%(name)s_data); 
  660      msg->%(name)s_set = 0; 
  662      msg->%(name)s_data = %(refname)s_new(); 
  663      if (msg->%(name)s_data == NULL) { 
  664        event_warn("%%s: %(refname)s_new()", __func__); 
  668    if ((tmp = evbuffer_new()) == NULL) { 
  669      event_warn("%%s: evbuffer_new()", __func__); 
  672    %(refname)s_marshal(tmp, value); 
  673    if (%(refname)s_unmarshal(msg->%(name)s_data, tmp) == -1) { 
  674      event_warnx("%%s: %(refname)s_unmarshal", __func__); 
  677    msg->%(name)s_set = 1; 
  683    if (msg->%(name)s_data != NULL) { 
  684      %(refname)s_free(msg->%(name)s_data); 
  685      msg->%(name)s_data = NULL; 
  689         return code.split(
'\n')
 
  691     def CodeComplete(self, structname):
 
  693             code = [ 
'if (%s->%s_set && %s_complete(%s->%s_data) == -1)' % (
 
  694                 structname, self.
Name(),
 
  698             code = [ 
'if (%s_complete(%s->%s_data) == -1)' % (
 
  704     def CodeUnmarshal(self, buf, tag_name, var_name):
 
  705         code = [
'%s->%s_data = %s_new();' % (
 
  707                 'if (%s->%s_data == NULL)' % (var_name, self.
_name),
 
  709                 'if (evtag_unmarshal_%s(%s, %s, %s->%s_data) == -1) {' % (
 
  711                   '  event_warnx("%%s: failed to unmarshal %s", __func__);' % (
 
  718     def CodeMarshal(self, buf, tag_name, var_name):
 
  719         code = [
'evtag_marshal_%s(%s, %s, %s->%s_data);' % (
 
  723     def CodeClear(self, structname):
 
  724         code = [ 
'if (%s->%s_set == 1) {' % (structname, self.
Name()),
 
  725                  '  %s_free(%s->%s_data);' % (
 
  727                  '  %s->%s_data = NULL;' % (structname, self.
Name()),
 
  728                  '  %s->%s_set = 0;' % (structname, self.
Name()),
 
  734     def CodeNew(self, name):
 
  735         code  = [
'%s->%s_data = NULL;' % (name, self.
_name)]
 
  738     def CodeFree(self, name):
 
  739         code  = [
'if (%s->%s_data != NULL)' % (name, self.
_name),
 
  740                  '    %s_free(%s->%s_data); ' % (
 
  745     def Declaration(self):
 
  751     def __init__(self, type, name, tag):
 
  753         Entry.__init__(self, type, name, tag)
 
  757     def GetDeclaration(self, funcname):
 
  758         code = [ 
'int %s(struct %s *, %s *, uint32_t *);' % (
 
  759             funcname, self._struct.Name(), self.
_ctype ) ]
 
  762     def AssignDeclaration(self, funcname):
 
  763         code = [ 
'int %s(struct %s *, const %s, uint32_t);' % (
 
  764             funcname, self._struct.Name(), self.
_ctype ) ]
 
  767     def CodeAssign(self):
 
  770                  '%s_%s_assign(struct %s *msg, ' 
  771                  'const %s value, uint32_t len)' % (
 
  772             self._struct.Name(), name,
 
  773             self._struct.Name(), self.
_ctype),
 
  775                  '  if (msg->%s_data != NULL)' % name,
 
  776                  '    free (msg->%s_data);' % name,
 
  777                  '  msg->%s_data = malloc(len);' % name,
 
  778                  '  if (msg->%s_data == NULL)' % name,
 
  780                  '  msg->%s_set = 1;' % name,
 
  781                  '  msg->%s_length = len;' % name,
 
  782                  '  memcpy(msg->%s_data, value, len);' % name,
 
  790                  '%s_%s_get(struct %s *msg, %s *value, uint32_t *plen)' % (
 
  791             self._struct.Name(), name,
 
  792             self._struct.Name(), self.
_ctype),
 
  794                  '  if (msg->%s_set != 1)' % name,
 
  796                  '  *value = msg->%s_data;' % name,
 
  797                  '  *plen = msg->%s_length;' % name,
 
  802     def CodeUnmarshal(self, buf, tag_name, var_name):
 
  803         code = [
'if (evtag_payload_length(%s, &%s->%s_length) == -1)' % (
 
  804             buf, var_name, self.
_name),
 
  807                 'if (%s->%s_length > EVBUFFER_LENGTH(%s))' % (
 
  808             var_name, self.
_name, buf),
 
  810                 'if ((%s->%s_data = malloc(%s->%s_length)) == NULL)' % (
 
  813                 'if (evtag_unmarshal_fixed(%s, %s, %s->%s_data, ' 
  814                 '%s->%s_length) == -1) {' % (
 
  815             buf, tag_name, var_name, self.
_name, var_name, self.
_name),
 
  816                 '  event_warnx("%%s: failed to unmarshal %s", __func__);' % (
 
  823     def CodeMarshal(self, buf, tag_name, var_name):
 
  824         code = [
'evtag_marshal(%s, %s, %s->%s_data, %s->%s_length);' % (
 
  825             buf, tag_name, var_name, self.
_name, var_name, self.
_name)]
 
  828     def CodeClear(self, structname):
 
  829         code = [ 
'if (%s->%s_set == 1) {' % (structname, self.
Name()),
 
  830                  '  free (%s->%s_data);' % (structname, self.
Name()),
 
  831                  '  %s->%s_data = NULL;' % (structname, self.
Name()),
 
  832                  '  %s->%s_length = 0;' % (structname, self.
Name()),
 
  833                  '  %s->%s_set = 0;' % (structname, self.
Name()),
 
  839     def CodeNew(self, name):
 
  840         code  = [
'%s->%s_data = NULL;' % (name, self.
_name),
 
  841                  '%s->%s_length = 0;' % (name, self.
_name) ]
 
  844     def CodeFree(self, name):
 
  845         code  = [
'if (%s->%s_data != NULL)' % (name, self.
_name),
 
  846                  '    free (%s->%s_data); ' % (name, self.
_name)]
 
  850     def Declaration(self):
 
  851         dcl  = [
'uint8_t *%s_data;' % self.
_name,
 
  852                 'uint32_t %s_length;' % self.
_name]
 
  857     def __init__(self, entry):
 
  859         Entry.__init__(self, entry._type, entry._name, entry._tag)
 
  866         """Allows direct access to elements of the array.""" 
  868         translate[
"funcname"] = funcname
 
  870             'int %(funcname)s(struct %(parent_name)s *, int, %(ctype)s *);' %
 
  874     def AssignDeclaration(self, funcname):
 
  875         code = [ 
'int %s(struct %s *, int, const %s);' % (
 
  876             funcname, self._struct.Name(), self.
_ctype ) ]
 
  879     def AddDeclaration(self, funcname):
 
  880         code = [ 
'%s %s(struct %s *);' % (
 
  881             self.
_ctype, funcname, self._struct.Name() ) ]
 
  886 %(parent_name)s_%(name)s_get(struct %(parent_name)s *msg, int offset, 
  889   if (!msg->%(name)s_set || offset < 0 || offset >= msg->%(name)s_length) 
  891   *value = msg->%(name)s_data[offset]; 
  895         return code.split(
'\n')
 
  897     def CodeAssign(self):
 
  899 %(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg, int off, 
  900     const %(ctype)s value) 
  902   struct evbuffer *tmp = NULL; 
  903   if (!msg->%(name)s_set || off < 0 || off >= msg->%(name)s_length) 
  905   %(refname)s_clear(msg->%(name)s_data[off]); 
  906   if ((tmp = evbuffer_new()) == NULL) { 
  907     event_warn("%%s: evbuffer_new()", __func__); 
  910   %(refname)s_marshal(tmp, value); 
  911   if (%(refname)s_unmarshal(msg->%(name)s_data[off], tmp) == -1) { 
  912     event_warnx("%%s: %(refname)s_unmarshal", __func__); 
  920   %(refname)s_clear(msg->%(name)s_data[off]); 
  924         return code.split(
'\n')
 
  929 %(parent_name)s_%(name)s_add(struct %(parent_name)s *msg) 
  931   if (++msg->%(name)s_length >= msg->%(name)s_num_allocated) { 
  932     int tobe_allocated = msg->%(name)s_num_allocated; 
  933     %(ctype)s* new_data = NULL; 
  934     tobe_allocated = !tobe_allocated ? 1 : tobe_allocated << 1; 
  935     new_data = (%(ctype)s*) realloc(msg->%(name)s_data, 
  936         tobe_allocated * sizeof(%(ctype)s)); 
  937     if (new_data == NULL) 
  939     msg->%(name)s_data = new_data; 
  940     msg->%(name)s_num_allocated = tobe_allocated; 
  942   msg->%(name)s_data[msg->%(name)s_length - 1] = %(refname)s_new(); 
  943   if (msg->%(name)s_data[msg->%(name)s_length - 1] == NULL) 
  945   msg->%(name)s_set = 1; 
  946   return (msg->%(name)s_data[msg->%(name)s_length - 1]); 
  948   --msg->%(name)s_length; 
  953         return code.split(
'\n')
 
  955     def CodeComplete(self, structname):
 
  960             code.append( 
'if (%(structname)s->%(name)s_set)'  % translate)
 
  962         translate[
"structname"] = structname
 
  965   for (i = 0; i < %(structname)s->%(name)s_length; ++i) { 
  966     if (%(refname)s_complete(%(structname)s->%(name)s_data[i]) == -1) 
  970         code.extend(tmp.split(
'\n'))
 
  974     def CodeUnmarshal(self, buf, tag_name, var_name):
 
  976         translate[
"var_name"] = var_name
 
  977         translate[
"buf"] = buf
 
  978         translate[
"tag_name"] = tag_name
 
  979         code = 
"""if (%(parent_name)s_%(name)s_add(%(var_name)s) == NULL) 
  981 if (evtag_unmarshal_%(refname)s(%(buf)s, %(tag_name)s, 
  982   %(var_name)s->%(name)s_data[%(var_name)s->%(name)s_length - 1]) == -1) { 
  983   --%(var_name)s->%(name)s_length; 
  984   event_warnx("%%s: failed to unmarshal %(name)s", __func__); 
  988         return code.split(
'\n')
 
  990     def CodeMarshal(self, buf, tag_name, var_name):
 
  993                 '  for (i = 0; i < %s->%s_length; ++i) {' % (
 
  994             var_name, self.
_name),
 
  995                 '    evtag_marshal_%s(%s, %s, %s->%s_data[i]);' % (
 
 1002     def CodeClear(self, structname):
 
 1003         code = [ 
'if (%s->%s_set == 1) {' % (structname, self.
Name()),
 
 1005                  '  for (i = 0; i < %s->%s_length; ++i) {' % (
 
 1006             structname, self.
Name()),
 
 1007                  '    %s_free(%s->%s_data[i]);' % (
 
 1010                  '  free(%s->%s_data);' % (structname, self.
Name()),
 
 1011                  '  %s->%s_data = NULL;' % (structname, self.
Name()),
 
 1012                  '  %s->%s_set = 0;' % (structname, self.
Name()),
 
 1013                  '  %s->%s_length = 0;' % (structname, self.
Name()),
 
 1014                  '  %s->%s_num_allocated = 0;' % (structname, self.
Name()),
 
 1020     def CodeNew(self, name):
 
 1021         code  = [
'%s->%s_data = NULL;' % (name, self.
_name),
 
 1022                  '%s->%s_length = 0;' % (name, self.
_name),
 
 1023                  '%s->%s_num_allocated = 0;' % (name, self.
_name)]
 
 1026     def CodeFree(self, name):
 
 1027         code  = [
'if (%s->%s_data != NULL) {' % (name, self.
_name),
 
 1029                  '  for (i = 0; i < %s->%s_length; ++i) {' % (
 
 1031                  '    %s_free(%s->%s_data[i]); ' % (
 
 1033                  '    %s->%s_data[i] = NULL;' % (name, self.
_name),
 
 1035                  '  free(%s->%s_data);' % (name, self.
_name),
 
 1036                  '  %s->%s_data = NULL;' % (name, self.
_name),
 
 1037                  '  %s->%s_length = 0;' % (name, self.
_name),
 
 1038                  '  %s->%s_num_allocated = 0;' % (name, self.
_name),
 
 1044     def Declaration(self):
 
 1045         dcl  = [
'struct %s **%s_data;' % (self.
_refname, self.
_name),
 
 1046                 'int %s_length;' % self.
_name,
 
 1047                 'int %s_num_allocated;' % self.
_name ]
 
 1051 def NormalizeLine(line):
 
 1055     line = cppcomment.sub(
'', line)
 
 1057     line = white.sub(
' ', line)
 
 1061 def ProcessOneEntry(newstruct, entry):
 
 1071     tokens = entry.split(
' ')
 
 1077             if not optional 
and token == 
'optional':
 
 1081             if not array 
and token == 
'array':
 
 1090             res = re.match(
r'^([^\[\]]+)(\[.*\])?$', token)
 
 1092                 print >>sys.stderr, 
'Cannot parse name: \"%s\" around %d' % (
 
 1096             fixed_length = res.group(2)
 
 1098                 fixed_length = fixed_length[1:-1]
 
 1103             if separator != 
'=':
 
 1104                 print >>sys.stderr, 
'Expected "=" after name \"%s\" got %s' % (
 
 1111             if not re.match(
r'^(0x)?[0-9]+$', token):
 
 1112                 print >>sys.stderr, 
'Expected tag number: \"%s\"' % entry
 
 1117         print >>sys.stderr, 
'Cannot parse \"%s\"' % entry
 
 1121         print >>sys.stderr, 
'Need tag number: \"%s\"' % entry
 
 1125     if entry_type == 
'bytes':
 
 1127             newentry = 
EntryBytes(entry_type, name, tag, fixed_length)
 
 1130     elif entry_type == 
'int' and not fixed_length:
 
 1131         newentry = 
EntryInt(entry_type, name, tag)
 
 1132     elif entry_type == 
'string' and not fixed_length:
 
 1135         res = re.match(
r'^struct\[(%s)\]$' % _STRUCT_RE,
 
 1136                        entry_type, re.IGNORECASE)
 
 1139             newentry = 
EntryStruct(entry_type, name, tag, res.group(1))
 
 1141             print >>sys.stderr, 
'Bad type: "%s" in "%s"' % (entry_type, entry)
 
 1147         newentry.MakeOptional()
 
 1149         newentry.MakeArray()
 
 1151     newentry.SetStruct(newstruct)
 
 1152     newentry.SetLineCount(line_count)
 
 1157         newname = newentry.Name()+ 
'_array' 
 1161         newentry.SetStruct(newstruct)
 
 1162         newentry.SetLineCount(line_count)
 
 1163         newentry.MakeArray()
 
 1165     newstruct.AddEntry(newentry)
 
 1169 def ProcessStruct(data):
 
 1170     tokens = data.split(
' ')
 
 1173     newstruct = 
Struct(tokens[1])
 
 1175     inside = 
' '.join(tokens[3:-1])
 
 1177     tokens = inside.split(
';')
 
 1181     for entry 
in tokens:
 
 1182         entry = NormalizeLine(entry)
 
 1187         structs.extend(ProcessOneEntry(newstruct, entry))
 
 1189     structs.append(newstruct)
 
 1192 def GetNextStruct(file):
 
 1198     processed_lines = []
 
 1203         line = file.readline()
 
 1210         if not have_c_comment 
and re.search(
r'/\*', line):
 
 1211             if re.search(
r'/\*.*\*/', line):
 
 1212                 line = re.sub(
r'/\*.*\*/', 
'', line)
 
 1214                 line = re.sub(
r'/\*.*$', 
'', line)
 
 1218             if not re.search(
r'\*/', line):
 
 1221             line = re.sub(
r'^.*\*/', 
'', line)
 
 1223         line = NormalizeLine(line)
 
 1229             if re.match(
r'#include ["<].*[>"]', line):
 
 1230                 cppdirect.append(line)
 
 1233             if re.match(
r'^#(if( |def)|endif)', line):
 
 1234                 cppdirect.append(line)
 
 1237             if re.match(
r'^#define', line):
 
 1238                 headerdirect.append(line)
 
 1241             if not re.match(
r'^struct %s {$' % _STRUCT_RE,
 
 1242                             line, re.IGNORECASE):
 
 1243                 print >>sys.stderr, 
'Missing struct on line %d: %s' % (
 
 1252         tokens = line.split(
'}')
 
 1253         if len(tokens) == 1:
 
 1258             print >>sys.stderr, 
'Trailing garbage after struct on line %d' % (
 
 1263         data += 
' %s}' % tokens[0]
 
 1267     data = re.sub(
r'/\*.*\*/', 
'', data)
 
 1274     Parses the input file and returns C code and corresponding header file. 
 1281         data = GetNextStruct(file)
 
 1286         entities.extend(ProcessStruct(data))
 
 1290 def GuardName(name):
 
 1291     name = 
'_'.join(name.split(
'.'))
 
 1292     name = 
'_'.join(name.split(
'/'))
 
 1293     guard = 
'_'+name.upper()+
'_' 
 1297 def HeaderPreamble(name):
 
 1298     guard = GuardName(name)
 
 1301         ' * Automatically generated from %s\n' 
 1304         '#define %s\n\n' ) % (
 
 1309         '#include <event-config.h>\n' 
 1310         '#ifdef _EVENT_HAVE_STDINT_H\n' 
 1311         '#include <stdint.h>\n' 
 1314     for statement 
in headerdirect:
 
 1315         pre += 
'%s\n' % statement
 
 1320         '#define EVTAG_HAS(msg, member) ((msg)->member##_set == 1)\n' 
 1322         '#define EVTAG_ASSIGN(msg, member, args...) ' 
 1323         '(*(msg)->base->member##_assign)(msg, ## args)\n' 
 1324         '#define EVTAG_GET(msg, member, args...) ' 
 1325         '(*(msg)->base->member##_get)(msg, ## args)\n' 
 1327         '#define EVTAG_ASSIGN(msg, member, ...) ' 
 1328         '(*(msg)->base->member##_assign)(msg, ## __VA_ARGS__)\n' 
 1329         '#define EVTAG_GET(msg, member, ...) ' 
 1330         '(*(msg)->base->member##_get)(msg, ## __VA_ARGS__)\n' 
 1332         '#define EVTAG_ADD(msg, member) (*(msg)->base->member##_add)(msg)\n' 
 1333         '#define EVTAG_LEN(msg, member) ((msg)->member##_length)\n' 
 1339 def HeaderPostamble(name):
 
 1340     guard = GuardName(name)
 
 1341     return '#endif  /* %s */' % guard
 
 1343 def BodyPreamble(name):
 
 1347     header_file = 
'.'.join(name.split(
'.')[:-1]) + 
'.gen.h' 
 1350             ' * Automatically generated from %s\n' 
 1351             ' * by %s/%s.  DO NOT EDIT THIS FILE.\n' 
 1352             ' */\n\n' ) % (name, _NAME, _VERSION)
 
 1353     pre += ( 
'#include <sys/types.h>\n' 
 1354              '#include <sys/time.h>\n' 
 1355              '#include <stdlib.h>\n' 
 1356              '#include <string.h>\n' 
 1357              '#include <assert.h>\n' 
 1358              '#include <event.h>\n\n' )
 
 1360     for statement 
in cppdirect:
 
 1361         pre += 
'%s\n' % statement
 
 1363     pre += 
'\n#include "%s"\n\n' % header_file
 
 1365     pre += 
'void event_err(int eval, const char *fmt, ...);\n' 
 1366     pre += 
'void event_warn(const char *fmt, ...);\n' 
 1367     pre += 
'void event_errx(int eval, const char *fmt, ...);\n' 
 1368     pre += 
'void event_warnx(const char *fmt, ...);\n\n' 
 1373     if len(argv) < 2 
or not argv[1]:
 
 1374         print >>sys.stderr, 
'Need RPC description file as first argument.' 
 1379     ext = filename.split(
'.')[-1]
 
 1381         print >>sys.stderr, 
'Unrecognized file extension: %s' % ext
 
 1384     print >>sys.stderr, 
'Reading \"%s\"' % filename
 
 1386     fp = open(filename, 
'r') 
 1387     entities = Parse(fp) 
 1390     header_file = '.'.join(filename.split(
'.')[:-1]) + 
'.gen.h' 
 1391     impl_file = 
'.'.join(filename.split(
'.')[:-1]) + 
'.gen.c' 
 1393     print >>sys.stderr, 
'... creating "%s"' % header_file
 
 1394     header_fp = open(header_file, 
'w')
 
 1395     print >>header_fp, HeaderPreamble(filename)
 
 1399     for entry 
in entities:
 
 1400         entry.PrintForwardDeclaration(header_fp)
 
 1401     print >>header_fp, 
'' 
 1403     for entry 
in entities:
 
 1404         entry.PrintTags(header_fp)
 
 1405         entry.PrintDeclaration(header_fp)
 
 1406     print >>header_fp, HeaderPostamble(filename)
 
 1409     print >>sys.stderr, 
'... creating "%s"' % impl_file
 
 1410     impl_fp = open(impl_file, 
'w')
 
 1411     print >>impl_fp, BodyPreamble(filename)
 
 1412     for entry 
in entities:
 
 1413         entry.PrintCode(impl_fp)
 
 1416 if __name__ == 
'__main__':