1#!/usr/bin/python
2
3import sys, re;
4from structs import unions, structs, defines;
5
6# command line arguments
7arch    = sys.argv[1];
8outfile = sys.argv[2];
9infiles = sys.argv[3:];
10
11
12###########################################################################
13# configuration #2: architecture information
14
15inttypes = {};
16header = {};
17footer = {};
18
19# x86_32
20inttypes["x86_32"] = {
21    "unsigned long" : "uint32_t",
22    "long"          : "uint32_t",
23    "xen_pfn_t"     : "uint32_t",
24};
25header["x86_32"] = """
26#define __i386___X86_32 1
27#pragma pack(4)
28""";
29footer["x86_32"] = """
30#pragma pack()
31""";
32
33# x86_64
34inttypes["x86_64"] = {
35    "unsigned long" : "__align8__ uint64_t",
36    "long"          : "__align8__ uint64_t",
37    "xen_pfn_t"     : "__align8__ uint64_t",
38};
39header["x86_64"] = """
40#ifdef __GNUC__
41# define __DECL_REG(name) union { uint64_t r ## name, e ## name; }
42# define __align8__ __attribute__((aligned (8)))
43#else
44# define __DECL_REG(name) uint64_t r ## name
45# define __align8__ FIXME
46#endif
47#define __x86_64___X86_64 1
48""";
49
50# ia64
51inttypes["ia64"] = {
52    "unsigned long" : "__align8__ uint64_t",
53    "long"          : "__align8__ uint64_t",
54    "xen_pfn_t"     : "__align8__ uint64_t",
55    "long double"   : "__align16__ ldouble_t",
56};
57header["ia64"] = """
58#define __align8__ __attribute__((aligned (8)))
59#define __align16__ __attribute__((aligned (16)))
60typedef unsigned char ldouble_t[16];
61""";
62
63
64###########################################################################
65# main
66
67input  = "";
68output = "";
69fileid = re.sub("[-.]", "_", "__FOREIGN_%s__" % outfile.upper());
70
71# read input header files
72for name in infiles:
73    f = open(name, "r");
74    input += f.read();
75    f.close();
76
77# add header
78output += """
79/*
80 * public xen defines and struct for %s
81 * generated by %s -- DO NOT EDIT
82 */
83
84#ifndef %s
85#define %s 1
86
87""" % (arch, sys.argv[0], fileid, fileid)
88
89if arch in header:
90    output += header[arch];
91    output += "\n";
92
93# add defines to output
94for line in re.findall("#define[^\n]+", input):
95    for define in defines:
96        regex = "#define\s+%s\\b" % define;
97        match = re.search(regex, line);
98        if None == match:
99            continue;
100        if define.upper()[0] == define[0]:
101            replace = define + "_" + arch.upper();
102        else:
103            replace = define + "_" + arch;
104        regex = "\\b%s\\b" % define;
105        output += re.sub(regex, replace, line) + "\n";
106output += "\n";
107
108# delete defines, comments, empty lines
109input = re.sub("#define[^\n]+\n", "", input);
110input = re.compile("/\*(.*?)\*/", re.S).sub("", input)
111input = re.compile("\n\s*\n", re.S).sub("\n", input);
112
113# add unions to output
114for union in unions:
115    regex = "union\s+%s\s*\{(.*?)\n\};" % union;
116    match = re.search(regex, input, re.S)
117    if None == match:
118        output += "#define %s_has_no_%s 1\n" % (arch, union);
119    else:
120        output += "union %s_%s {%s\n};\n" % (union, arch, match.group(1));
121    output += "\n";
122
123# add structs to output
124for struct in structs:
125    regex = "struct\s+%s\s*\{(.*?)\n\};" % struct;
126    match = re.search(regex, input, re.S)
127    if None == match:
128        output += "#define %s_has_no_%s 1\n" % (arch, struct);
129    else:
130        output += "struct %s_%s {%s\n};\n" % (struct, arch, match.group(1));
131        output += "typedef struct %s_%s %s_%s_t;\n" % (struct, arch, struct, arch);
132    output += "\n";
133
134# add footer
135if arch in footer:
136    output += footer[arch];
137    output += "\n";
138output += "#endif /* %s */\n" % fileid;
139
140# replace: defines
141for define in defines:
142    if define.upper()[0] == define[0]:
143        replace = define + "_" + arch.upper();
144    else:
145        replace = define + "_" + arch;
146    output = re.sub("\\b%s\\b" % define, replace, output);
147
148# replace: unions
149for union in unions:
150    output = re.sub("\\b(union\s+%s)\\b" % union, "\\1_%s" % arch, output);
151
152# replace: structs + struct typedefs
153for struct in structs:
154    output = re.sub("\\b(struct\s+%s)\\b" % struct, "\\1_%s" % arch, output);
155    output = re.sub("\\b(%s)_t\\b" % struct, "\\1_%s_t" % arch, output);
156
157# replace: integer types
158integers = list(inttypes[arch].keys());
159integers.sort(lambda a, b: cmp(len(b),len(a)));
160for type in integers:
161    output = re.sub("\\b%s\\b" % type, inttypes[arch][type], output);
162
163# print results
164f = open(outfile, "w");
165f.write(output);
166f.close;
167
168