]> granicus.if.org Git - libevent/commitdiff
first attempts at refactoring this code to make it more readable;
authorNiels Provos <provos@gmail.com>
Sun, 23 Sep 2007 03:49:28 +0000 (03:49 +0000)
committerNiels Provos <provos@gmail.com>
Sun, 23 Sep 2007 03:49:28 +0000 (03:49 +0000)
mostly changing to dictionaries for format strings

svn:r450

event_rpcgen.py

index ef780be1777fbb03f1b8be141d9167c793e6ba26..4e767d65618e65ce7db6aed51cf47a1b6f1c8a5b 100755 (executable)
@@ -85,20 +85,18 @@ class Struct:
             print >>file, '  uint8_t %s_set;' % entry.Name()
         print >>file, '};\n'
 
-        print >>file, (
-            'struct %s *%s_new(void);\n' % (self._name, self._name) +
-            'void %s_free(struct %s *);\n' % (self._name, self._name) +
-            'void %s_clear(struct %s *);\n' % (self._name, self._name) +
-            'void %s_marshal(struct evbuffer *, const struct %s *);\n' % (
-            self._name, self._name) +
-            'int %s_unmarshal(struct %s *, struct evbuffer *);\n' % (
-            self._name, self._name) +
-            'int %s_complete(struct %s *);' % (self._name, self._name)
-            )
-        print >>file, ('void evtag_marshal_%s(struct evbuffer *, uint8_t, '
-                       'const struct %s *);') % ( self._name, self._name)
-        print >>file, ('int evtag_unmarshal_%s(struct evbuffer *, uint8_t, '
-                       'struct %s *);') % ( self._name, self._name)
+        print >>file, \
+"""struct %(name)s *%(name)s_new(void);
+void %(name)s_free(struct %(name)s *);
+void %(name)s_clear(struct %(name)s *);
+void %(name)s_marshal(struct evbuffer *, const struct %(name)s *);
+int %(name)s_unmarshal(struct %(name)s *, struct evbuffer *);
+int %(name)s_complete(struct %(name)s *);
+void evtag_marshal_%(name)s(struct evbuffer *, uint8_t, 
+    const struct %(name)s *);
+int evtag_unmarshal_%(name)s(struct evbuffer *, uint8_t,
+    struct %(name)s *);""" % { 'name' : self._name }
+
 
         # Write a setting function of every variable
         for entry in self._entries:
@@ -118,21 +116,23 @@ class Struct:
                        ' */\n') % self._name
 
         # Creation
-        print >>file, ( 'struct %s *\n' % self._name +
-                        '%s_new(void)\n' % self._name +
-                        '{\n'
-                        '  struct %s *tmp;\n' % self._name +
-                        '  if ((tmp = malloc(sizeof(struct %s))) == NULL) {\n'
-                        '    event_warn("%%s: malloc", __func__);\n'
-                        '    return (NULL);\n' % self._name +
-                        '  }'
-                        )
+        print >>file, (
+            'struct %(name)s *\n'
+            '%(name)s_new(void)\n'
+            '{\n'
+            '  struct %(name)s *tmp;\n'
+            '  if ((tmp = malloc(sizeof(struct %(name)s))) == NULL) {\n'
+            '    event_warn("%%s: malloc", __func__);\n'
+            '    return (NULL);\n'
+            '  }') % { 'name' : self._name }
+
         for entry in self._entries:
             self.PrintIdented(file, '  ', entry.CodeNew('tmp'))
             print >>file, '  tmp->%s_set = 0;\n' % entry.Name()
 
-        print >>file, ('  return (tmp);\n'
-                       '}\n')
+        print >>file, (
+            '  return (tmp);\n'
+            '}\n')
 
         # Adding
         for entry in self._entries:
@@ -152,10 +152,9 @@ class Struct:
             
         # Clearing
         print >>file, ( 'void\n'
-                        '%s_clear(struct %s *tmp)\n' % (
-            self._name, self._name)+
+                        '%(name)s_clear(struct %(name)s *tmp)\n'
                         '{'
-                        )
+                        ) % { 'name' : self._name }
         for entry in self._entries:
             self.PrintIdented(file, '  ', entry.CodeClear('tmp'))
 
