mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-10 04:50:37 -04:00
support integer arrays in rpc structures; this involved some refactoring of the event_rpcgen code, so that other types should be able to get arrays fairly easily
svn:r609
This commit is contained in:
parent
a5176a65cc
commit
68725dc8bd
@ -29,6 +29,7 @@ Changes in current version:
|
|||||||
o Correctly handle DNS replies with no answers set (Fixes bug 1846282)
|
o Correctly handle DNS replies with no answers set (Fixes bug 1846282)
|
||||||
o add -Wstrict-aliasing to warnings and more cleanup
|
o add -Wstrict-aliasing to warnings and more cleanup
|
||||||
o removed linger from http server socket; reported by Ilya Martynov
|
o removed linger from http server socket; reported by Ilya Martynov
|
||||||
|
o event_rpcgen now allows creating integer arrays
|
||||||
|
|
||||||
Changes in 1.4.0:
|
Changes in 1.4.0:
|
||||||
o allow \r or \n individually to separate HTTP headers instead of the standard "\r\n"; from Charles Kerr.
|
o allow \r or \n individually to separate HTTP headers instead of the standard "\r\n"; from Charles Kerr.
|
||||||
|
575
event_rpcgen.py
575
event_rpcgen.py
@ -21,6 +21,9 @@ cppcomment = re.compile(r'\/\/.*$')
|
|||||||
headerdirect = []
|
headerdirect = []
|
||||||
cppdirect = []
|
cppdirect = []
|
||||||
|
|
||||||
|
def TranslateList(mylist, mydict):
|
||||||
|
return map(lambda x: x % mydict, mylist)
|
||||||
|
|
||||||
# Holds everything that makes a struct
|
# Holds everything that makes a struct
|
||||||
class Struct:
|
class Struct:
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
@ -49,7 +52,7 @@ class Struct:
|
|||||||
name = "%s_%s" % (self._name, entry.Name())
|
name = "%s_%s" % (self._name, entry.Name())
|
||||||
return name.upper()
|
return name.upper()
|
||||||
|
|
||||||
def PrintIdented(self, file, ident, code):
|
def PrintIndented(self, file, ident, code):
|
||||||
"""Takes an array, add indentation to each entry and prints it."""
|
"""Takes an array, add indentation to each entry and prints it."""
|
||||||
for entry in code:
|
for entry in code:
|
||||||
print >>file, '%s%s' % (ident, entry)
|
print >>file, '%s%s' % (ident, entry)
|
||||||
@ -77,14 +80,14 @@ class Struct:
|
|||||||
if entry.Array():
|
if entry.Array():
|
||||||
dcl.extend(
|
dcl.extend(
|
||||||
entry.AddDeclaration('(*%s_add)' % entry.Name()))
|
entry.AddDeclaration('(*%s_add)' % entry.Name()))
|
||||||
self.PrintIdented(file, ' ', dcl)
|
self.PrintIndented(file, ' ', dcl)
|
||||||
print >>file, '};\n'
|
print >>file, '};\n'
|
||||||
|
|
||||||
print >>file, 'struct %s {' % self._name
|
print >>file, 'struct %s {' % self._name
|
||||||
print >>file, ' struct %s_access_ *base;\n' % self._name
|
print >>file, ' struct %s_access_ *base;\n' % self._name
|
||||||
for entry in self._entries:
|
for entry in self._entries:
|
||||||
dcl = entry.Declaration()
|
dcl = entry.Declaration()
|
||||||
self.PrintIdented(file, ' ', dcl)
|
self.PrintIndented(file, ' ', dcl)
|
||||||
print >>file, ''
|
print >>file, ''
|
||||||
for entry in self._entries:
|
for entry in self._entries:
|
||||||
print >>file, ' uint8_t %s_set;' % entry.Name()
|
print >>file, ' uint8_t %s_set;' % entry.Name()
|
||||||
@ -105,12 +108,12 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, uint32_t,
|
|||||||
|
|
||||||
# Write a setting function of every variable
|
# Write a setting function of every variable
|
||||||
for entry in self._entries:
|
for entry in self._entries:
|
||||||
self.PrintIdented(file, '', entry.AssignDeclaration(
|
self.PrintIndented(file, '', entry.AssignDeclaration(
|
||||||
entry.AssignFuncName()))
|
entry.AssignFuncName()))
|
||||||
self.PrintIdented(file, '', entry.GetDeclaration(
|
self.PrintIndented(file, '', entry.GetDeclaration(
|
||||||
entry.GetFuncName()))
|
entry.GetFuncName()))
|
||||||
if entry.Array():
|
if entry.Array():
|
||||||
self.PrintIdented(file, '', entry.AddDeclaration(
|
self.PrintIndented(file, '', entry.AddDeclaration(
|
||||||
entry.AddFuncName()))
|
entry.AddFuncName()))
|
||||||
|
|
||||||
print >>file, '/* --- %s done --- */\n' % self._name
|
print >>file, '/* --- %s done --- */\n' % self._name
|
||||||
@ -124,7 +127,7 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, uint32_t,
|
|||||||
'static struct %(name)s_access_ __%(name)s_base = {' % \
|
'static struct %(name)s_access_ __%(name)s_base = {' % \
|
||||||
{ 'name' : self._name }
|
{ 'name' : self._name }
|
||||||
for entry in self._entries:
|
for entry in self._entries:
|
||||||
self.PrintIdented(file, ' ', entry.CodeBase())
|
self.PrintIndented(file, ' ', entry.CodeBase())
|
||||||
print >>file, '};\n'
|
print >>file, '};\n'
|
||||||
|
|
||||||
# Creation
|
# Creation
|
||||||
@ -140,7 +143,7 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, uint32_t,
|
|||||||
' tmp->base = &__%(name)s_base;\n') % { 'name' : self._name }
|
' tmp->base = &__%(name)s_base;\n') % { 'name' : self._name }
|
||||||
|
|
||||||
for entry in self._entries:
|
for entry in self._entries:
|
||||||
self.PrintIdented(file, ' ', entry.CodeNew('tmp'))
|
self.PrintIndented(file, ' ', entry.CodeInitialize('tmp'))
|
||||||
print >>file, ' tmp->%s_set = 0;\n' % entry.Name()
|
print >>file, ' tmp->%s_set = 0;\n' % entry.Name()
|
||||||
|
|
||||||
print >>file, (
|
print >>file, (
|
||||||
@ -150,17 +153,17 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, uint32_t,
|
|||||||
# Adding
|
# Adding
|
||||||
for entry in self._entries:
|
for entry in self._entries:
|
||||||
if entry.Array():
|
if entry.Array():
|
||||||
self.PrintIdented(file, '', entry.CodeAdd())
|
self.PrintIndented(file, '', entry.CodeAdd())
|
||||||
print >>file, ''
|
print >>file, ''
|
||||||
|
|
||||||
# Assigning
|
# Assigning
|
||||||
for entry in self._entries:
|
for entry in self._entries:
|
||||||
self.PrintIdented(file, '', entry.CodeAssign())
|
self.PrintIndented(file, '', entry.CodeAssign())
|
||||||
print >>file, ''
|
print >>file, ''
|
||||||
|
|
||||||
# Getting
|
# Getting
|
||||||
for entry in self._entries:
|
for entry in self._entries:
|
||||||
self.PrintIdented(file, '', entry.CodeGet())
|
self.PrintIndented(file, '', entry.CodeGet())
|
||||||
print >>file, ''
|
print >>file, ''
|
||||||
|
|
||||||
# Clearing
|
# Clearing
|
||||||
@ -169,7 +172,7 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, uint32_t,
|
|||||||
'{'
|
'{'
|
||||||
) % { 'name' : self._name }
|
) % { 'name' : self._name }
|
||||||
for entry in self._entries:
|
for entry in self._entries:
|
||||||
self.PrintIdented(file, ' ', entry.CodeClear('tmp'))
|
self.PrintIndented(file, ' ', entry.CodeClear('tmp'))
|
||||||
|
|
||||||
print >>file, '}\n'
|
print >>file, '}\n'
|
||||||
|
|
||||||
@ -180,7 +183,7 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, uint32_t,
|
|||||||
) % { 'name' : self._name }
|
) % { 'name' : self._name }
|
||||||
|
|
||||||
for entry in self._entries:
|
for entry in self._entries:
|
||||||
self.PrintIdented(file, ' ', entry.CodeFree('tmp'))
|
self.PrintIndented(file, ' ', entry.CodeFree('tmp'))
|
||||||
|
|
||||||
print >>file, (' free(tmp);\n'
|
print >>file, (' free(tmp);\n'
|
||||||
'}\n')
|
'}\n')
|
||||||
@ -196,9 +199,11 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, uint32_t,
|
|||||||
if entry.Optional():
|
if entry.Optional():
|
||||||
indent += ' '
|
indent += ' '
|
||||||
print >>file, ' if (tmp->%s_set) {' % entry.Name()
|
print >>file, ' if (tmp->%s_set) {' % entry.Name()
|
||||||
self.PrintIdented(
|
self.PrintIndented(
|
||||||
file, indent,
|
file, indent,
|
||||||
entry.CodeMarshal('evbuf', self.EntryTagName(entry), 'tmp'))
|
entry.CodeMarshal('evbuf', self.EntryTagName(entry),
|
||||||
|
entry.GetVarName('tmp'),
|
||||||
|
entry.GetVarLen('tmp')))
|
||||||
if entry.Optional():
|
if entry.Optional():
|
||||||
print >>file, ' }'
|
print >>file, ' }'
|
||||||
|
|
||||||
@ -223,10 +228,12 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, uint32_t,
|
|||||||
' return (-1);'
|
' return (-1);'
|
||||||
) % (entry.Name())
|
) % (entry.Name())
|
||||||
|
|
||||||
self.PrintIdented(
|
self.PrintIndented(
|
||||||
file, ' ',
|
file, ' ',
|
||||||
entry.CodeUnmarshal('evbuf',
|
entry.CodeUnmarshal('evbuf',
|
||||||
self.EntryTagName(entry), 'tmp'))
|
self.EntryTagName(entry),
|
||||||
|
entry.GetVarName('tmp'),
|
||||||
|
entry.GetVarLen('tmp')))
|
||||||
|
|
||||||
print >>file, ( ' tmp->%s_set = 1;\n' % entry.Name() +
|
print >>file, ( ' tmp->%s_set = 1;\n' % entry.Name() +
|
||||||
' break;\n' )
|
' break;\n' )
|
||||||
@ -249,9 +256,17 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, uint32_t,
|
|||||||
'%(name)s_complete(struct %(name)s *msg)\n'
|
'%(name)s_complete(struct %(name)s *msg)\n'
|
||||||
'{' ) % { 'name' : self._name }
|
'{' ) % { 'name' : self._name }
|
||||||
for entry in self._entries:
|
for entry in self._entries:
|
||||||
self.PrintIdented(
|
if not entry.Optional():
|
||||||
|
code = [
|
||||||
|
'if (!msg->%(name)s_set)',
|
||||||
|
' return (-1);' ]
|
||||||
|
code = TranslateList(code, entry.GetTranslation())
|
||||||
|
self.PrintIndented(
|
||||||
|
file, ' ', code)
|
||||||
|
|
||||||
|
self.PrintIndented(
|
||||||
file, ' ',
|
file, ' ',
|
||||||
entry.CodeComplete('msg'))
|
entry.CodeComplete('msg', entry.GetVarName('msg')))
|
||||||
print >>file, (
|
print >>file, (
|
||||||
' return (0);\n'
|
' return (0);\n'
|
||||||
'}\n' )
|
'}\n' )
|
||||||
@ -309,12 +324,26 @@ class Entry:
|
|||||||
self._struct = None
|
self._struct = None
|
||||||
self._refname = None
|
self._refname = None
|
||||||
|
|
||||||
def GetTranslation(self):
|
self._optpointer = True
|
||||||
return { "parent_name" : self._struct.Name(),
|
self._optaddarg = True
|
||||||
"name" : self._name,
|
|
||||||
"ctype" : self._ctype,
|
def GetInitializer(self):
|
||||||
"refname" : self._refname
|
assert 0, "Entry does not provide initializer"
|
||||||
}
|
|
||||||
|
def GetTranslation(self, extradict = {}):
|
||||||
|
mapping = {
|
||||||
|
"parent_name" : self._struct.Name(),
|
||||||
|
"name" : self._name,
|
||||||
|
"ctype" : self._ctype,
|
||||||
|
"refname" : self._refname,
|
||||||
|
"optpointer" : self._optpointer and "*" or "",
|
||||||
|
"optreference" : self._optpointer and "&" or "",
|
||||||
|
"optaddarg" : self._optaddarg and ", %s value" % self._ctype or ""
|
||||||
|
}
|
||||||
|
for (k, v) in extradict.items():
|
||||||
|
mapping[k] = v
|
||||||
|
|
||||||
|
return mapping
|
||||||
|
|
||||||
def SetStruct(self, struct):
|
def SetStruct(self, struct):
|
||||||
self._struct = struct
|
self._struct = struct
|
||||||
@ -347,6 +376,12 @@ class Entry:
|
|||||||
def MakeOptional(self):
|
def MakeOptional(self):
|
||||||
self._optional = 1
|
self._optional = 1
|
||||||
|
|
||||||
|
def GetVarName(self, var):
|
||||||
|
return '%(var)s->%(name)s_data' % self.GetTranslation({ 'var' : var })
|
||||||
|
|
||||||
|
def GetVarLen(self, var):
|
||||||
|
return 'sizeof(%s)' % self._ctype
|
||||||
|
|
||||||
def GetFuncName(self):
|
def GetFuncName(self):
|
||||||
return '%s_%s_get' % (self._struct.Name(), self._name)
|
return '%s_%s_get' % (self._struct.Name(), self._name)
|
||||||
|
|
||||||
@ -399,14 +434,8 @@ class Entry:
|
|||||||
|
|
||||||
return code
|
return code
|
||||||
|
|
||||||
def CodeComplete(self, structname):
|
def CodeComplete(self, structname, var_name):
|
||||||
if self.Optional():
|
return []
|
||||||
return []
|
|
||||||
|
|
||||||
code = [ 'if (!%s->%s_set)' % (structname, self.Name()),
|
|
||||||
' return (-1);' ]
|
|
||||||
|
|
||||||
return code
|
|
||||||
|
|
||||||
def CodeFree(self, name):
|
def CodeFree(self, name):
|
||||||
return []
|
return []
|
||||||
@ -446,7 +475,17 @@ class EntryBytes(Entry):
|
|||||||
Entry.__init__(self, type, name, tag)
|
Entry.__init__(self, type, name, tag)
|
||||||
|
|
||||||
self._length = length
|
self._length = length
|
||||||
self._ctype = 'uint32_t'
|
self._ctype = 'uint8_t'
|
||||||
|
|
||||||
|
def GetInitializer(self):
|
||||||
|
return "NULL"
|
||||||
|
|
||||||
|
def GetVarLen(self, var):
|
||||||
|
return '(%s)' % self._length
|
||||||
|
|
||||||
|
def CodeArrayAdd(self, varname, value):
|
||||||
|
# XXX: copy here
|
||||||
|
return '%(varname)s = NULL;' % { 'varname' : varname }
|
||||||
|
|
||||||
def GetDeclaration(self, funcname):
|
def GetDeclaration(self, funcname):
|
||||||
code = [ 'int %s(struct %s *, %s **);' % (
|
code = [ 'int %s(struct %s *, %s **);' % (
|
||||||
@ -491,21 +530,23 @@ class EntryBytes(Entry):
|
|||||||
'}' ]
|
'}' ]
|
||||||
return code
|
return code
|
||||||
|
|
||||||
def CodeUnmarshal(self, buf, tag_name, var_name):
|
def CodeUnmarshal(self, buf, tag_name, var_name, var_len):
|
||||||
code = [ 'if (evtag_unmarshal_fixed(%s, %s, ' % (buf, tag_name) +
|
code = [ 'if (evtag_unmarshal_fixed(%(buf)s, %(tag)s, '
|
||||||
'%s->%s_data, ' % (var_name, self._name) +
|
'%(var)s, %(varlen)s) == -1) {',
|
||||||
'sizeof(%s->%s_data)) == -1) {' % (
|
' event_warnx("%%s: failed to unmarshal %(name)s", __func__);',
|
||||||
var_name, self._name),
|
|
||||||
' event_warnx("%%s: failed to unmarshal %s", __func__);' % (
|
|
||||||
self._name ),
|
|
||||||
' return (-1);',
|
' return (-1);',
|
||||||
'}'
|
'}'
|
||||||
]
|
]
|
||||||
return code
|
return TranslateList(code,
|
||||||
|
self.GetTranslation({
|
||||||
|
'var' : var_name,
|
||||||
|
'varlen' : var_len,
|
||||||
|
'buf' : buf,
|
||||||
|
'tag' : tag_name }))
|
||||||
|
|
||||||
def CodeMarshal(self, buf, tag_name, var_name):
|
def CodeMarshal(self, buf, tag_name, var_name, var_len):
|
||||||
code = ['evtag_marshal(%s, %s, %s->%s_data, sizeof(%s->%s_data));' % (
|
code = ['evtag_marshal(%s, %s, %s, %s);' % (
|
||||||
buf, tag_name, var_name, self._name, var_name, self._name )]
|
buf, tag_name, var_name, var_len)]
|
||||||
return code
|
return code
|
||||||
|
|
||||||
def CodeClear(self, structname):
|
def CodeClear(self, structname):
|
||||||
@ -515,10 +556,9 @@ class EntryBytes(Entry):
|
|||||||
|
|
||||||
return code
|
return code
|
||||||
|
|
||||||
def CodeNew(self, name):
|
def CodeInitialize(self, name):
|
||||||
code = ['memset(%s->%s_data, 0, sizeof(%s->%s_data));' % (
|
code = ['memset(%s->%s_data, 0, sizeof(%s->%s_data));' % (
|
||||||
name, self._name, name, self._name)]
|
name, self._name, name, self._name)]
|
||||||
code.extend(Entry.CodeNew(self, name))
|
|
||||||
return code
|
return code
|
||||||
|
|
||||||
def Verify(self):
|
def Verify(self):
|
||||||
@ -534,20 +574,38 @@ class EntryInt(Entry):
|
|||||||
# Init base class
|
# Init base class
|
||||||
Entry.__init__(self, type, name, tag)
|
Entry.__init__(self, type, name, tag)
|
||||||
|
|
||||||
|
self._can_be_array = 1
|
||||||
self._ctype = 'uint32_t'
|
self._ctype = 'uint32_t'
|
||||||
|
|
||||||
def CodeUnmarshal(self, buf, tag_name, var_name):
|
def GetInitializer(self):
|
||||||
code = ['if (evtag_unmarshal_int(%s, %s, &%s->%s_data) == -1) {' % (
|
return "0"
|
||||||
buf, tag_name, var_name, self._name),
|
|
||||||
' event_warnx("%%s: failed to unmarshal %s", __func__);' % (
|
def CodeArrayFree(self, var):
|
||||||
self._name ),
|
return ""
|
||||||
|
|
||||||
|
def CodeArrayAssign(self, varname, srcvar):
|
||||||
|
return "%(varname)s = %(srcvar)s" % { 'varname' : varname,
|
||||||
|
'srcvar' : srcvar }
|
||||||
|
|
||||||
|
def CodeArrayAdd(self, varname, value):
|
||||||
|
"""Returns a new entry of this type."""
|
||||||
|
return '%(varname)s = %(value)s;' % { 'varname' : varname,
|
||||||
|
'value' : value }
|
||||||
|
|
||||||
|
def CodeUnmarshal(self, buf, tag_name, var_name, var_len):
|
||||||
|
code = ['if (evtag_unmarshal_int(%(buf)s, %(tag)s, &%(var)s) == -1) {',
|
||||||
|
' event_warnx("%%s: failed to unmarshal %(name)s", __func__);',
|
||||||
' return (-1);',
|
' return (-1);',
|
||||||
'}' ]
|
'}' ]
|
||||||
return code
|
code = '\n'.join(code) % self.GetTranslation({
|
||||||
|
'buf' : buf,
|
||||||
|
'tag' : tag_name,
|
||||||
|
'var' : var_name })
|
||||||
|
return code.split('\n')
|
||||||
|
|
||||||
def CodeMarshal(self, buf, tag_name, var_name):
|
def CodeMarshal(self, buf, tag_name, var_name, var_len):
|
||||||
code = ['evtag_marshal_int(%s, %s, %s->%s_data);' % (
|
code = ['evtag_marshal_int(%s, %s, %s);' % (
|
||||||
buf, tag_name, var_name, self._name)]
|
buf, tag_name, var_name)]
|
||||||
return code
|
return code
|
||||||
|
|
||||||
def Declaration(self):
|
def Declaration(self):
|
||||||
@ -555,7 +613,7 @@ class EntryInt(Entry):
|
|||||||
|
|
||||||
return dcl
|
return dcl
|
||||||
|
|
||||||
def CodeNew(self, name):
|
def CodeInitialize(self, name):
|
||||||
code = ['%s->%s_data = 0;' % (name, self._name)]
|
code = ['%s->%s_data = 0;' % (name, self._name)]
|
||||||
return code
|
return code
|
||||||
|
|
||||||
@ -566,6 +624,15 @@ class EntryString(Entry):
|
|||||||
|
|
||||||
self._ctype = 'char *'
|
self._ctype = 'char *'
|
||||||
|
|
||||||
|
def GetInitializer(self):
|
||||||
|
return "NULL"
|
||||||
|
|
||||||
|
def GetVarLen(self, var):
|
||||||
|
return 'strlen(%s)' % self.GetVarName(var)
|
||||||
|
|
||||||
|
def CodeMakeInitalize(self, varname):
|
||||||
|
return '%(varname)s = NULL;' % { 'varname' : varname }
|
||||||
|
|
||||||
def CodeAssign(self):
|
def CodeAssign(self):
|
||||||
name = self._name
|
name = self._name
|
||||||
code = """int
|
code = """int
|
||||||
@ -582,19 +649,21 @@ class EntryString(Entry):
|
|||||||
|
|
||||||
return code.split('\n')
|
return code.split('\n')
|
||||||
|
|
||||||
def CodeUnmarshal(self, buf, tag_name, var_name):
|
def CodeUnmarshal(self, buf, tag_name, var_name, var_len):
|
||||||
code = ['if (evtag_unmarshal_string(%s, %s, &%s->%s_data) == -1) {' % (
|
code = ['if (evtag_unmarshal_string(%(buf)s, %(tag)s, &%(var)s) == -1) {',
|
||||||
buf, tag_name, var_name, self._name),
|
' event_warnx("%%s: failed to unmarshal %(name)s", __func__);',
|
||||||
' event_warnx("%%s: failed to unmarshal %s", __func__);' % (
|
|
||||||
self._name ),
|
|
||||||
' return (-1);',
|
' return (-1);',
|
||||||
'}'
|
'}'
|
||||||
]
|
]
|
||||||
return code
|
code = '\n'.join(code) % self.GetTranslation({
|
||||||
|
'buf' : buf,
|
||||||
|
'tag' : tag_name,
|
||||||
|
'var' : var_name })
|
||||||
|
return code.split('\n')
|
||||||
|
|
||||||
def CodeMarshal(self, buf, tag_name, var_name):
|
def CodeMarshal(self, buf, tag_name, var_name, var_len):
|
||||||
code = ['evtag_marshal_string(%s, %s, %s->%s_data);' % (
|
code = ['evtag_marshal_string(%s, %s, %s);' % (
|
||||||
buf, tag_name, var_name, self._name)]
|
buf, tag_name, var_name)]
|
||||||
return code
|
return code
|
||||||
|
|
||||||
def CodeClear(self, structname):
|
def CodeClear(self, structname):
|
||||||
@ -607,7 +676,7 @@ class EntryString(Entry):
|
|||||||
|
|
||||||
return code
|
return code
|
||||||
|
|
||||||
def CodeNew(self, name):
|
def CodeInitialize(self, name):
|
||||||
code = ['%s->%s_data = NULL;' % (name, self._name)]
|
code = ['%s->%s_data = NULL;' % (name, self._name)]
|
||||||
return code
|
return code
|
||||||
|
|
||||||
@ -627,9 +696,51 @@ class EntryStruct(Entry):
|
|||||||
# Init base class
|
# Init base class
|
||||||
Entry.__init__(self, type, name, tag)
|
Entry.__init__(self, type, name, tag)
|
||||||
|
|
||||||
|
self._optpointer = False
|
||||||
self._can_be_array = 1
|
self._can_be_array = 1
|
||||||
self._refname = refname
|
self._refname = refname
|
||||||
self._ctype = 'struct %s*' % refname
|
self._ctype = 'struct %s*' % refname
|
||||||
|
self._optaddarg = False
|
||||||
|
|
||||||
|
def GetInitializer(self):
|
||||||
|
return "NULL"
|
||||||
|
|
||||||
|
def GetVarLen(self, var):
|
||||||
|
return '-1'
|
||||||
|
|
||||||
|
def CodeArrayAdd(self, varname, value):
|
||||||
|
return ( '%(varname)s = %(refname)s_new();\n'
|
||||||
|
'if (%(varname)s == NULL) \n'
|
||||||
|
' goto error;'
|
||||||
|
) % self.GetTranslation({ 'varname' : varname })
|
||||||
|
|
||||||
|
def CodeArrayFree(self, var):
|
||||||
|
code = """%(refname)s_free(%(var)s);""" % self.GetTranslation(
|
||||||
|
{ 'var' : var })
|
||||||
|
return code
|
||||||
|
|
||||||
|
def CodeArrayAssign(self, var, srcvar):
|
||||||
|
code = """struct evbuffer *tmp = NULL;
|
||||||
|
%(refname)s_clear(%(var)s);
|
||||||
|
if ((tmp = evbuffer_new()) == NULL) {
|
||||||
|
event_warn("%%s: evbuffer_new()", __func__);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
%(refname)s_marshal(tmp, %(srcvar)s);
|
||||||
|
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(
|
||||||
|
{ 'var' : var,
|
||||||
|
'srcvar' : srcvar})
|
||||||
|
return code
|
||||||
|
|
||||||
def CodeGet(self):
|
def CodeGet(self):
|
||||||
name = self._name
|
name = self._name
|
||||||
@ -689,36 +800,34 @@ class EntryStruct(Entry):
|
|||||||
}""" % self.GetTranslation()
|
}""" % self.GetTranslation()
|
||||||
return code.split('\n')
|
return code.split('\n')
|
||||||
|
|
||||||
def CodeComplete(self, structname):
|
def CodeComplete(self, structname, var_name):
|
||||||
if self.Optional():
|
code = [ 'if (%(structname)s->%(name)s_set && '
|
||||||
code = [ 'if (%s->%s_set && %s_complete(%s->%s_data) == -1)' % (
|
'%(refname)s_complete(%(var)s) == -1)',
|
||||||
structname, self.Name(),
|
' return (-1);' ]
|
||||||
self._refname, structname, self.Name()),
|
|
||||||
' return (-1);' ]
|
|
||||||
else:
|
|
||||||
code = [ 'if (%s_complete(%s->%s_data) == -1)' % (
|
|
||||||
self._refname, structname, self.Name()),
|
|
||||||
' return (-1);' ]
|
|
||||||
|
|
||||||
return code
|
return TranslateList(code, self.GetTranslation({
|
||||||
|
'structname' : structname,
|
||||||
|
'var' : var_name }))
|
||||||
|
|
||||||
def CodeUnmarshal(self, buf, tag_name, var_name):
|
def CodeUnmarshal(self, buf, tag_name, var_name, var_len):
|
||||||
code = ['%s->%s_data = %s_new();' % (
|
code = ['%(var)s = %(refname)s_new();',
|
||||||
var_name, self._name, self._refname),
|
'if (%(var)s == NULL)',
|
||||||
'if (%s->%s_data == NULL)' % (var_name, self._name),
|
|
||||||
' return (-1);',
|
' return (-1);',
|
||||||
'if (evtag_unmarshal_%s(%s, %s, %s->%s_data) == -1) {' % (
|
'if (evtag_unmarshal_%(refname)s(%(buf)s, %(tag)s, '
|
||||||
self._refname, buf, tag_name, var_name, self._name),
|
'%(var)s) == -1) {',
|
||||||
' event_warnx("%%s: failed to unmarshal %s", __func__);' % (
|
' event_warnx("%%s: failed to unmarshal %(name)s", __func__);',
|
||||||
self._name ),
|
|
||||||
' return (-1);',
|
' return (-1);',
|
||||||
'}'
|
'}'
|
||||||
]
|
]
|
||||||
return code
|
code = '\n'.join(code) % self.GetTranslation({
|
||||||
|
'buf' : buf,
|
||||||
|
'tag' : tag_name,
|
||||||
|
'var' : var_name })
|
||||||
|
return code.split('\n')
|
||||||
|
|
||||||
def CodeMarshal(self, buf, tag_name, var_name):
|
def CodeMarshal(self, buf, tag_name, var_name, var_len):
|
||||||
code = ['evtag_marshal_%s(%s, %s, %s->%s_data);' % (
|
code = ['evtag_marshal_%s(%s, %s, %s);' % (
|
||||||
self._refname, buf, tag_name, var_name, self._name)]
|
self._refname, buf, tag_name, var_name)]
|
||||||
return code
|
return code
|
||||||
|
|
||||||
def CodeClear(self, structname):
|
def CodeClear(self, structname):
|
||||||
@ -732,7 +841,7 @@ class EntryStruct(Entry):
|
|||||||
|
|
||||||
return code
|
return code
|
||||||
|
|
||||||
def CodeNew(self, name):
|
def CodeInitialize(self, name):
|
||||||
code = ['%s->%s_data = NULL;' % (name, self._name)]
|
code = ['%s->%s_data = NULL;' % (name, self._name)]
|
||||||
return code
|
return code
|
||||||
|
|
||||||
@ -755,6 +864,16 @@ class EntryVarBytes(Entry):
|
|||||||
|
|
||||||
self._ctype = 'uint8_t *'
|
self._ctype = 'uint8_t *'
|
||||||
|
|
||||||
|
def GetInitializer(self):
|
||||||
|
return "NULL"
|
||||||
|
|
||||||
|
def GetVarLen(self, var):
|
||||||
|
return '%(var)s->%(name)s_length' % self.GetTranslation({ 'var' : var })
|
||||||
|
|
||||||
|
def CodeArrayAdd(self, varname, value):
|
||||||
|
# xxx: copy
|
||||||
|
return '%(varname)s = NULL;' % { 'varname' : varname }
|
||||||
|
|
||||||
def GetDeclaration(self, funcname):
|
def GetDeclaration(self, funcname):
|
||||||
code = [ 'int %s(struct %s *, %s *, uint32_t *);' % (
|
code = [ 'int %s(struct %s *, %s *, uint32_t *);' % (
|
||||||
funcname, self._struct.Name(), self._ctype ) ]
|
funcname, self._struct.Name(), self._ctype ) ]
|
||||||
@ -800,30 +919,30 @@ class EntryVarBytes(Entry):
|
|||||||
'}' ]
|
'}' ]
|
||||||
return code
|
return code
|
||||||
|
|
||||||
def CodeUnmarshal(self, buf, tag_name, var_name):
|
def CodeUnmarshal(self, buf, tag_name, var_name, var_len):
|
||||||
code = ['if (evtag_payload_length(%s, &%s->%s_length) == -1)' % (
|
code = ['if (evtag_payload_length(%(buf)s, &%(varlen)s) == -1)',
|
||||||
buf, var_name, self._name),
|
|
||||||
' return (-1);',
|
' return (-1);',
|
||||||
# We do not want DoS opportunities
|
# We do not want DoS opportunities
|
||||||
'if (%s->%s_length > EVBUFFER_LENGTH(%s))' % (
|
'if (%(varlen)s > EVBUFFER_LENGTH(%(buf)s))',
|
||||||
var_name, self._name, buf),
|
|
||||||
' return (-1);',
|
' return (-1);',
|
||||||
'if ((%s->%s_data = malloc(%s->%s_length)) == NULL)' % (
|
'if ((%(var)s = malloc(%(varlen)s)) == NULL)',
|
||||||
var_name, self._name, var_name, self._name),
|
|
||||||
' return (-1);',
|
' return (-1);',
|
||||||
'if (evtag_unmarshal_fixed(%s, %s, %s->%s_data, '
|
'if (evtag_unmarshal_fixed(%(buf)s, %(tag)s, %(var)s, '
|
||||||
'%s->%s_length) == -1) {' % (
|
'%(varlen)s) == -1) {',
|
||||||
buf, tag_name, var_name, self._name, var_name, self._name),
|
' event_warnx("%%s: failed to unmarshal %(name)s", __func__);',
|
||||||
' event_warnx("%%s: failed to unmarshal %s", __func__);' % (
|
|
||||||
self._name ),
|
|
||||||
' return (-1);',
|
' return (-1);',
|
||||||
'}'
|
'}'
|
||||||
]
|
]
|
||||||
return code
|
code = '\n'.join(code) % self.GetTranslation({
|
||||||
|
'buf' : buf,
|
||||||
|
'tag' : tag_name,
|
||||||
|
'var' : var_name,
|
||||||
|
'varlen' : var_len })
|
||||||
|
return code.split('\n')
|
||||||
|
|
||||||
def CodeMarshal(self, buf, tag_name, var_name):
|
def CodeMarshal(self, buf, tag_name, var_name, var_len):
|
||||||
code = ['evtag_marshal(%s, %s, %s->%s_data, %s->%s_length);' % (
|
code = ['evtag_marshal(%s, %s, %s, %s);' % (
|
||||||
buf, tag_name, var_name, self._name, var_name, self._name)]
|
buf, tag_name, var_name, var_len)]
|
||||||
return code
|
return code
|
||||||
|
|
||||||
def CodeClear(self, structname):
|
def CodeClear(self, structname):
|
||||||
@ -837,7 +956,7 @@ class EntryVarBytes(Entry):
|
|||||||
|
|
||||||
return code
|
return code
|
||||||
|
|
||||||
def CodeNew(self, name):
|
def CodeInitialize(self, name):
|
||||||
code = ['%s->%s_data = NULL;' % (name, self._name),
|
code = ['%s->%s_data = NULL;' % (name, self._name),
|
||||||
'%s->%s_length = 0;' % (name, self._name) ]
|
'%s->%s_length = 0;' % (name, self._name) ]
|
||||||
return code
|
return code
|
||||||
@ -861,15 +980,32 @@ class EntryArray(Entry):
|
|||||||
|
|
||||||
self._entry = entry
|
self._entry = entry
|
||||||
self._refname = entry._refname
|
self._refname = entry._refname
|
||||||
self._ctype = 'struct %s *' % self._refname
|
self._ctype = self._entry._ctype
|
||||||
|
self._optional = True
|
||||||
|
self._optpointer = self._entry._optpointer
|
||||||
|
self._optaddarg = self._entry._optaddarg
|
||||||
|
|
||||||
|
# provide a new function for accessing the variable name
|
||||||
|
def GetVarName(var_name):
|
||||||
|
return '%(var)s->%(name)s_data[%(index)s]' % \
|
||||||
|
self._entry.GetTranslation({'var' : var_name,
|
||||||
|
'index' : self._index})
|
||||||
|
self._entry.GetVarName = GetVarName
|
||||||
|
|
||||||
|
def GetInitializer(self):
|
||||||
|
return "NULL"
|
||||||
|
|
||||||
|
def GetVarName(self, var_name):
|
||||||
|
return var_name
|
||||||
|
|
||||||
|
def GetVarLen(self, var_name):
|
||||||
|
return '-1'
|
||||||
|
|
||||||
def GetDeclaration(self, funcname):
|
def GetDeclaration(self, funcname):
|
||||||
"""Allows direct access to elements of the array."""
|
"""Allows direct access to elements of the array."""
|
||||||
translate = self.GetTranslation()
|
|
||||||
translate["funcname"] = funcname
|
|
||||||
code = [
|
code = [
|
||||||
'int %(funcname)s(struct %(parent_name)s *, int, %(ctype)s *);' %
|
'int %(funcname)s(struct %(parent_name)s *, int, %(ctype)s *);' %
|
||||||
translate ]
|
self.GetTranslation({ 'funcname' : funcname }) ]
|
||||||
return code
|
return code
|
||||||
|
|
||||||
def AssignDeclaration(self, funcname):
|
def AssignDeclaration(self, funcname):
|
||||||
@ -878,8 +1014,10 @@ class EntryArray(Entry):
|
|||||||
return code
|
return code
|
||||||
|
|
||||||
def AddDeclaration(self, funcname):
|
def AddDeclaration(self, funcname):
|
||||||
code = [ '%s %s(struct %s *);' % (
|
code = [
|
||||||
self._ctype, funcname, self._struct.Name() ) ]
|
'%(ctype)s %(optpointer)s '
|
||||||
|
'%(funcname)s(struct %(parent_name)s *msg%(optaddarg)s);' % \
|
||||||
|
self.GetTranslation({ 'funcname' : funcname }) ]
|
||||||
return code
|
return code
|
||||||
|
|
||||||
def CodeGet(self):
|
def CodeGet(self):
|
||||||
@ -896,38 +1034,29 @@ class EntryArray(Entry):
|
|||||||
return code.split('\n')
|
return code.split('\n')
|
||||||
|
|
||||||
def CodeAssign(self):
|
def CodeAssign(self):
|
||||||
|
codearrayassign = self._entry.CodeArrayAssign(
|
||||||
|
'msg->%(name)s_data[off]' % self.GetTranslation(), 'value')
|
||||||
code = """int
|
code = """int
|
||||||
%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg, int off,
|
%(parent_name)s_%(name)s_assign(struct %(parent_name)s *msg, int off,
|
||||||
const %(ctype)s value)
|
const %(ctype)s value)
|
||||||
{
|
{
|
||||||
struct evbuffer *tmp = NULL;
|
|
||||||
if (!msg->%(name)s_set || off < 0 || off >= msg->%(name)s_length)
|
if (!msg->%(name)s_set || off < 0 || off >= msg->%(name)s_length)
|
||||||
return (-1);
|
return (-1);\n
|
||||||
%(refname)s_clear(msg->%(name)s_data[off]);
|
{
|
||||||
if ((tmp = evbuffer_new()) == NULL) {
|
%(codearrayassign)s;
|
||||||
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);
|
return (0);
|
||||||
error:
|
}""" % self.GetTranslation({'codearrayassign' : codearrayassign})
|
||||||
if (tmp != NULL)
|
|
||||||
evbuffer_free(tmp);
|
|
||||||
%(refname)s_clear(msg->%(name)s_data[off]);
|
|
||||||
return (-1);
|
|
||||||
}""" % self.GetTranslation()
|
|
||||||
|
|
||||||
return code.split('\n')
|
return code.split('\n')
|
||||||
|
|
||||||
def CodeAdd(self):
|
def CodeAdd(self):
|
||||||
|
codearrayadd = self._entry.CodeArrayAdd(
|
||||||
|
'msg->%(name)s_data[msg->%(name)s_length - 1]' % self.GetTranslation(),
|
||||||
|
'value')
|
||||||
code = \
|
code = \
|
||||||
"""%(ctype)s
|
"""%(ctype)s %(optpointer)s
|
||||||
%(parent_name)s_%(name)s_add(struct %(parent_name)s *msg)
|
%(parent_name)s_%(name)s_add(struct %(parent_name)s *msg%(optaddarg)s)
|
||||||
{
|
{
|
||||||
if (++msg->%(name)s_length >= msg->%(name)s_num_allocated) {
|
if (++msg->%(name)s_length >= msg->%(name)s_num_allocated) {
|
||||||
int tobe_allocated = msg->%(name)s_num_allocated;
|
int tobe_allocated = msg->%(name)s_num_allocated;
|
||||||
@ -940,110 +1069,143 @@ error:
|
|||||||
msg->%(name)s_data = new_data;
|
msg->%(name)s_data = new_data;
|
||||||
msg->%(name)s_num_allocated = tobe_allocated;
|
msg->%(name)s_num_allocated = tobe_allocated;
|
||||||
}
|
}
|
||||||
msg->%(name)s_data[msg->%(name)s_length - 1] = %(refname)s_new();
|
%(codearrayadd)s;
|
||||||
if (msg->%(name)s_data[msg->%(name)s_length - 1] == NULL)
|
|
||||||
goto error;
|
|
||||||
msg->%(name)s_set = 1;
|
msg->%(name)s_set = 1;
|
||||||
return (msg->%(name)s_data[msg->%(name)s_length - 1]);
|
return %(optreference)s(msg->%(name)s_data[msg->%(name)s_length - 1]);
|
||||||
error:
|
error:
|
||||||
--msg->%(name)s_length;
|
--msg->%(name)s_length;
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
""" % self.GetTranslation()
|
""" % self.GetTranslation({ 'codearrayadd' : codearrayadd })
|
||||||
|
|
||||||
return code.split('\n')
|
return code.split('\n')
|
||||||
|
|
||||||
def CodeComplete(self, structname):
|
def CodeComplete(self, structname, var_name):
|
||||||
code = []
|
self._index = 'i'
|
||||||
translate = self.GetTranslation()
|
tmp = self._entry.CodeComplete(structname, self._entry.GetVarName(var_name))
|
||||||
|
# skip the whole loop if there is nothing to check
|
||||||
|
if not tmp:
|
||||||
|
return []
|
||||||
|
|
||||||
if self.Optional():
|
translate = self.GetTranslation({ 'structname' : structname })
|
||||||
code.append( 'if (%(structname)s->%(name)s_set)' % translate)
|
code = [
|
||||||
|
'{',
|
||||||
|
' int i;',
|
||||||
|
' for (i = 0; i < %(structname)s->%(name)s_length; ++i) {' ]
|
||||||
|
|
||||||
translate["structname"] = structname
|
code = TranslateList(code, translate)
|
||||||
tmp = """{
|
|
||||||
int i;
|
code += map(lambda x: ' ' + x, tmp)
|
||||||
for (i = 0; i < %(structname)s->%(name)s_length; ++i) {
|
|
||||||
if (%(refname)s_complete(%(structname)s->%(name)s_data[i]) == -1)
|
code += [
|
||||||
return (-1);
|
' }',
|
||||||
}
|
'}' ]
|
||||||
}""" % translate
|
|
||||||
code.extend(tmp.split('\n'))
|
|
||||||
|
|
||||||
return code
|
return code
|
||||||
|
|
||||||
def CodeUnmarshal(self, buf, tag_name, var_name):
|
def CodeUnmarshal(self, buf, tag_name, var_name, var_len):
|
||||||
translate = self.GetTranslation()
|
translate = self.GetTranslation({ 'var' : var_name,
|
||||||
translate["var_name"] = var_name
|
'buf' : buf,
|
||||||
translate["buf"] = buf
|
'tag' : tag_name,
|
||||||
translate["tag_name"] = tag_name
|
'init' : self._entry.GetInitializer()})
|
||||||
code = """if (%(parent_name)s_%(name)s_add(%(var_name)s) == NULL)
|
if self._optaddarg:
|
||||||
return (-1);
|
code = [
|
||||||
if (evtag_unmarshal_%(refname)s(%(buf)s, %(tag_name)s,
|
'if (%(parent_name)s_%(name)s_add(%(var)s, %(init)s) == NULL)',
|
||||||
%(var_name)s->%(name)s_data[%(var_name)s->%(name)s_length - 1]) == -1) {
|
' return (-1);' ]
|
||||||
--%(var_name)s->%(name)s_length;
|
else:
|
||||||
event_warnx("%%s: failed to unmarshal %(name)s", __func__);
|
code = [
|
||||||
return (-1);
|
'if (%(parent_name)s_%(name)s_add(%(var)s) == NULL)',
|
||||||
}""" % translate
|
' return (-1);' ]
|
||||||
|
|
||||||
return code.split('\n')
|
# the unmarshal code directly returns
|
||||||
|
code += [ '--%(var)s->%(name)s_length;' % translate ]
|
||||||
|
code = TranslateList(code, translate)
|
||||||
|
|
||||||
def CodeMarshal(self, buf, tag_name, var_name):
|
self._index = '%(var)s->%(name)s_length' % translate
|
||||||
|
code += self._entry.CodeUnmarshal(buf, tag_name,
|
||||||
|
self._entry.GetVarName(var_name),
|
||||||
|
self._entry.GetVarLen(var_name))
|
||||||
|
|
||||||
|
code += [ '++%(var)s->%(name)s_length;' % translate ]
|
||||||
|
|
||||||
|
return code
|
||||||
|
|
||||||
|
def CodeMarshal(self, buf, tag_name, var_name, var_len):
|
||||||
code = ['{',
|
code = ['{',
|
||||||
' int i;',
|
' int i;',
|
||||||
' for (i = 0; i < %s->%s_length; ++i) {' % (
|
' for (i = 0; i < %(var)s->%(name)s_length; ++i) {' ]
|
||||||
var_name, self._name),
|
|
||||||
' evtag_marshal_%s(%s, %s, %s->%s_data[i]);' % (
|
|
||||||
self._refname, buf, tag_name, var_name, self._name),
|
|
||||||
' }',
|
|
||||||
'}'
|
|
||||||
]
|
|
||||||
return code
|
|
||||||
|
|
||||||
def CodeClear(self, structname):
|
self._index = 'i'
|
||||||
code = [ 'if (%s->%s_set == 1) {' % (structname, self.Name()),
|
code += self._entry.CodeMarshal(buf, tag_name,
|
||||||
' int i;',
|
self._entry.GetVarName(var_name),
|
||||||
' for (i = 0; i < %s->%s_length; ++i) {' % (
|
self._entry.GetVarLen(var_name))
|
||||||
structname, self.Name()),
|
code += [' }',
|
||||||
' %s_free(%s->%s_data[i]);' % (
|
|
||||||
self._refname, structname, self.Name()),
|
|
||||||
' }',
|
|
||||||
' free(%s->%s_data);' % (structname, self.Name()),
|
|
||||||
' %s->%s_data = NULL;' % (structname, self.Name()),
|
|
||||||
' %s->%s_set = 0;' % (structname, self.Name()),
|
|
||||||
' %s->%s_length = 0;' % (structname, self.Name()),
|
|
||||||
' %s->%s_num_allocated = 0;' % (structname, self.Name()),
|
|
||||||
'}'
|
'}'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
code = "\n".join(code) % self.GetTranslation({ 'var' : var_name })
|
||||||
|
|
||||||
|
return code.split('\n')
|
||||||
|
|
||||||
|
def CodeClear(self, structname):
|
||||||
|
codearrayfree = self._entry.CodeArrayFree(
|
||||||
|
'%(structname)s->%(name)s_data[i]' % self.GetTranslation(
|
||||||
|
{ 'structname' : structname } ))
|
||||||
|
code = [ 'if (%(structname)s->%(name)s_set == 1) {',
|
||||||
|
' int i;',
|
||||||
|
' for (i = 0; i < %(structname)s->%(name)s_length; ++i) {',
|
||||||
|
' %(codearrayfree)s',
|
||||||
|
' }',
|
||||||
|
' free(%(structname)s->%(name)s_data);',
|
||||||
|
' %(structname)s->%(name)s_data = NULL;',
|
||||||
|
' %(structname)s->%(name)s_set = 0;',
|
||||||
|
' %(structname)s->%(name)s_length = 0;',
|
||||||
|
' %(structname)s->%(name)s_num_allocated = 0;',
|
||||||
|
'}'
|
||||||
|
]
|
||||||
|
|
||||||
|
code = TranslateList(code, self.GetTranslation(
|
||||||
|
{ 'structname' : structname,
|
||||||
|
'codearrayfree' : codearrayfree }))
|
||||||
|
|
||||||
return code
|
return code
|
||||||
|
|
||||||
def CodeNew(self, name):
|
def CodeInitialize(self, name):
|
||||||
code = ['%s->%s_data = NULL;' % (name, self._name),
|
code = ['%s->%s_data = NULL;' % (name, self._name),
|
||||||
'%s->%s_length = 0;' % (name, self._name),
|
'%s->%s_length = 0;' % (name, self._name),
|
||||||
'%s->%s_num_allocated = 0;' % (name, self._name)]
|
'%s->%s_num_allocated = 0;' % (name, self._name)]
|
||||||
return code
|
return code
|
||||||
|
|
||||||
def CodeFree(self, name):
|
def CodeFree(self, structname):
|
||||||
code = ['if (%s->%s_data != NULL) {' % (name, self._name),
|
codearrayfree = self._entry.CodeArrayFree(
|
||||||
' int i;',
|
'%(structname)s->%(name)s_data[i]' % self.GetTranslation(
|
||||||
' for (i = 0; i < %s->%s_length; ++i) {' % (
|
{ 'structname' : structname } ))
|
||||||
name, self._name),
|
code = [ 'if (%(structname)s->%(name)s_data != NULL) {' ]
|
||||||
' %s_free(%s->%s_data[i]); ' % (
|
|
||||||
self._refname, name, self._name),
|
if codearrayfree:
|
||||||
' %s->%s_data[i] = NULL;' % (name, self._name),
|
code += [
|
||||||
' }',
|
' int i;',
|
||||||
' free(%s->%s_data);' % (name, self._name),
|
' for (i = 0; i < %(structname)s->%(name)s_length; ++i) {',
|
||||||
' %s->%s_data = NULL;' % (name, self._name),
|
' %(codearrayfree)s',
|
||||||
' %s->%s_length = 0;' % (name, self._name),
|
' }' ]
|
||||||
' %s->%s_num_allocated = 0;' % (name, self._name),
|
|
||||||
|
code += [
|
||||||
|
' free(%(structname)s->%(name)s_data);',
|
||||||
|
' %(structname)s->%(name)s_data = NULL;',
|
||||||
|
' %(structname)s->%(name)s_set = 0;',
|
||||||
|
' %(structname)s->%(name)s_length = 0;',
|
||||||
|
' %(structname)s->%(name)s_num_allocated = 0;',
|
||||||
'}'
|
'}'
|
||||||
]
|
]
|
||||||
|
|
||||||
return code
|
code = '\n'.join(code) % self.GetTranslation(
|
||||||
|
{ 'structname' : structname,
|
||||||
|
'codearrayfree' : codearrayfree })
|
||||||
|
|
||||||
|
return code.split('\n')
|
||||||
|
|
||||||
def Declaration(self):
|
def Declaration(self):
|
||||||
dcl = ['struct %s **%s_data;' % (self._refname, self._name),
|
dcl = ['%s *%s_data;' % (self._ctype, self._name),
|
||||||
'int %s_length;' % self._name,
|
'int %s_length;' % self._name,
|
||||||
'int %s_num_allocated;' % self._name ]
|
'int %s_num_allocated;' % self._name ]
|
||||||
|
|
||||||
@ -1319,7 +1481,8 @@ def HeaderPreamble(name):
|
|||||||
'(*(msg)->base->member##_assign)(msg, ## args)\n'
|
'(*(msg)->base->member##_assign)(msg, ## args)\n'
|
||||||
'#define EVTAG_GET(msg, member, args...) '
|
'#define EVTAG_GET(msg, member, args...) '
|
||||||
'(*(msg)->base->member##_get)(msg, ## args)\n'
|
'(*(msg)->base->member##_get)(msg, ## args)\n'
|
||||||
'#define EVTAG_ADD(msg, member) (*(msg)->base->member##_add)(msg)\n'
|
'#define EVTAG_ADD(msg, member, args...) '
|
||||||
|
'(*(msg)->base->member##_add)(msg, ## args)\n'
|
||||||
'#define EVTAG_LEN(msg, member) ((msg)->member##_length)\n'
|
'#define EVTAG_LEN(msg, member) ((msg)->member##_length)\n'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1417,6 +1417,12 @@ rpc_test(void)
|
|||||||
|
|
||||||
EVTAG_ASSIGN(attack, weapon, "feather");
|
EVTAG_ASSIGN(attack, weapon, "feather");
|
||||||
EVTAG_ASSIGN(attack, action, "tickle");
|
EVTAG_ASSIGN(attack, action, "tickle");
|
||||||
|
for (i = 0; i < 3; ++i) {
|
||||||
|
if (EVTAG_ADD(attack, how_often, i) == NULL) {
|
||||||
|
fprintf(stderr, "Failed to add how_often.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gettimeofday(&tv_start, NULL);
|
gettimeofday(&tv_start, NULL);
|
||||||
for (i = 0; i < 1000; ++i) {
|
for (i = 0; i < 1000; ++i) {
|
||||||
@ -1426,6 +1432,8 @@ rpc_test(void)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
EVTAG_ASSIGN(run, how, "very fast but with some data in it");
|
EVTAG_ASSIGN(run, how, "very fast but with some data in it");
|
||||||
|
EVTAG_ASSIGN(run, fixed_bytes,
|
||||||
|
(uint8_t*)"012345678901234567890123");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg_complete(msg) == -1) {
|
if (msg_complete(msg) == -1) {
|
||||||
@ -1464,11 +1472,33 @@ rpc_test(void)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (EVTAG_GET(msg2, attack, &attack) == -1) {
|
||||||
|
fprintf(stderr, "Get not get attack.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
if (EVTAG_LEN(msg2, run) != i) {
|
if (EVTAG_LEN(msg2, run) != i) {
|
||||||
fprintf(stderr, "Wrong number of run messages.\n");
|
fprintf(stderr, "Wrong number of run messages.\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (EVTAG_LEN(attack, how_often) != 3) {
|
||||||
|
fprintf(stderr, "Wrong number of how_often ints.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 3; ++i) {
|
||||||
|
uint32_t res;
|
||||||
|
if (EVTAG_GET(attack, how_often, i, &res) == -1) {
|
||||||
|
fprintf(stderr, "Cannot get %dth how_often msg.\n", i);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (res != i) {
|
||||||
|
fprintf(stderr, "Wrong message encoded %d != %d\n", i, res);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
msg_free(msg);
|
msg_free(msg);
|
||||||
msg_free(msg2);
|
msg_free(msg2);
|
||||||
|
|
||||||
|
@ -10,9 +10,12 @@ struct msg {
|
|||||||
struct kill {
|
struct kill {
|
||||||
string weapon = 0x10121;
|
string weapon = 0x10121;
|
||||||
string action = 2;
|
string action = 2;
|
||||||
optional int how_often = 3;
|
array int how_often = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct run {
|
struct run {
|
||||||
string how = 1;
|
string how = 1;
|
||||||
|
optional bytes some_bytes = 2;
|
||||||
|
|
||||||
|
bytes fixed_bytes[24] = 3;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user