view CbC-scripts/make_headers.py2 @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents f9b1a53df341
children
line wrap: on
line source

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import re
import getopt

reserved_words = [ "if", "for", "switch", "return", "while", "else", ]

PATTERN = r"([a-zA-Z_][\w\s]*\**)\s([a-zA-Z_]\w*)\s*\(([^\{/;]*)\)\s*\{"
#PATTERN = r"([a-zA-Z_]\w*)\s+([a-zA-Z_]\w*)\s*\(([^;]*)\)\s*\{"
#PATTERN = r"((?:[a-zA-Z_]\w*)\s+)+?([a-zA-Z_]\w*)\s*\(([^;]*)\)\s*\{"
# TODO: 関数パラメータ内にコメントがあると正しく動かない!
PROG = re.compile(PATTERN, re.S)

omit_static=False
add_extern=""

def truncate_comments(data):
	pass

def check_reserved_word(decl):
	""" return true if decl's type and name is not reserved word. """

	if decl["name"] in reserved_words or decl["type"] in reserved_words:
		return False
	return True

def read_decls(file):
	declarators = []

	# open the file and read all lines into a string.
	try:
		fo = open(file, 'r')
		lines = fo.readlines()
		data = "".join(lines)
		truncate_comments(data)
	except IOError:
		print "cannot read file %s" % file
		return None

	# find all matched strings.
	# moiter is iterator of MatchObject.
	moiter = PROG.finditer(data)
	for mo in moiter:
		tmp = { "type": mo.group(1),
				"name": mo.group(2),
				"parms": mo.group(3),
				"offset": mo.start() }
		if check_reserved_word(tmp):
			declarators.append(tmp)

	return declarators

def debug_print(decl):
	for (key,value) in decl.items():
		if isinstance(value, str):
			decl[key] = value.replace("\n"," ").replace("\t"," ")

	print "Type:\t%s" % decl["type"]
	print "Name:\t%s" % decl["name"]
	print "Params:\t%s" % decl["parms"]
	print "offset:\t%d" % decl["offset"]
	print ""
	#s = "%s %s ( %s );" % (decl["type"], decl["name"], decl["parms"])
	#print s, "/* offset: %d */" % decl["offset"]

def format_print(decl, file):
	for (key,value) in decl.items():
		if isinstance(value, str):
			decl[key] = value.replace("\n"," ").replace("\t"," ")

	print "/* defined in file %s at offset %d  */" % (file,decl["offset"])
	print "%s%s %s (%s);" % (add_extern, decl["type"],decl["name"],decl["parms"])
	print ""

def getoptions():
	global omit_static, add_extern

	try:
		opts, args = getopt.getopt(sys.argv[1:], 'se', [ 'omit-static', 'add-extern' ])
	except getopt.GetoptError:
		print(err)
		usage()
		sys.exit(2)

	for opt,a in opts:
		if opt in ("-s", "--omit-static"):
			omit_static=True
		elif opt in ("-e", "--add-extern"):
			add_extern="extern "
		else:
			print("unhandled option {0}".format(opt))
			usage()
	
	return args

def usage():
	print( """\
Usage: {0:s} OPION... [FILE]...
OPTIONS:
	-s, --omit-static	omit static functions
	-e, --add-extern	add extern to all function declarations
	""".format(sys.argv[0]))

def main():
	# option handling.
	args = getoptions()

	for file in args:
		# read function declaration from each file.
		decls = read_decls(file)
		if decls==None or len(decls)==0:
			# no function found.
			print "%s have no function definition!" % file
			continue

		for decl in decls:
			if omit_static and 0 <= decl["type"].find("static"):
				# static function is ignored.
				continue
			#debug_print(decl)
			format_print(decl, file)

main()