]>
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": 1}
22 idRe
= "[a-zA-Z_][a-zA-Z_0-9]*"
23 tokenRe
= "#?" + idRe
+ "|[0-9]+|."
24 includeRe
= re
.compile(r
'\s*#include\s+<(openflow/[^#]+)>')
39 if line
.startswith("/*"):
43 commentEnd
= line
.find("*/")
48 line
= line
[commentEnd
+ 2:]
50 match
= re
.match(tokenRe
, line
)
51 token
= match
.group(0)
52 line
= line
[len(token
):]
53 if token
.startswith('#'):
55 elif token
in macros
and not inDirective
:
56 line
= macros
[token
] + line
66 line
= inputFile
.readline()
68 while line
.endswith("\\\n"):
69 line
= line
[:-2] + inputFile
.readline()
71 match
= includeRe
.match(line
)
73 inputStack
.append((fileName
, inputFile
, lineNumber
))
74 inputFile
= open(includePath
+ match
.group(1))
79 fileName
, inputFile
, lineNumber
= inputStack
.pop()
82 fatal("unexpected end of input")
88 sys
.stderr
.write("%s:%d: error at \"%s\": %s\n" % (fileName
, lineNumber
, token
, msg
))
94 sys
.stderr
.write("%s:%d: warning: %s\n" % (fileName
, lineNumber
, msg
))
102 return re
.match(idRe
+ "$", s
) != None
106 fatal("identifier expected")
109 if not re
.match('[0-9]+$', token
):
110 fatal("integer expected")
121 fatal("%s expected" % t
)
123 def parseTaggedName():
124 assert token
in ('struct', 'union')
128 name
= "%s %s" % (name
, token
)
133 if token
in ('struct', 'union'):
134 name
= parseTaggedName()
139 fatal("type name expected")
144 fatal("unknown type \"%s\"" % name
)
147 isStruct
= token
== 'struct'
148 structName
= parseTaggedName()
153 alignment
= 4 # ARM has minimum 32-bit alignment
155 while not match('}'):
156 typeName
= parseTypeName()
157 typeSize
= types
[typeName
]['size']
158 typeAlignment
= types
[typeName
]['alignment']
175 nBytes
= typeSize
* count
177 if ofs
% typeAlignment
:
178 shortage
= typeAlignment
- (ofs
% typeAlignment
)
179 warn("%s member %s is %d bytes short of %d-byte alignment"
180 % (structName
, memberName
, shortage
, typeAlignment
))
188 if typeAlignment
> alignment
:
189 alignment
= typeAlignment
193 shortage
= alignment
- (size
% alignment
)
194 if (structName
== "struct ofp10_packet_in" and
196 memberName
== 'data' and
198 # This is intentional
201 warn("%s needs %d bytes of tail padding" % (structName
, shortage
))
203 types
[structName
] = {"size": size
, "alignment": alignment
}
207 if len(sys
.argv
) < 2:
208 sys
.stderr
.write("at least one non-option argument required; "
209 "use --help for help")
212 if '--help' in sys
.argv
:
213 argv0
= os
.path
.basename(sys
.argv
[0])
215 %(argv0)s, for checking struct and struct member alignment
216 usage: %(argv0)s -Ipath HEADER [HEADER]...
218 This program reads the header files specified on the command line and
219 verifies that all struct members are aligned on natural boundaries
220 without any need for the compiler to add additional padding. It also
221 verifies that each struct's size is a multiple of 32 bits (because
222 some ABIs for ARM require all structs to be a multiple of 32 bits), or
223 64 bits if the struct has any 64-bit members, again without the
224 compiler adding additional padding. Finally, it checks struct size
225 assertions using OFP_ASSERT.
227 This program is specialized for reading Open vSwitch's OpenFlow header
228 files. It will not work on arbitrary header files without extensions.\
229 ''' % {"argv0": argv0
}
233 for fileName
in sys
.argv
[1:]:
234 if fileName
.startswith('-I'):
236 includePath
= fileName
[2:]
237 if not includePath
.endswith('/'):
242 inputFile
= open(fileName
)
246 if token
in ("#ifdef", "#ifndef", "#include",
247 "#endif", "#elif", "#else"):
249 elif token
== "#define":
252 if line
.startswith('('):
260 macros
[name
] = definition
261 elif token
== "enum":
264 elif token
in ('struct', 'union'):
265 lastStruct
= parseStruct()
266 elif match('OFP_ASSERT') or match('BOOST_STATIC_ASSERT'):
270 typeName
= parseTypeName()
271 if typeName
!= lastStruct
:
272 warn("checking size of %s but %s was most recently defined"
273 % (typeName
, lastStruct
))
281 if types
[typeName
]['size'] != size
:
282 warn("%s is %d bytes long but declared as %d" % (
283 typeName
, types
[typeName
]['size'], size
))
290 if __name__
== '__main__':