]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Python-2.7.2/Tools/scripts/h2py.py
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Tools / scripts / h2py.py
CommitLineData
4710c53d 1#! /usr/bin/env python\r
2\r
3# Read #define's and translate to Python code.\r
4# Handle #include statements.\r
5# Handle #define macros with one argument.\r
6# Anything that isn't recognized or doesn't translate into valid\r
7# Python is ignored.\r
8\r
9# Without filename arguments, acts as a filter.\r
10# If one or more filenames are given, output is written to corresponding\r
11# filenames in the local directory, translated to all uppercase, with\r
12# the extension replaced by ".py".\r
13\r
14# By passing one or more options of the form "-i regular_expression"\r
15# you can specify additional strings to be ignored. This is useful\r
16# e.g. to ignore casts to u_long: simply specify "-i '(u_long)'".\r
17\r
18# XXX To do:\r
19# - turn trailing C comments into Python comments\r
20# - turn C Boolean operators "&& || !" into Python "and or not"\r
21# - what to do about #if(def)?\r
22# - what to do about macros with multiple parameters?\r
23\r
24import sys, re, getopt, os\r
25\r
26p_define = re.compile('^[\t ]*#[\t ]*define[\t ]+([a-zA-Z0-9_]+)[\t ]+')\r
27\r
28p_macro = re.compile(\r
29 '^[\t ]*#[\t ]*define[\t ]+'\r
30 '([a-zA-Z0-9_]+)\(([_a-zA-Z][_a-zA-Z0-9]*)\)[\t ]+')\r
31\r
32p_include = re.compile('^[\t ]*#[\t ]*include[\t ]+<([a-zA-Z0-9_/\.]+)')\r
33\r
34p_comment = re.compile(r'/\*([^*]+|\*+[^/])*(\*+/)?')\r
35p_cpp_comment = re.compile('//.*')\r
36\r
37ignores = [p_comment, p_cpp_comment]\r
38\r
39p_char = re.compile(r"'(\\.[^\\]*|[^\\])'")\r
40\r
41p_hex = re.compile(r"0x([0-9a-fA-F]+)L?")\r
42\r
43filedict = {}\r
44importable = {}\r
45\r
46try:\r
47 searchdirs=os.environ['include'].split(';')\r
48except KeyError:\r
49 try:\r
50 searchdirs=os.environ['INCLUDE'].split(';')\r
51 except KeyError:\r
52 try:\r
53 if sys.platform.find("beos") == 0:\r
54 searchdirs=os.environ['BEINCLUDES'].split(';')\r
55 elif sys.platform.startswith("atheos"):\r
56 searchdirs=os.environ['C_INCLUDE_PATH'].split(':')\r
57 else:\r
58 raise KeyError\r
59 except KeyError:\r
60 searchdirs=['/usr/include']\r
61\r
62def main():\r
63 global filedict\r
64 opts, args = getopt.getopt(sys.argv[1:], 'i:')\r
65 for o, a in opts:\r
66 if o == '-i':\r
67 ignores.append(re.compile(a))\r
68 if not args:\r
69 args = ['-']\r
70 for filename in args:\r
71 if filename == '-':\r
72 sys.stdout.write('# Generated by h2py from stdin\n')\r
73 process(sys.stdin, sys.stdout)\r
74 else:\r
75 fp = open(filename, 'r')\r
76 outfile = os.path.basename(filename)\r
77 i = outfile.rfind('.')\r
78 if i > 0: outfile = outfile[:i]\r
79 modname = outfile.upper()\r
80 outfile = modname + '.py'\r
81 outfp = open(outfile, 'w')\r
82 outfp.write('# Generated by h2py from %s\n' % filename)\r
83 filedict = {}\r
84 for dir in searchdirs:\r
85 if filename[:len(dir)] == dir:\r
86 filedict[filename[len(dir)+1:]] = None # no '/' trailing\r
87 importable[filename[len(dir)+1:]] = modname\r
88 break\r
89 process(fp, outfp)\r
90 outfp.close()\r
91 fp.close()\r
92\r
93def pytify(body):\r
94 # replace ignored patterns by spaces\r
95 for p in ignores:\r
96 body = p.sub(' ', body)\r
97 # replace char literals by ord(...)\r
98 body = p_char.sub("ord('\\1')", body)\r
99 # Compute negative hexadecimal constants\r
100 start = 0\r
101 UMAX = 2*(sys.maxint+1)\r
102 while 1:\r
103 m = p_hex.search(body, start)\r
104 if not m: break\r
105 s,e = m.span()\r
106 val = long(body[slice(*m.span(1))], 16)\r
107 if val > sys.maxint:\r
108 val -= UMAX\r
109 body = body[:s] + "(" + str(val) + ")" + body[e:]\r
110 start = s + 1\r
111 return body\r
112\r
113def process(fp, outfp, env = {}):\r
114 lineno = 0\r
115 while 1:\r
116 line = fp.readline()\r
117 if not line: break\r
118 lineno = lineno + 1\r
119 match = p_define.match(line)\r
120 if match:\r
121 # gobble up continuation lines\r
122 while line[-2:] == '\\\n':\r
123 nextline = fp.readline()\r
124 if not nextline: break\r
125 lineno = lineno + 1\r
126 line = line + nextline\r
127 name = match.group(1)\r
128 body = line[match.end():]\r
129 body = pytify(body)\r
130 ok = 0\r
131 stmt = '%s = %s\n' % (name, body.strip())\r
132 try:\r
133 exec stmt in env\r
134 except:\r
135 sys.stderr.write('Skipping: %s' % stmt)\r
136 else:\r
137 outfp.write(stmt)\r
138 match = p_macro.match(line)\r
139 if match:\r
140 macro, arg = match.group(1, 2)\r
141 body = line[match.end():]\r
142 body = pytify(body)\r
143 stmt = 'def %s(%s): return %s\n' % (macro, arg, body)\r
144 try:\r
145 exec stmt in env\r
146 except:\r
147 sys.stderr.write('Skipping: %s' % stmt)\r
148 else:\r
149 outfp.write(stmt)\r
150 match = p_include.match(line)\r
151 if match:\r
152 regs = match.regs\r
153 a, b = regs[1]\r
154 filename = line[a:b]\r
155 if importable.has_key(filename):\r
156 outfp.write('from %s import *\n' % importable[filename])\r
157 elif not filedict.has_key(filename):\r
158 filedict[filename] = None\r
159 inclfp = None\r
160 for dir in searchdirs:\r
161 try:\r
162 inclfp = open(dir + '/' + filename)\r
163 break\r
164 except IOError:\r
165 pass\r
166 if inclfp:\r
167 outfp.write(\r
168 '\n# Included from %s\n' % filename)\r
169 process(inclfp, outfp, env)\r
170 else:\r
171 sys.stderr.write('Warning - could not find file %s\n' %\r
172 filename)\r
173\r
174if __name__ == '__main__':\r
175 main()\r