From 3c1a6a68d2b9938a387c694928ab97b948eb09de Mon Sep 17 00:00:00 2001 From: Niels Provos Date: Sun, 23 Sep 2007 03:49:28 +0000 Subject: first attempts at refactoring this code to make it more readable; mostly changing to dictionaries for format strings svn:r450 --- event_rpcgen.py | 502 +++++++++++++++++++++++++++----------------------------- 1 file changed, 243 insertions(+), 259 deletions(-) (limited to 'event_rpcgen.py') diff --git a/event_rpcgen.py b/event_rpcgen.py index ef780be1..4e767d65 100755 --- a/event_rpcgen.py +++ b/event_rpcgen.py @@ -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 = ['{', -- cgit v1.2.1