@@ -163,10 +162,10 @@ class Struct:
 
         # Freeing
         print >>file, ( 'void\n'
-                        '%s_free(struct %s *tmp)\n' % (
-            self._name, self._name)+
+                        '%(name)s_free(struct %(name)s *tmp)\n'
                         '{'
-                        )
+                        ) % { 'name' : self._name }
+        
         for entry in self._entries:
             self.PrintIdented(file, '  ', entry.CodeFree('tmp'))
 
@@ -175,9 +174,9 @@ class Struct:
 
         # Marshaling
         print >>file, ('void\n'
-                       '%s_marshal(struct evbuffer *evbuf, '
-                       'const struct %s *tmp)' % (self._name, self._name) +
-                       '{')
+                       '%(name)s_marshal(struct evbuffer *evbuf, '
+                       'const struct %(name)s *tmp)'
+                       '{') % { 'name' : self._name }
         for entry in self._entries:
             indent = '  '
             # Optional entries do not have to be set
@@ -194,16 +193,15 @@ class Struct:
                        
         # Unmarshaling
         print >>file, ('int\n'
-                       '%s_unmarshal(struct %s *tmp, '
-                       ' struct evbuffer *evbuf)\n' % (
-            self._name, self._name) +
+                       '%(name)s_unmarshal(struct %(name)s *tmp, '
+                       ' struct evbuffer *evbuf)\n'
                        '{\n'
                        '  uint8_t tag;\n'
                        '  while (EVBUFFER_LENGTH(evbuf) > 0) {\n'
                        '    if (evtag_peek(evbuf, &tag) == -1)\n'
                        '      return (-1);\n'
                        '    switch (tag) {\n'
-                       )
+                       ) % { 'name' : self._name }
         for entry in self._entries:
             print >>file, '      case %s:\n' % self.EntryTagName(entry)
             if not entry.Array():
@@ -224,8 +222,9 @@ class Struct:
                         '    }\n'
                         '  }\n' )
         # Check if it was decoded completely
-        print >>file, ( '  if (%s_complete(tmp) == -1)\n' % self._name +
-                        '    return (-1);')
+        print >>file, ( '  if (%(name)s_complete(tmp) == -1)\n'
+                        '    return (-1);'
+                        ) % { 'name' : self._name }
 
         # Successfully decoded
         print >>file, ( '  return (0);\n'
@@ -234,8 +233,8 @@ class Struct:
         # Checking if a structure has all the required data
         print >>file, (
             'int\n'
-            '%s_complete(struct %s *msg)\n' % (self._name, self._name) +
-            '{' )
+            '%(name)s_complete(struct %(name)s *msg)\n'
+            '{' ) % { 'name' : self._name }
         for entry in self._entries:
             self.PrintIdented(
                 file, '  ',
@@ -247,10 +246,8 @@ class Struct:
         # Complete message unmarshaling
         print >>file, (
             'int\n'
-            'evtag_unmarshal_%s(struct evbuffer *evbuf, uint8_t need_tag, '
-            ' struct %s *msg)'
-            ) % (self._name, self._name)
-        print >>file, (
+            'evtag_unmarshal_%(name)s(struct evbuffer *evbuf, '
+            'uint8_t need_tag, struct %(name)s *msg)\n'
             '{\n'
             '  uint8_t tag;\n'
             '  int res = -1;\n'
@@ -261,7 +258,7 @@ class Struct:
             ' || tag != need_tag)\n'
             '    goto error;\n'
             '\n'
-            '  if (%s_unmarshal(msg, tmp) == -1)\n'
+            '  if (%(name)s_unmarshal(msg, tmp) == -1)\n'
             '    goto error;\n'
             '\n'
             '  res = 0;\n'
@@ -269,22 +266,22 @@ class Struct:
             ' error:\n'
             '  evbuffer_free(tmp);\n'
             '  return (res);\n'
-            '}\n' ) % self._name
+            '}\n' ) % { 'name' : self._name }
 
         # Complete message marshaling
         print >>file, (
             'void\n'
-            'evtag_marshal_%s(struct evbuffer *evbuf, uint8_t tag, '
-            'const struct %s *msg)\n' % (self._name, self._name) +
+            'evtag_marshal_%(name)s(struct evbuffer *evbuf, uint8_t tag, '
+            'const struct %(name)s *msg)\n'
             '{\n'
             '  struct evbuffer *_buf = evbuffer_new();\n'
             '  assert(_buf != NULL);\n'
             '  evbuffer_drain(_buf, -1);\n'
-            '  %s_marshal(_buf, msg);\n' % self._name +
+            '  %(name)s_marshal(_buf, msg);\n'
             '  evtag_marshal(evbuf, tag, EVBUFFER_DATA(_buf), '
             'EVBUFFER_LENGTH(_buf));\n'
             '  evbuffer_free(_buf);\n'
-            '}\n' )
+            '}\n' ) % { 'name' : self._name }
 
 class Entry:
     def __init__(self, type, name, tag):
