Initial oftest skeleton with wrapper generators and pylibopenflow
diff --git a/tools/pylibopenflow/pylib/cheader.py b/tools/pylibopenflow/pylib/cheader.py
new file mode 100644
index 0000000..a23e1eb
--- /dev/null
+++ b/tools/pylibopenflow/pylib/cheader.py
@@ -0,0 +1,434 @@
+"""This module parse and store a C/C++ header file.
+
+Date June 2009
+Created by ykk
+"""
+import re
+from config import *
+
+class textfile:
+ """Class to handle text file.
+
+ Date June 2009
+ Created by ykk
+ """
+ def __init__(self, filename):
+ """Initialize filename with no content.
+ """
+ ##Filename
+ if (isinstance(filename, str)):
+ self.filename = []
+ self.filename.append(filename)
+ else:
+ self.filename = filename
+ ##Content
+ self.content = []
+
+ def read(self):
+ """Read file
+ """
+ for filename in self.filename:
+ fileRef = open(filename, "r")
+ for line in fileRef:
+ self.content.append(line)
+ fileRef.close()
+
+class ctype:
+ """Class to represent types in C
+ """
+ def __init__(self,typename, name=None, expanded=False):
+ """Initialize
+ """
+ ##Name
+ self.name = name
+ ##Type of primitive
+ self.typename = typename
+ ##Expanded
+ self.expanded = expanded
+
+ def expand(self, cheader):
+ """Expand type if applicable
+ """
+ raise NotImplementedError()
+
+ def get_names(self):
+ """Return name of variables
+ """
+ raise NotImplementedError()
+
+class cprimitive(ctype):
+ """Class to represent C primitive
+
+ Date October 2009
+ Created by ykk
+ """
+ def __init__(self,typename, name=None):
+ """Initialize and store primitive
+ """
+ ctype.__init__(self, typename, name, True)
+
+ def __str__(self):
+ """Return string representation
+ """
+ if (self.name == None):
+ return self.typename
+ else:
+ return self.typename+" "+str(self.name)
+
+ def expand(self, cheader):
+ """Expand type if applicable
+ """
+ pass
+
+ def get_names(self):
+ """Return name of variables
+ """
+ namelist = []
+ namelist.append(self.name)
+ return namelist
+
+class cstruct(ctype):
+ """Class to represent C struct
+
+ Date October 2009
+ Created by ykk
+ """
+ def __init__(self, typename, name=None):
+ """Initialize struct
+ """
+ ctype.__init__(self, typename, name)
+ ##List of members in struct
+ self.members = []
+
+ def __str__(self):
+ """Return string representation
+ """
+ string = "struct "+self.typename
+ if (self.name != None):
+ string += " "+self.name
+ if (len(self.members) == 0):
+ return string
+ #Add members
+ string +=" {\n"
+ for member in self.members:
+ string += "\t"+str(member)
+ if (not isinstance(member, cstruct)):
+ string += ";"
+ string += "\n"
+ string +="};"
+ return string
+
+ def expand(self, cheader):
+ """Expand struct
+ """
+ self.expanded = True
+ #Expanded each member
+ for member in self.members:
+ if (isinstance(member, cstruct) and
+ (not member.expanded)):
+ try:
+ if (not cheader.structs[member.typename].expanded):
+ cheader.structs[member.typename].expand(cheader)
+ member.members=cheader.structs[member.typename].members[:]
+ member.expanded = True
+ except KeyError:
+ self.expanded=False
+ else:
+ member.expand(cheader)
+
+ def get_names(self):
+ """Return name of variables
+ """
+ namelist = []
+ for member in self.members:
+ if (isinstance(member, cstruct)):
+ tmplist = member.get_names()
+ for item in tmplist:
+ namelist.append(member.name+"."+item)
+ else:
+ namelist.extend(member.get_names())
+ return namelist
+
+
+class carray(ctype):
+ """Class to represent C array
+
+ Date October 2009
+ Created by ykk
+ """
+ def __init__(self, typename, name, isPrimitive, size):
+ """Initialize array of object.
+ """
+ ctype.__init__(self, typename, name,
+ (isinstance(size, int) and isPrimitive))
+ ##Object reference
+ if (isPrimitive):
+ self.object = cprimitive(typename, name)
+ else:
+ self.object = cstruct(typename, name)
+ ##Size of array
+ self.size = size
+
+ def __str__(self):
+ """Return string representation
+ """
+ return str(self.object)+"["+str(self.size)+"]"
+
+ def expand(self, cheader):
+ """Expand array
+ """
+ self.expanded = True
+ if (not self.object.expanded):
+ if (isinstance(self.object, cstruct)):
+ cheader.structs[self.object.typename].expand(cheader)
+ self.object.members=cheader.structs[self.object.typename].members[:]
+ else:
+ self.object.expand(cheader)
+
+ if (not isinstance(self.size, int)):
+ val = cheader.get_value(self.size)
+ if (val == None):
+ self.expanded = False
+ else:
+ try:
+ self.size = int(val)
+ except ValueError:
+ self.size = val
+ self.expanded = False
+
+ def get_names(self):
+ """Return name of variables
+ """
+ namelist = []
+ for i in range(0,self.size):
+ namelist.append(self.object.name)
+ return namelist
+
+class ctype_parser:
+ """Class to check c types
+
+ Date October 2009
+ Created by ykk
+ """
+ def __init__(self):
+ """Initialize
+ """
+ self.CPrimitives = ["char","signed char","unsigned char",
+ "short","unsigned short",
+ "int","unsigned int",
+ "long","unsigned long",
+ "long long","unsigned long long",
+ "float","double",
+ "uint8_t","uint16_t","uint32_t","uint64_t"]
+
+ def is_primitive(self,type):
+ """Check type given is primitive.
+
+ Return true if valid, and false otherwise
+ """
+ if (type in self.CPrimitives):
+ return True
+ else:
+ return False
+
+ def is_array(self, string):
+ """Check if string declares an array
+ """
+ parts=string.strip().split()
+ if (len(parts) <= 1):
+ return False
+ else:
+ pattern = re.compile("\[.*?\]", re.MULTILINE)
+ values = pattern.findall(string)
+ if (len(values) == 1):
+ return True
+ else:
+ return False
+
+ def parse_array(self, string):
+ """Parse array from string.
+ Return occurrence and name.
+ """
+ pattern = re.compile("\[.*?\]", re.MULTILINE)
+ namepattern = re.compile(".*?\[", re.MULTILINE)
+ values = pattern.findall(string)
+ if (len(values) != 1):
+ return (1,string)
+ else:
+ val = values[0][1:-1]
+ try:
+ sizeval = int(val)
+ except ValueError:
+ if (val==""):
+ sizeval = 0
+ else:
+ sizeval = val
+ return (sizeval,
+ namepattern.findall(string)[0].strip()[0:-1])
+
+ def parse_type(self, string):
+ """Parse string and return cstruct or cprimitive.
+ Else return None
+ """
+ parts=string.strip().split()
+ if (len(parts) >= 2):
+ if (parts[0].strip() == "struct"):
+ typename = " ".join(parts[1:-1])
+ else:
+ typename = " ".join(parts[:-1])
+ (size, name) = self.parse_array(parts[-1])
+ if IGNORE_ZERO_ARRAYS and size == 0:
+ return None
+ #Create appropriate type
+ if (size != 1):
+ #Array
+ return carray(typename, name,
+ self.is_primitive(typename),size)
+ else:
+ #Not array
+ if IGNORE_OFP_HEADER and typename == "ofp_header":
+ return None
+ if (self.is_primitive(typename)):
+ return cprimitive(typename, name)
+ else:
+ return cstruct(typename, name)
+ else:
+ return None
+
+class cheaderfile(textfile):
+ """Class to handle C header file.
+
+ Date June 2009
+ Created by ykk
+ """
+ def __init__(self, filename):
+ """Initialize filename and read from file
+ """
+ textfile.__init__(self,filename)
+ self.read()
+ self.__remove_comments()
+ ##Dictionary of macros
+ self.macros = {}
+ self.__get_macros()
+ ##Dictionary of enumerations
+ self.enums = {}
+ self.enum_values = {}
+ self.__get_enum()
+ self.__get_enum_values()
+ ##Dictionary of structs
+ self.structs = {}
+ self.__get_struct()
+
+ def get_enum_name(self, enum, value):
+ """Return name of variable in enum
+ """
+ for e in self.enums[enum]:
+ if (self.enum_values[e] == value):
+ return e
+
+ def eval_value(self, value):
+ """Evaluate value string
+ """
+ try:
+ return eval(value, self.enum_values)
+ except:
+ return value.strip()
+
+ def get_value(self, name):
+ """Get value for variable name,
+ searching through enum and macros.
+ Else return None
+ """
+ try:
+ return self.enum_values[name]
+ except KeyError:
+ try:
+ return self.macros[name]
+ except KeyError:
+ return None
+
+ def __remove_comments(self):
+ """Remove all comments
+ """
+ fileStr = "".join(self.content)
+ pattern = re.compile("\\\.*?\n", re.MULTILINE)
+ fileStr = pattern.sub("",fileStr)
+ pattern = re.compile(r"/\*.*?\*/", re.MULTILINE|re.DOTALL)
+ fileStr = pattern.sub("",fileStr)
+ pattern = re.compile("//.*$", re.MULTILINE)
+ fileStr = pattern.sub("",fileStr)
+ self.content = fileStr.split('\n')
+
+ def __get_struct(self):
+ """Get all structs
+ """
+ typeparser = ctype_parser()
+ fileStr = "".join(self.content)
+ #Remove attribute
+ attrpattern = re.compile("} __attribute__ \(\((.+?)\)\);", re.MULTILINE)
+ attrmatches = attrpattern.findall(fileStr)
+ for amatch in attrmatches:
+ fileStr=fileStr.replace(" __attribute__ (("+amatch+"));",";")
+ #Find all structs
+ pattern = re.compile("struct[\w\s]*?{.*?};", re.MULTILINE)
+ matches = pattern.findall(fileStr)
+ #Process each struct
+ namepattern = re.compile("struct(.+?)[ {]", re.MULTILINE)
+ pattern = re.compile("{(.+?)};", re.MULTILINE)
+ for match in matches:
+ structname = namepattern.findall(match)[0].strip()
+ if (len(structname) != 0):
+ values = pattern.findall(match)[0].strip().split(";")
+ cstru = cstruct(structname)
+ for val in values:
+ presult = typeparser.parse_type(val)
+ if (presult != None):
+ cstru.members.append(presult)
+ self.structs[structname] = cstru
+ #Expand all structs
+ for (structname, struct) in self.structs.items():
+ struct.expand(self)
+
+ def __get_enum(self):
+ """Get all enumeration
+ """
+ fileStr = "".join(self.content)
+ #Find all enumerations
+ pattern = re.compile("enum[\w\s]*?{.*?}", re.MULTILINE)
+ matches = pattern.findall(fileStr)
+ #Process each enumeration
+ namepattern = re.compile("enum(.+?){", re.MULTILINE)
+ pattern = re.compile("{(.+?)}", re.MULTILINE)
+ for match in matches:
+ values = pattern.findall(match)[0].strip().split(",")
+ #Process each value in enumeration
+ enumList = []
+ value = 0
+ for val in values:
+ if not (val.strip() == ""):
+ valList=val.strip().split("=")
+ enumList.append(valList[0].strip())
+ if (len(valList) == 1):
+ self.enum_values[valList[0].strip()] = value
+ value += 1
+ else:
+ self.enum_values[valList[0].strip()] = self.eval_value(valList[1].strip())
+ self.enums[namepattern.findall(match)[0].strip()] = enumList
+
+ def __get_enum_values(self):
+ """Patch unresolved enum values
+ """
+ for name,enumval in self.enum_values.items():
+ if isinstance(enumval,str):
+ self.enum_values[name] = self.eval_value(enumval)
+
+ def __get_macros(self):
+ """Extract macros
+ """
+ for line in self.content:
+ if (line[0:8] == "#define "):
+ lineList = line[8:].split()
+ if (len(lineList) >= 2):
+ self.macros[lineList[0]] = self.eval_value("".join(lineList[1:]))
+ else:
+ self.macros[lineList[0]] = ""