| #/usr/bin/env python | |
| """This script transforms the structs inside the kernel ABI headers into a define | |
| of an anonymous struct. | |
| eg | |
| struct abc {int foo;}; | |
| becomes | |
| #define _STRUCT_abc struct {int foo;}; | |
| This allows the exact same struct to be included in the provider wrapper struct: | |
| struct abc_resp { | |
| struct ibv_abc ibv_resp; | |
| _STRUCT_abc; | |
| }; | |
| Which duplicates the struct layout and naming we have historically used, but | |
| sources the data directly from the kernel headers instead of manually copying.""" | |
| import re; | |
| import functools; | |
| import sys; | |
| def in_struct(ln,FO,nesting=0): | |
| """Copy a top level structure over to the #define output, keeping track of | |
| nested structures.""" | |
| if nesting == 0: | |
| if re.match(r"(}.*);",ln): | |
| FO.write(ln[:-1] + "\n\n"); | |
| return find_struct; | |
| FO.write(ln + " \\\n"); | |
| if ln == "struct {" or ln == "union {": | |
| return functools.partial(in_struct,nesting=nesting+1); | |
| if re.match(r"}.*;",ln): | |
| return functools.partial(in_struct,nesting=nesting-1); | |
| return functools.partial(in_struct,nesting=nesting); | |
| def find_struct(ln,FO): | |
| """Look for the start of a top level structure""" | |
| if ln.startswith("struct ") or ln.startswith("union "): | |
| g = re.match(r"(struct|union)\s+(\S+)\s+{",ln); | |
| FO.write("#define _STRUCT_%s %s { \\\n"%(g.group(2),g.group(1))); | |
| return in_struct; | |
| return find_struct; | |
| with open(sys.argv[1]) as FI: | |
| with open(sys.argv[2],"w") as FO: | |
| state = find_struct; | |
| for ln in FI: | |
| # Drop obvious comments | |
| ln = ln.strip(); | |
| ln = re.sub(r"/\*.*\*/","",ln); | |
| ln = re.sub(r"//.*$","",ln); | |
| state = state(ln,FO); |