@@ -297,7 +294,15 @@ class Entry:
         self._array = 0
         self._line_count = -1
         self._struct = None
-
+        self._refname = None
+
+    def GetTranslation(self):
+        return { "parent_name" : self._struct.Name(),
+                 "name" : self._name,
+                 "ctype" : self._ctype,
+                 "refname" : self._refname
+                 }
+    
     def SetStruct(self, struct):
         self._struct = struct
 
@@ -338,17 +343,19 @@ class Entry:
         return code
 
     def CodeGet(self):
-        code = [ 'int',
-                 '%s_%s_get(struct %s *msg, %s *value)' % (
-            self._struct.Name(), self._name,
-            self._struct.Name(), self._ctype),
-                 '{',
-                 '  if (msg->%s_set != 1)' % self._name,
-                 '    return (-1);',
-                 '  *value = msg->%s_data;' % self._name,
-                 '  return (0);',
-                 '}' ]
-        return code
+        code = (
+            'int',
+            '%(parent_name)s_%(name)s_get(struct %(parent_name)s *msg, '
+            '%(ctype)s *value)',
+            '{',
+            '  if (msg->%(name)s_set != 1)',
+            '    return (-1);',
+            '  *value = msg->%(name)s_data;',
+            '  return (0);',
+            '}' )
+        code = '\n'.join(code)
+        code = code % self.GetTranslation()
+        return code.split('\n')
         
     def AssignFuncName(self):
         return '%s_%s_assign' % (self._struct.Name(), self._name)
@@ -363,15 +370,16 @@ class Entry:
 
     def CodeAssign(self):
         code = [ 'int',
-                 '%s_%s_assign(struct %s *msg, const %s value)' % (
-            self._struct.Name(), self._name,
-            self._struct.Name(), self._ctype),
+                 '%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg,'
+                 ' const %(ctype)s value)',
                  '{',
-                 '  msg->%s_set = 1;' % self._name,
-                 '  msg->%s_data = value;' % self._name,
+                 '  msg->%(name)s_set = 1;',
+                 '  msg->%(name)s_data = value;',
                  '  return (0);',
                  '}' ]
-        return code
+        code = '\n'.join(code)
+        code = code % self.GetTranslation()
+        return code.split('\n')
 
     def CodeClear(self, structname):
         code = [ '%s->%s_set = 0;' % (structname, self.Name()) ]
@@ -391,16 +399,19 @@ class Entry:
         return []
 
     def CodeNew(self, name):
-        code = [ '%s->%s_assign = %s_%s_assign;' % (
-            name, self._name, self._struct.Name(), self._name ),
-                 '%s->%s_get = %s_%s_get;' % (
-            name, self._name, self._struct.Name(), self._name ),
-        ]
+        code = [
+            '%(vname)s->%(name)s_assign = %(parent_name)s_%(name)s_assign;',
+            '%(vname)s->%(name)s_get = %(parent_name)s_%(name)s_get;'
+            ]
         if self.Array():
             code.append(
-                '%s->%s_add = %s_%s_add;' % (
-                name, self._name, self._struct.Name(), self._name ) )
-        return code
+                '%(vname)s->%(name)s_add = %(parent_name)s_%(name)s_add;')
+
+        code = '\n'.join(code)
+        trans = self.GetTranslation()
+        trans['vname'] = name
+        code = code % trans
+        return code.split('\n')
 
     def Verify(self):
         if self.Array() and not self._can_be_array:
