| 
									
										
										
										
											1996-11-27 19:52:01 +00:00
										 |  |  | #! /usr/bin/env python | 
					
						
							| 
									
										
										
										
											1992-03-02 16:20:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-10-03 16:45:35 +00:00
										 |  |  | # Read #define's and translate to Python code. | 
					
						
							|  |  |  | # Handle #include statements. | 
					
						
							|  |  |  | # Handle #define macros with one argument. | 
					
						
							|  |  |  | # Anything that isn't recognized or doesn't translate into valid | 
					
						
							|  |  |  | # Python is ignored. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Without filename arguments, acts as a filter. | 
					
						
							| 
									
										
										
										
											1994-05-03 14:37:30 +00:00
										 |  |  | # If one or more filenames are given, output is written to corresponding | 
					
						
							|  |  |  | # filenames in the local directory, translated to all uppercase, with | 
					
						
							|  |  |  | # the extension replaced by ".py". | 
					
						
							| 
									
										
										
										
											1994-10-03 16:45:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-05-17 09:05:54 +00:00
										 |  |  | # By passing one or more options of the form "-i regular_expression" | 
					
						
							|  |  |  | # you can specify additional strings to be ignored.  This is useful | 
					
						
							|  |  |  | # e.g. to ignore casts to u_long: simply specify "-i '(u_long)'". | 
					
						
							| 
									
										
										
										
											1992-03-02 16:20:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # XXX To do: | 
					
						
							|  |  |  | # - turn trailing C comments into Python comments | 
					
						
							|  |  |  | # - turn C Boolean operators "&& || !" into Python "and or not" | 
					
						
							|  |  |  | # - what to do about #if(def)? | 
					
						
							| 
									
										
										
										
											1994-10-03 16:45:35 +00:00
										 |  |  | # - what to do about macros with multiple parameters? | 
					
						
							| 
									
										
										
										
											1992-03-02 16:20:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-10-03 16:45:35 +00:00
										 |  |  | import sys, regex, regsub, string, getopt, os | 
					
						
							| 
									
										
										
										
											1992-03-02 16:20:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-08-22 23:12:23 +00:00
										 |  |  | p_define = regex.compile('^[\t ]*#[\t ]*define[\t ]+\([a-zA-Z0-9_]+\)[\t ]+') | 
					
						
							| 
									
										
										
										
											1992-03-02 16:20:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-10-03 16:45:35 +00:00
										 |  |  | p_macro = regex.compile( | 
					
						
							| 
									
										
										
										
											1996-08-22 23:12:23 +00:00
										 |  |  |   '^[\t ]*#[\t ]*define[\t ]+' | 
					
						
							|  |  |  |   '\([a-zA-Z0-9_]+\)(\([_a-zA-Z][_a-zA-Z0-9]*\))[\t ]+') | 
					
						
							| 
									
										
										
										
											1994-10-03 16:45:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-08-22 23:12:23 +00:00
										 |  |  | p_include = regex.compile('^[\t ]*#[\t ]*include[\t ]+<\([a-zA-Z0-9_/\.]+\)') | 
					
						
							| 
									
										
										
										
											1994-10-03 16:45:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-06-05 15:13:53 +00:00
										 |  |  | p_comment = regex.compile('/\*\([^*]+\|\*+[^/]\)*\(\*+/\)?') | 
					
						
							| 
									
										
										
										
											1997-08-14 20:14:29 +00:00
										 |  |  | p_cpp_comment = regex.compile('//.*') | 
					
						
							| 
									
										
										
										
											1992-03-02 16:20:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-08-14 20:14:29 +00:00
										 |  |  | ignores = [p_comment, p_cpp_comment] | 
					
						
							| 
									
										
										
										
											1994-05-17 09:05:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-10-03 16:45:35 +00:00
										 |  |  | p_char = regex.compile("'\(\\\\.[^\\\\]*\|[^\\\\]\)'") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | filedict = {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-01-17 17:01:40 +00:00
										 |  |  | try: | 
					
						
							|  |  |  | 	searchdirs=string.splitfields(os.environ['include'],';') | 
					
						
							|  |  |  | except KeyError: | 
					
						
							|  |  |  | 	try: | 
					
						
							|  |  |  | 		searchdirs=string.splitfields(os.environ['INCLUDE'],';') | 
					
						
							|  |  |  | 	except KeyError: | 
					
						
							| 
									
										
										
										
											1998-12-17 18:02:15 +00:00
										 |  |  | 		try: | 
					
						
							|  |  |  | 			if string.find( sys.platform, "beos" ) == 0: | 
					
						
							|  |  |  | 				searchdirs=string.splitfields(os.environ['BEINCLUDES'],';') | 
					
						
							|  |  |  | 			else: | 
					
						
							|  |  |  | 				raise KeyError | 
					
						
							|  |  |  | 		except KeyError: | 
					
						
							|  |  |  | 			searchdirs=['/usr/include'] | 
					
						
							| 
									
										
										
										
											1995-01-17 17:01:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-03-02 16:20:32 +00:00
										 |  |  | def main(): | 
					
						
							| 
									
										
										
										
											1997-08-14 20:14:29 +00:00
										 |  |  | 	global filedict | 
					
						
							| 
									
										
										
										
											1994-05-17 09:05:54 +00:00
										 |  |  | 	opts, args = getopt.getopt(sys.argv[1:], 'i:') | 
					
						
							|  |  |  | 	for o, a in opts: | 
					
						
							|  |  |  | 		if o == '-i': | 
					
						
							|  |  |  | 			ignores.append(regex.compile(a)) | 
					
						
							| 
									
										
										
										
											1994-05-03 14:37:30 +00:00
										 |  |  | 	if not args: | 
					
						
							|  |  |  | 		args = ['-'] | 
					
						
							|  |  |  | 	for filename in args: | 
					
						
							|  |  |  | 		if filename == '-': | 
					
						
							|  |  |  | 			sys.stdout.write('# Generated by h2py from stdin\n') | 
					
						
							|  |  |  | 			process(sys.stdin, sys.stdout) | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			fp = open(filename, 'r') | 
					
						
							|  |  |  | 			outfile = os.path.basename(filename) | 
					
						
							|  |  |  | 			i = string.rfind(outfile, '.') | 
					
						
							|  |  |  | 			if i > 0: outfile = outfile[:i] | 
					
						
							|  |  |  | 			outfile = string.upper(outfile) | 
					
						
							|  |  |  | 			outfile = outfile + '.py' | 
					
						
							|  |  |  | 			outfp = open(outfile, 'w') | 
					
						
							|  |  |  | 			outfp.write('# Generated by h2py from %s\n' % filename) | 
					
						
							| 
									
										
										
										
											1994-10-03 16:45:35 +00:00
										 |  |  | 			filedict = {} | 
					
						
							| 
									
										
										
										
											1995-01-17 17:01:40 +00:00
										 |  |  | 			for dir in searchdirs: | 
					
						
							|  |  |  | 				if filename[:len(dir)] == dir: | 
					
						
							|  |  |  | 					filedict[filename[len(dir)+1:]] = None	# no '/' trailing | 
					
						
							|  |  |  | 					break | 
					
						
							| 
									
										
										
										
											1994-05-03 14:37:30 +00:00
										 |  |  | 			process(fp, outfp) | 
					
						
							|  |  |  | 			outfp.close() | 
					
						
							|  |  |  | 			fp.close() | 
					
						
							| 
									
										
										
										
											1992-03-02 16:20:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-10-03 16:45:35 +00:00
										 |  |  | def process(fp, outfp, env = {}): | 
					
						
							| 
									
										
										
										
											1992-03-02 16:20:32 +00:00
										 |  |  | 	lineno = 0 | 
					
						
							|  |  |  | 	while 1: | 
					
						
							|  |  |  | 		line = fp.readline() | 
					
						
							|  |  |  | 		if not line: break | 
					
						
							|  |  |  | 		lineno = lineno + 1 | 
					
						
							| 
									
										
										
										
											1994-05-17 09:05:54 +00:00
										 |  |  | 		n = p_define.match(line) | 
					
						
							|  |  |  | 		if n >= 0: | 
					
						
							| 
									
										
										
										
											1994-10-03 16:45:35 +00:00
										 |  |  | 			# gobble up continuation lines | 
					
						
							|  |  |  | 			while line[-2:] == '\\\n': | 
					
						
							|  |  |  | 				nextline = fp.readline() | 
					
						
							|  |  |  | 				if not nextline: break | 
					
						
							|  |  |  | 				lineno = lineno + 1 | 
					
						
							|  |  |  | 				line = line + nextline | 
					
						
							| 
									
										
										
										
											1994-05-17 09:05:54 +00:00
										 |  |  | 			name = p_define.group(1) | 
					
						
							|  |  |  | 			body = line[n:] | 
					
						
							|  |  |  | 			# replace ignored patterns by spaces | 
					
						
							|  |  |  | 			for p in ignores: | 
					
						
							| 
									
										
										
										
											1994-10-03 16:45:35 +00:00
										 |  |  | 				body = regsub.gsub(p, ' ', body) | 
					
						
							|  |  |  | 			# replace char literals by ord(...) | 
					
						
							|  |  |  | 			body = regsub.gsub(p_char, 'ord(\\0)', body) | 
					
						
							| 
									
										
										
										
											1994-05-03 14:37:30 +00:00
										 |  |  | 			stmt = '%s = %s\n' % (name, string.strip(body)) | 
					
						
							|  |  |  | 			ok = 0 | 
					
						
							|  |  |  | 			try: | 
					
						
							|  |  |  | 				exec stmt in env | 
					
						
							|  |  |  | 			except: | 
					
						
							|  |  |  | 				sys.stderr.write('Skipping: %s' % stmt) | 
					
						
							| 
									
										
										
										
											1994-10-03 16:45:35 +00:00
										 |  |  | 			else: | 
					
						
							| 
									
										
										
										
											1994-05-03 14:37:30 +00:00
										 |  |  | 				outfp.write(stmt) | 
					
						
							| 
									
										
										
										
											1994-10-03 16:45:35 +00:00
										 |  |  | 		n =p_macro.match(line) | 
					
						
							|  |  |  | 		if n >= 0: | 
					
						
							|  |  |  | 			macro, arg = p_macro.group(1, 2) | 
					
						
							|  |  |  | 			body = line[n:] | 
					
						
							|  |  |  | 			for p in ignores: | 
					
						
							|  |  |  | 				body = regsub.gsub(p, ' ', body) | 
					
						
							|  |  |  | 			body = regsub.gsub(p_char, 'ord(\\0)', body) | 
					
						
							|  |  |  | 			stmt = 'def %s(%s): return %s\n' % (macro, arg, body) | 
					
						
							|  |  |  | 			try: | 
					
						
							|  |  |  | 				exec stmt in env | 
					
						
							|  |  |  | 			except: | 
					
						
							|  |  |  | 				sys.stderr.write('Skipping: %s' % stmt) | 
					
						
							|  |  |  | 			else: | 
					
						
							|  |  |  | 				outfp.write(stmt) | 
					
						
							|  |  |  | 		if p_include.match(line) >= 0: | 
					
						
							|  |  |  | 			regs = p_include.regs | 
					
						
							|  |  |  | 			a, b = regs[1] | 
					
						
							|  |  |  | 			filename = line[a:b] | 
					
						
							|  |  |  | 			if not filedict.has_key(filename): | 
					
						
							|  |  |  | 				filedict[filename] = None | 
					
						
							| 
									
										
										
										
											1995-01-17 17:01:40 +00:00
										 |  |  | 				inclfp = None | 
					
						
							|  |  |  | 				for dir in searchdirs: | 
					
						
							|  |  |  | 					try: | 
					
						
							|  |  |  | 						inclfp = open(dir + '/' + filename, 'r') | 
					
						
							|  |  |  | 						break | 
					
						
							|  |  |  | 					except IOError: | 
					
						
							|  |  |  | 						pass | 
					
						
							|  |  |  | 				if inclfp: | 
					
						
							|  |  |  | 					outfp.write( | 
					
						
							|  |  |  | 						'\n# Included from %s\n' % filename) | 
					
						
							|  |  |  | 					process(inclfp, outfp, env) | 
					
						
							|  |  |  | 				else: | 
					
						
							|  |  |  | 					sys.stderr.write('Warning - could not find file %s' % filename) | 
					
						
							| 
									
										
										
										
											1994-10-03 16:45:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-01-17 17:01:40 +00:00
										 |  |  | main() |