Files
xen/tools/include/xen-foreign/mkheader.py
T
Andrew Cooper a9047a722b tools/xen-foreign: Update python scripts to be Py3 compatible
The issues are:
 * dict.has_key() was completely removed in Py3
 * dict.keys() is an iterable rather than list in Py3, so .sort() doesn't work.
 * list.sort(cmp=) was deprecated in Py2.4 and removed in Py3.

The has_key() issue is trivially fixed by switching to using the in keyword.
The sorting issue could be trivially fixed, but take the opportunity to
improve the code.

The reason for the sorting is to ensure that "unsigned long" gets replaced
before "long", and the only reason sorting is necessary is because
inttypes[arch] is needlessly a dictionary.  Update inttypes[arch] to be a list
of tuples rather than a dictionary, and process them in list order.

Reported-by: George Dunlap <george.dunlap@eu.citrix.com>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
2019-03-12 12:57:21 +00:00

216 lines
5.6 KiB
Python

#!/usr/bin/python
import sys, re;
from structs import unions, structs, defines;
# command line arguments
arch = sys.argv[1];
outfile = sys.argv[2];
infiles = sys.argv[3:];
###########################################################################
# configuration #2: architecture information
inttypes = {};
header = {};
footer = {};
#arm
inttypes["arm32"] = [
("unsigned long", "__danger_unsigned_long_on_arm32"),
("long", "__danger_long_on_arm32"),
("xen_pfn_t", "uint64_t"),
("xen_ulong_t", "uint64_t"),
("uint64_t", "__align8__ uint64_t"),
]
header["arm32"] = """
#define __arm___ARM32 1
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
# define __DECL_REG(n64, n32) union { uint64_t n64; uint32_t n32; }
# define __align8__ __attribute__((aligned (8)))
#else
# define __DECL_REG(n64, n32) uint64_t n64
# define __align8__ FIXME
#endif
""";
footer["arm32"] = """
#undef __DECL_REG
"""
inttypes["arm64"] = [
("unsigned long", "__danger_unsigned_long_on_arm64"),
("long", "__danger_long_on_arm64"),
("xen_pfn_t", "uint64_t"),
("xen_ulong_t", "uint64_t"),
("uint64_t", "__align8__ uint64_t"),
]
header["arm64"] = """
#define __aarch64___ARM64 1
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
# define __DECL_REG(n64, n32) union { uint64_t n64; uint32_t n32; }
# define __align8__ __attribute__((aligned (8)))
#else
# define __DECL_REG(n64, n32) uint64_t n64
# define __align8__ FIXME
#endif
""";
footer["arm64"] = """
#undef __DECL_REG
"""
# x86_32
inttypes["x86_32"] = [
("unsigned long", "uint32_t"),
("long", "uint32_t"),
("xen_pfn_t", "uint32_t"),
("xen_ulong_t", "uint32_t"),
]
header["x86_32"] = """
#define __DECL_REG_LO8(which) uint32_t e ## which ## x
#define __DECL_REG_LO16(name) uint32_t e ## name
#define __i386___X86_32 1
#pragma pack(4)
""";
footer["x86_32"] = """
#undef __DECL_REG_LO8
#undef __DECL_REG_LO16
#pragma pack()
""";
# x86_64
inttypes["x86_64"] = [
("unsigned long", "__align8__ uint64_t"),
("long", "__align8__ uint64_t"),
("xen_pfn_t", "__align8__ uint64_t"),
("xen_ulong_t", "__align8__ uint64_t"),
]
header["x86_64"] = """
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
# define __DECL_REG(name) union { uint64_t r ## name, e ## name; }
# define __align8__ __attribute__((aligned (8)))
#else
# define __DECL_REG(name) uint64_t r ## name
# define __align8__ FIXME
#endif
#define __DECL_REG_LOHI(name) __DECL_REG(name ## x)
#define __DECL_REG_LO8 __DECL_REG
#define __DECL_REG_LO16 __DECL_REG
#define __DECL_REG_HI __DECL_REG
#define __x86_64___X86_64 1
""";
footer["x86_64"] = """
#undef __DECL_REG
#undef __DECL_REG_LOHI
#undef __DECL_REG_LO8
#undef __DECL_REG_LO16
#undef __DECL_REG_HI
"""
###########################################################################
# main
input = "";
output = "";
fileid = re.sub("[-.]", "_", "__FOREIGN_%s__" % outfile.upper());
# read input header files
for name in infiles:
f = open(name, "r");
input += f.read();
f.close();
# add header
output += """
/*
* public xen defines and struct for %s
* generated by %s -- DO NOT EDIT
*/
#ifndef %s
#define %s 1
""" % (arch, sys.argv[0], fileid, fileid)
if arch in header:
output += header[arch];
output += "\n";
defined = {}
# add defines to output
for line in re.findall("#define[^\n]+", input):
for define in defines:
regex = "#define\s+%s\\b" % define;
match = re.search(regex, line);
if None == match:
continue;
defined[define] = 1
if define.upper()[0] == define[0]:
replace = define + "_" + arch.upper();
else:
replace = define + "_" + arch;
regex = "\\b%s\\b" % define;
output += re.sub(regex, replace, line) + "\n";
output += "\n";
# delete defines, comments, empty lines
input = re.sub("#define[^\n]+\n", "", input);
input = re.compile("/\*(.*?)\*/", re.S).sub("", input)
input = re.compile("\n\s*\n", re.S).sub("\n", input);
# add unions to output
for union in unions:
regex = "union\s+%s\s*\{(.*?)\n\};" % union;
match = re.search(regex, input, re.S)
if None == match:
output += "#define %s_has_no_%s 1\n" % (arch, union);
else:
output += "union %s_%s {%s\n};\n" % (union, arch, match.group(1));
output += "\n";
# add structs to output
for struct in structs:
regex = "(?:#ifdef ([A-Z_]+))?\nstruct\s+%s\s*\{(.*?)\n\};" % struct;
match = re.search(regex, input, re.S)
if None == match or \
(match.group(1) is not None and match.group(1) not in defined):
output += "#define %s_has_no_%s 1\n" % (arch, struct);
else:
output += "struct %s_%s {%s\n};\n" % (struct, arch, match.group(2));
output += "typedef struct %s_%s %s_%s_t;\n" % (struct, arch, struct, arch);
output += "\n";
# add footer
if arch in footer:
output += footer[arch];
output += "\n";
output += "#endif /* %s */\n" % fileid;
# replace: defines
for define in defines:
if define.upper()[0] == define[0]:
replace = define + "_" + arch.upper();
else:
replace = define + "_" + arch;
output = re.sub("\\b%s\\b" % define, replace, output);
# replace: unions
for union in unions:
output = re.sub("\\b(union\s+%s)\\b" % union, "\\1_%s" % arch, output);
# replace: structs + struct typedefs
for struct in structs:
output = re.sub("\\b(struct\s+%s)\\b" % struct, "\\1_%s" % arch, output);
output = re.sub("\\b(%s)_t\\b" % struct, "\\1_%s_t" % arch, output);
# replace: integer types
for old, new in inttypes[arch]:
output = re.sub("\\b%s\\b" % old, new, output)
# print results
f = open(outfile, "w");
f.write(output);
f.close;