Setting tag sliver-openvswitch-2.2.90-1
[sliver-openvswitch.git] / build-aux / check-structs
index 545c80a..0428abf 100755 (executable)
@@ -1,5 +1,6 @@
 #! /usr/bin/python
 
+import os.path
 import sys
 import re
 
@@ -10,21 +11,27 @@ anyWarnings = False
 types = {}
 types['char'] = {"size": 1, "alignment": 1}
 types['uint8_t'] = {"size": 1, "alignment": 1}
-types['uint16_t'] = {"size": 2, "alignment": 2}
-types['uint32_t'] = {"size": 4, "alignment": 4}
-types['uint64_t'] = {"size": 8, "alignment": 8}
+types['ovs_be16'] = {"size": 2, "alignment": 2}
+types['ovs_be32'] = {"size": 4, "alignment": 4}
+types['ovs_be64'] = {"size": 8, "alignment": 8}
+types['ovs_32aligned_be64'] = {"size": 8, "alignment": 4}
 
 token = None
 line = ""
 idRe = "[a-zA-Z_][a-zA-Z_0-9]*"
 tokenRe = "#?" + idRe + "|[0-9]+|."
+includeRe = re.compile(r'\s*#include\s+"(openflow/[^#]+)"')
+includePath = ''
 inComment = False
 inDirective = False
+inputStack = []
 def getToken():
     global token
     global line
     global inComment
     global inDirective
+    global inputFile
+    global fileName
     while True:
         line = line.lstrip()
         if line != "":
@@ -54,16 +61,27 @@ def getToken():
             return True
         else:
             global lineNumber
-            line = inputFile.readline()
-            lineNumber += 1
-            while line.endswith("\\\n"):
-                line = line[:-2] + inputFile.readline()
+            while True:
+                line = inputFile.readline()
                 lineNumber += 1
-            if line == "":
-                if token == None:
-                    fatal("unexpected end of input")
-                token = None
-                return False
+                while line.endswith("\\\n"):
+                    line = line[:-2] + inputFile.readline()
+                    lineNumber += 1
+                match = includeRe.match(line)
+                if match:
+                    inputStack.append((fileName, inputFile, lineNumber))
+                    inputFile = open(includePath + match.group(1))
+                    lineNumber = 0
+                    continue
+                if line == "":
+                    if inputStack:
+                        fileName, inputFile, lineNumber = inputStack.pop()
+                        continue
+                    if token == None:
+                        fatal("unexpected end of input")
+                    token = None
+                    return False
+                break
     
 def fatal(msg):
     sys.stderr.write("%s:%d: error at \"%s\": %s\n" % (fileName, lineNumber, token, msg))
@@ -172,7 +190,7 @@ def parseStruct():
         forceMatch(';')
     if size % alignment:
         shortage = alignment - (size % alignment)
-        if (structName == "struct ofp_packet_in" and
+        if (structName == "struct ofp10_packet_in" and
             shortage == 2 and
             memberName == 'data' and
             count == 0):
@@ -182,6 +200,7 @@ def parseStruct():
             warn("%s needs %d bytes of tail padding" % (structName, shortage))
         size += shortage
     types[structName] = {"size": size, "alignment": alignment}
+    return structName
 
 def checkStructs():
     if len(sys.argv) < 2:
@@ -190,13 +209,10 @@ def checkStructs():
         sys.exit(1)
 
     if '--help' in sys.argv:
-        argv0 = sys.argv[0]
-        slash = argv0.rfind('/')
-        if slash:
-            argv0 = argv0[slash + 1:]
+        argv0 = os.path.basename(sys.argv[0])
         print '''\
 %(argv0)s, for checking struct and struct member alignment
-usage: %(argv0)s HEADER [HEADER]...
+usage: %(argv0)s -Ipath HEADER [HEADER]...
 
 This program reads the header files specified on the command line and
 verifies that all struct members are aligned on natural boundaries
@@ -207,20 +223,24 @@ some ABIs for ARM require all structs to be a multiple of 32 bits), or
 compiler adding additional padding.  Finally, it checks struct size
 assertions using OFP_ASSERT.
 
-Header files are read in the order specified.  #include directives are
-not processed, so specify them in dependency order.
-
-This program is specialized for reading include/openflow/openflow.h
-and include/openflow/nicira-ext.h.  It will not work on arbitrary
-header files without extensions.''' % {"argv0": argv0}
+This program is specialized for reading Open vSwitch's OpenFlow header
+files.  It will not work on arbitrary header files without extensions.\
+''' % {"argv0": argv0}
         sys.exit(0)
 
     global fileName
     for fileName in sys.argv[1:]:
+        if fileName.startswith('-I'):
+            global includePath
+            includePath = fileName[2:]
+            if not includePath.endswith('/'):
+                includePath += '/'
+            continue
         global inputFile
         global lineNumber
         inputFile = open(fileName)
         lineNumber = 0
+        lastStruct = None
         while getToken():
             if token in ("#ifdef", "#ifndef", "#include",
                          "#endif", "#elif", "#else"):
@@ -241,12 +261,15 @@ header files without extensions.''' % {"argv0": argv0}
                 while token != ';':
                     getToken()
             elif token in ('struct', 'union'):
-                parseStruct()
+                lastStruct = parseStruct()
             elif match('OFP_ASSERT') or match('BOOST_STATIC_ASSERT'):
                 forceMatch('(')
                 forceMatch('sizeof')
                 forceMatch('(')
                 typeName = parseTypeName()
+                if typeName != lastStruct:
+                    warn("checking size of %s but %s was most recently defined"
+                         % (typeName, lastStruct))
                 forceMatch(')')
                 forceMatch('=')
                 forceMatch('=')