@@ -543,19 +554,19 @@ class EntryString(Entry):
 
     def CodeAssign(self):
         name = self._name
-        code = [ 'int',
-                 '%s_%s_assign(struct %s *msg, const %s value)' % (
-            self._struct.Name(), name,
-            self._struct.Name(), self._ctype),
-                 '{',
-                 '  if (msg->%s_data != NULL)' % name,
-                 '    free(msg->%s_data);' % name,
-                 '  if ((msg->%s_data = strdup(value)) == NULL)' % name,
-                 '    return (-1);',
-                 '  msg->%s_set = 1;' % name,
-                 '  return (0);',
-                 '}' ]
-        return code
+        code = """int
+%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg,
+    const %(ctype)s value)
+{
+  if (msg->%(name)s_data != NULL)
+    free(msg->%(name)s_data);
+  if ((msg->%(name)s_data = strdup(value)) == NULL)
+    return (-1);
+  msg->%(name)s_set = 1;
+  return (0);
+}""" % self.GetTranslation()
+
+        return code.split('\n')
         
     def CodeUnmarshal(self, buf, tag_name, var_name):
         code = ['if (evtag_unmarshal_string(%s, %s, &%s->%s_data) == -1) {' % (
@@ -605,22 +616,12 @@ class EntryStruct(Entry):
 
         self._can_be_array = 1
         self._refname = refname
-        self._ctype = 'struct %s' % refname
+        self._ctype = 'struct %s*' % refname
 
-    def GetDeclaration(self, funcname):
-        code = [ 'int %s(struct %s *, %s **);' % (
-            funcname, self._struct.Name(), self._ctype ) ]
-        return code
-        
-    def AssignDeclaration(self, funcname):
-        code = [ 'int %s(struct %s *, const %s *);' % (
-            funcname, self._struct.Name(), self._ctype ) ]
-        return code
-        
     def CodeGet(self):
         name = self._name
         code = [ 'int',
-                 '%s_%s_get(struct %s *msg, %s **value)' % (
+                 '%s_%s_get(struct %s *msg, %s *value)' % (
             self._struct.Name(), name,
             self._struct.Name(), self._ctype),
                  '{',
@@ -637,47 +638,43 @@ class EntryStruct(Entry):
         
     def CodeAssign(self):
         name = self._name
-        code = [ 'int',
-                 '%s_%s_assign(struct %s *msg, const %s *value)' % (
-            self._struct.Name(), name,
-            self._struct.Name(), self._ctype),
-                 '{',
-                 '  struct evbuffer *tmp = NULL;',
-                 '  if (msg->%s_set) {' % name,
-                 '    %s_clear(msg->%s_data);' % (self._refname, name),
-                 '    msg->%s_set = 0;' % name,
-                 '  } else {',
-                 '    msg->%s_data = %s_new();' % (name, self._refname),
-                 '    if (msg->%s_data == NULL) {' % name,
-                 '      event_warn("%%s: %s_new()", __func__);' % (
-            self._refname),
-                 '      goto error;',
-                 '    }',
-                 '  }',
-                 '  if ((tmp = evbuffer_new()) == NULL) {',
-                 '    event_warn("%s: evbuffer_new()", __func__);',
-                 '    goto error;',
-                 '  }',
-                 '  %s_marshal(tmp, value); ' % self._refname,
-                 '  if (%s_unmarshal(msg->%s_data, tmp) == -1) {' % (
-            self._refname, name ),
-                 '    event_warnx("%%s: %s_unmarshal", __func__);' % (
-            self._refname),
-                 '    goto error;',
-                 '  }',
-                 '  msg->%s_set = 1;' % name,
-                 '  evbuffer_free(tmp);',
-                 '  return (0);',
-                 ' error:',
-                 '  if (tmp != NULL)',
-                 '    evbuffer_free(tmp);',
-                 '  if (msg->%s_data != NULL) {' % name,
-                 '    %s_free(msg->%s_data);' % (self._refname, name),
-                 '    msg->%s_data = NULL;' % name,
-                 '  }',
-                 '  return (-1);',
-                 '}' ]
-        return code
+        code = """int
+%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg,
+    const %(ctype)s value)
+{
+   struct evbuffer *tmp = NULL;
+   if (msg->%(name)s_set) {
+     %(refname)s_clear(msg->%(name)s_data);
+     msg->%(name)s_set = 0;
+   } else {
+     msg->%(name)s_data = %(refname)s_new();
+     if (msg->%(name)s_data == NULL) {
+       event_warn("%%s: %(refname)s_new()", __func__);
+       goto error;
+     }
+   }
+   if ((tmp = evbuffer_new()) == NULL) {
+     event_warn("%%s: evbuffer_new()", __func__);
+     goto error;
+   }
+   %(refname)s_marshal(tmp, value);
+   if (%(refname)s_unmarshal(msg->%(name)s_data, tmp) == -1) {
+     event_warnx("%%s: %(refname)s_unmarshal", __func__);
+     goto error;
+   }
+   msg->%(name)s_set = 1;
+   evbuffer_free(tmp);
+   return (0);
+ error:
+   if (tmp != NULL)
+     evbuffer_free(tmp);
+   if (msg->%(name)s_data != NULL) {
+     %(refname)s_free(msg->%(name)s_data);
+     msg->%(name)s_data = NULL;
+   }
+   return (-1);
+}""" % self.GetTranslation()
+        return code.split('\n')
         
     def CodeComplete(self, structname):
         if self.Optional():
@@ -735,7 +732,7 @@ class EntryStruct(Entry):
         return code
 
     def Declaration(self):
-        dcl  = ['struct %s *%s_data;' % (self._refname, self._name)]
+        dcl  = ['%s %s_data;' % (self._ctype, self._name)]
 
         return dcl
 
@@ -853,145 +850,132 @@ class EntryArray(Entry):
 
         self._entry = entry
         self._refname = entry._refname
-        self._ctype = 'struct %s' % self._refname
+        self._ctype = 'struct %s *' % self._refname
 
     def GetDeclaration(self, funcname):
         """Allows direct access to elements of the array."""
-        code = [ 'int %s(struct %s *, int, %s **);' % (
-            funcname, self._struct.Name(), self._ctype ) ]
+        translate = self.GetTranslation()
+        translate["funcname"] = funcname
+        code = [
+            'int %(funcname)s(struct %(parent_name)s *, int, %(ctype)s *);' %
+            translate ]
         return code
         
     def AssignDeclaration(self, funcname):
-        code = [ 'int %s(struct %s *, int, const %s *);' % (
+        code = [ 'int %s(struct %s *, int, const %s);' % (
             funcname, self._struct.Name(), self._ctype ) ]
         return code
         
     def AddDeclaration(self, funcname):
-        code = [ '%s *%s(struct %s *);' % (
+        code = [ '%s %s(struct %s *);' % (
             self._ctype, funcname, self._struct.Name() ) ]
         return code
         
     def CodeGet(self):
-        name = self._name
-        code = [ 'int',
-                 '%s_%s_get(struct %s *msg, int offset, %s **value)' % (
-            self._struct.Name(), name,
-            self._struct.Name(), self._ctype),
-                 '{',
-                 '  if (msg->%s_set != 1)' % name,
-                 '    return (-1);',
-                 '  if (offset >= msg->%s_length)' % name,
-                 '    return (-1);',
-                 '  *value = msg->%s_data[offset];' % name,
-                 '  return (0);',
-                 '}' ]
-        return code
+        code = """int
+%(parent_name)s_%(name)s_get(struct %(parent_name)s *msg, int offset,
+    %(ctype)s *value)
+{
+  if (!msg->%(name)s_set || offset < 0 || offset >= msg->%(name)s_length)
+    return (-1);
+  *value = msg->%(name)s_data[offset];
+  return (0);
+}""" % self.GetTranslation()
+
+        return code.split('\n')
         
     def CodeAssign(self):
-        name = self._name
-        code = [ 'int',
-                 '%s_%s_assign(struct %s *msg, int off, const %s *value)' % (
-            self._struct.Name(), name,
-            self._struct.Name(), self._ctype),
-                 '{',
-                 '  struct evbuffer *tmp = NULL;',
-                 '  if (msg->%s_set != 1)' % name,
-                 '    return (-1);',
-                 '  if (off >= msg->%s_length)' % name,
-                 '    return (-1);',
-                 '',
-                 '  %s_clear(msg->%s_data[off]);' % (self._refname, name),
-                 '  if ((tmp = evbuffer_new()) == NULL) {',
-                 '    event_warn("%s: evbuffer_new()", __func__);',
-                 '    goto error;',
-                 '  }',
-                 '  %s_marshal(tmp, value); ' % self._refname,
-                 '  if (%s_unmarshal(msg->%s_data[off], tmp) == -1) {' % (
-            self._refname, name ),
-                 '    event_warnx("%%s: %s_unmarshal", __func__);' % (
-            self._refname),
-                 '    goto error;',
-                 '  }',
-                 '  evbuffer_free(tmp);',
-                 '  return (0);',
-                 ' error:',
-                 '  if (tmp != NULL)',
-                 '    evbuffer_free(tmp);',
-                 '  %s_clear(msg->%s_data[off]);' % (self._refname, name),
-                 '  return (-1);',
-                 '}' ]
-        return code
+        code = """int
+%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg, int off,
+    const %(ctype)s value)
+{
+  struct evbuffer *tmp = NULL;
+  if (!msg->%(name)s_set || off < 0 || off >= msg->%(name)s_length)
+    return (-1);
+  %(refname)s_clear(msg->%(name)s_data[off]);
+  if ((tmp = evbuffer_new()) == NULL) {
+    event_warn("%%s: evbuffer_new()", __func__);
+    goto error;
+  }
+  %(refname)s_marshal(tmp, value);
+  if (%(refname)s_unmarshal(msg->%(name)s_data[off], tmp) == -1) {
+    event_warnx("%%s: %(refname)s_unmarshal", __func__);
+    goto error;
+  }
+  evbuffer_free(tmp);
+  return (0);
+error:
+  if (tmp != NULL)
+    evbuffer_free(tmp);
+  %(refname)s_clear(msg->%(name)s_data[off]);
+  return (-1);
+}""" % self.GetTranslation()
+
+        return code.split('\n')
         
     def CodeAdd(self):
-        name = self._name
-        code = [
-            '%s *' % self._ctype, 
-            '%s_%s_add(struct %s *msg)' % (
-            self._struct.Name(), name, self._struct.Name()),
-            '{',
-            '  msg->%s_length++;' % name,
-            '  if (msg->%s_length >= msg->%s_num_allocated) { ' % (name, name),
-            '    struct %s** new_data = NULL; ' % self._refname,
-            '    int tobe_allocated = msg->%s_num_allocated; ' % name,
-            '    if (!tobe_allocated) ',
-            '      tobe_allocated = 1; ',
-            '    else ',
-            '      tobe_allocated <<= 1; ',
-            '    new_data = (struct %s**)realloc(msg->%s_data, '
-            'tobe_allocated * sizeof(struct %s*));' % (
-            self._refname, name, self._refname ),
-            '    if (new_data == NULL) {',
-            '      --msg->%s_length;' % name,
-            '      return (NULL);',
-            '    }',
-            '    msg->%s_data = new_data;' % name,
-            '    msg->%s_num_allocated = tobe_allocated;' % name,
-            '  }',
-            '  msg->%s_data[msg->%s_length - 1] = %s_new();' % (
-            name, name, self._refname),
-            '  if (msg->%s_data[msg->%s_length - 1] == NULL) {' % (name, name),
-            '    --msg->%s_length; ' % name,
-            '    return (NULL);',
-            '  }',
-            '  msg->%s_set = 1;' % name,
-            '  return (msg->%s_data[msg->%s_length - 1]);' % (name, name),
-            '}'
-            ]
-        return code
-        
+        code = \
+"""%(ctype)s
+%(parent_name)s_%(name)s_add(struct %(parent_name)s *msg)
+{
+  if (++msg->%(name)s_length >= msg->%(name)s_num_allocated) {
+    int tobe_allocated = msg->%(name)s_num_allocated;
+    %(ctype)s* new_data = NULL;
+    tobe_allocated = !tobe_allocated ? 1 : tobe_allocated << 1;
+    new_data = (%(ctype)s*) realloc(msg->%(name)s_data,
+        tobe_allocated * sizeof(%(ctype)s));
+    if (new_data == NULL)
+      goto error;
+    msg->%(name)s_data = new_data;
+    msg->%(name)s_num_allocated = tobe_allocated;
+  }
+  msg->%(name)s_data[msg->%(name)s_length - 1] = %(refname)s_new();
+  if (msg->%(name)s_data[msg->%(name)s_length - 1] == NULL)
+    goto error;
+  msg->%(name)s_set = 1;
+  return (msg->%(name)s_data[msg->%(name)s_length - 1]);
+error:
+  --msg->%(name)s_length;
+  return (NULL);
+}
+        """ % self.GetTranslation()
+
+        return code.split('\n')
+
     def CodeComplete(self, structname):
         code = []
-        if self.Optional():
-            code.append( 'if (%s->%s_set)'  % (structname, self.Name()))
+        translate = self.GetTranslation()
 
-        code.extend(['{',
-                     '  int i;',
-                     '  for (i = 0; i < %s->%s_length; ++i) {' % (
-                structname, self.Name()),
-                     '    if (%s_complete(%s->%s_data[i]) == -1)' % (
-                self._refname, structname, self.Name()),
-                     '      return (-1);',
-                     '  }',
-                     '}'
-                     ])
+        if self.Optional():
+            code.append( 'if (%(structname)s->%(name)s_set)'  % translate)
+
+        translate["structname"] = structname
+        tmp = """{
+  int i;
+  for (i = 0; i < %(structname)s->%(name)s_length; ++i) {
+    if (%(refname)s_complete(%(structname)s->%(name)s_data[i]) == -1)
+      return (-1);
+  }
+}""" % translate
+        code.extend(tmp.split('\n'))
 
         return code
     
     def CodeUnmarshal(self, buf, tag_name, var_name):
-        code = ['if (%s_%s_add(%s) == NULL)' % (
-            self._struct.Name(), self._name, var_name),
-                '  return (-1);',
-                'if (evtag_unmarshal_%s(%s, %s, '
-                '%s->%s_data[%s->%s_length - 1]) == -1) {' % (
-            self._refname, buf, tag_name, var_name, self._name,
-            var_name, self._name),
-                '  %s->%s_length--; ' % (var_name, self._name),
-                '  event_warnx("%%s: failed to unmarshal %s", __func__);' % (
-            self._name ),
-                '  return (-1);',
-                '}'
-                ]
-        return code
+        translate = self.GetTranslation()
+        translate["var_name"] = var_name
+        translate["buf"] = buf
+        translate["tag_name"] = tag_name
+        code = """if (%(parent_name)s_%(name)s_add(%(var_name)s) == NULL)
+  return (-1);
+if (evtag_unmarshal_%(refname)s(%(buf)s, %(tag_name)s,
+  %(var_name)s->%(name)s_data[%(var_name)s->%(name)s_length - 1]) == -1) {
+  --%(var_name)s->%(name)s_length;
+  event_warnx("%%s: failed to unmarshal %(name)s", __func__);
+  return (-1);
+}""" % translate
+
+        return code.split('\n')
 
     def CodeMarshal(self, buf, tag_name, var_name):
         code = ['{',