]>
git.proxmox.com Git - mirror_ovs.git/blob - build-aux/check-structs
12 types
['char'] = {"size": 1, "alignment": 1}
13 types
['uint8_t'] = {"size": 1, "alignment": 1}
14 types
['ovs_be16'] = {"size": 2, "alignment": 2}
15 types
['ovs_be32'] = {"size": 4, "alignment": 4}
16 types
['ovs_be64'] = {"size": 8, "alignment": 8}
17 types
['ovs_32aligned_be64'] = {"size": 8, "alignment": 4}
18 types
['struct eth_addr'] = {"size": 6, "alignment": 2}
19 types
['struct eth_addr64'] = {"size": 8, "alignment": 2}
23 idRe
= "[a-zA-Z_][a-zA-Z_0-9]*"
24 tokenRe
= "#?" + idRe
+ "|[0-9]+|."
25 includeRe
= re
.compile(r
'\s*#include\s+<(openflow/[^#]+)>')
40 if line
.startswith("/*"):
44 commentEnd
= line
.find("*/")
49 line
= line
[commentEnd
+ 2:]
51 match
= re
.match(tokenRe
, line
)
52 token
= match
.group(0)
53 line
= line
[len(token
):]
54 if token
.startswith('#'):
56 elif token
in macros
and not inDirective
:
57 line
= macros
[token
] + line
67 line
= inputFile
.readline()
69 while line
.endswith("\\\n"):
70 line
= line
[:-2] + inputFile
.readline()
72 match
= includeRe
.match(line
)
74 inputStack
.append((fileName
, inputFile
, lineNumber
))
75 inputFile
= open(includePath
+ match
.group(1))
80 fileName
, inputFile
, lineNumber
= inputStack
.pop()
83 fatal("unexpected end of input")
89 sys
.stderr
.write("%s:%d: error at \"%s\": %s\n" % (fileName
, lineNumber
, token
, msg
))
95 sys
.stderr
.write("%s:%d: warning: %s\n" % (fileName
, lineNumber
, msg
))
103 return re
.match(idRe
+ "$", s
) != None
107 fatal("identifier expected")
110 if not re
.match('[0-9]+$', token
):
111 fatal("integer expected")
122 fatal("%s expected" % t
)
124 def parseTaggedName():
125 assert token
in ('struct', 'union')
129 name
= "%s %s" % (name
, token
)
134 if token
in ('struct', 'union'):
135 name
= parseTaggedName()
140 fatal("type name expected")
145 fatal("unknown type \"%s\"" % name
)
148 isStruct
= token
== 'struct'
149 structName
= parseTaggedName()
154 alignment
= 4 # ARM has minimum 32-bit alignment
156 while not match('}'):
157 typeName
= parseTypeName()
158 typeSize
= types
[typeName
]['size']
159 typeAlignment
= types
[typeName
]['alignment']
176 nBytes
= typeSize
* count
178 if ofs
% typeAlignment
:
179 shortage
= typeAlignment
- (ofs
% typeAlignment
)
180 warn("%s member %s is %d bytes short of %d-byte alignment"
181 % (structName
, memberName
, shortage
, typeAlignment
))
189 if typeAlignment
> alignment
:
190 alignment
= typeAlignment
194 shortage
= alignment
- (size
% alignment
)
195 if (structName
== "struct ofp10_packet_in" and
197 memberName
== 'data' and
199 # This is intentional
202 warn("%s needs %d bytes of tail padding" % (structName
, shortage
))
204 types
[structName
] = {"size": size
, "alignment": alignment
}
208 if len(sys
.argv
) < 2:
209 sys
.stderr
.write("at least one non-option argument required; "
210 "use --help for help")
213 if '--help' in sys
.argv
:
214 argv0
= os
.path
.basename(sys
.argv
[0])
216 %(argv0)s, for checking struct and struct member alignment
217 usage: %(argv0)s -Ipath HEADER [HEADER]...
219 This program reads the header files specified on the command line and
220 verifies that all struct members are aligned on natural boundaries
221 without any need for the compiler to add additional padding. It also
222 verifies that each struct's size is a multiple of 32 bits (because
223 some ABIs for ARM require all structs to be a multiple of 32 bits), or
224 64 bits if the struct has any 64-bit members, again without the
225 compiler adding additional padding. Finally, it checks struct size
226 assertions using OFP_ASSERT.
228 This program is specialized for reading Open vSwitch's OpenFlow header
229 files. It will not work on arbitrary header files without extensions.\
230 ''' % {"argv0": argv0
}
234 for fileName
in sys
.argv
[1:]:
235 if fileName
.startswith('-I'):
237 includePath
= fileName
[2:]
238 if not includePath
.endswith('/'):
243 inputFile
= open(fileName
)
247 if token
in ("#ifdef", "#ifndef", "#include",
248 "#endif", "#elif", "#else"):
250 elif token
== "#define":
253 if line
.startswith('('):
261 macros
[name
] = definition
262 elif token
== "enum":
265 elif token
in ('struct', 'union'):
266 lastStruct
= parseStruct()
267 elif match('OFP_ASSERT') or match('BOOST_STATIC_ASSERT'):
271 typeName
= parseTypeName()
272 if typeName
!= lastStruct
:
273 warn("checking size of %s but %s was most recently defined"
274 % (typeName
, lastStruct
))
282 if types
[typeName
]['size'] != size
:
283 warn("%s is %d bytes long but declared as %d" % (
284 typeName
, types
[typeName
]['size'], size
))
291 if __name__
== '__main__':