26
|
1 #!/usr/bin/env python3.0
|
|
2
|
|
3 import sys
|
|
4 import re
|
|
5 import getopt
|
|
6
|
|
7 reserved_words = [ "if", "for", "switch", "return", "while", "else", ]
|
|
8
|
|
9 PATTERN = "([a-zA-Z_][\w\s]*\**)\s([a-zA-Z_]\w*)\s*\(([^{/;]*)\)\s*\{"
|
|
10 # TODO: 関数パラメータ内にコメントがあると正しく動かない!
|
|
11 # TODO: int * const * とか大丈夫?
|
|
12 PROG = re.compile(PATTERN, re.S)
|
|
13
|
|
14 omit_static=False
|
|
15 add_extern=""
|
|
16
|
|
17 def truncate_comments(data):
|
|
18 pass
|
|
19
|
|
20 def check_reserved_word(decl):
|
|
21 """ return true if decl's type and name is not reserved word. """
|
|
22
|
|
23 if decl["name"] in reserved_words or decl["type"] in reserved_words:
|
|
24 return False
|
|
25 return True
|
|
26
|
|
27 def read_decls(file):
|
|
28 declarators = []
|
|
29
|
|
30 # open the file and read all lines into a string.
|
|
31 try:
|
|
32 fo = open(file, 'r')
|
|
33 lines = fo.readlines()
|
|
34 data = "".join(lines)
|
|
35 truncate_comments(data)
|
|
36 except IOError:
|
|
37 print("cannot read file %s" % file)
|
|
38 return None
|
|
39
|
|
40 # find all matched strings.
|
|
41 # moiter is iterator of MatchObject.
|
|
42 moiter = PROG.finditer(data)
|
|
43 for mo in moiter:
|
|
44 tmp = { "type": mo.group(1),
|
|
45 "name": mo.group(2),
|
|
46 "parms": mo.group(3),
|
|
47 "offset": mo.start() }
|
|
48 if check_reserved_word(tmp):
|
|
49 declarators.append(tmp)
|
|
50
|
|
51 return declarators
|
|
52
|
|
53 def debug_print(decl):
|
|
54 for (key,value) in list(decl.items()):
|
|
55 if isinstance(value, str):
|
|
56 decl[key] = value.replace("\n"," ").replace("\t"," ")
|
|
57
|
|
58 print("Type:\t{0:s}".format(decl["type"]))
|
|
59 print("Name:\t{0:s}".format(decl["name"]))
|
|
60 print("Params:\t{0:s}".format(decl["parms"]))
|
|
61 print("offset:\t{0:d}".format(decl["offset"]))
|
|
62 print("")
|
|
63
|
|
64 def format_print(decl, file):
|
|
65 for (key,value) in list(decl.items()):
|
|
66 if isinstance(value, str):
|
|
67 decl[key] = value.replace("\n"," ").replace("\t"," ")
|
|
68
|
|
69 print("/* defined in file {0:s} at offset {1:d} */".format(file,decl["offset"]))
|
|
70 print("{3:s}{0:s} {1:s} ({2:s});".format(decl["type"],decl["name"],decl["parms"], add_extern))
|
|
71 print("")
|
|
72
|
|
73 def getoptions():
|
|
74 global omit_static, add_extern
|
|
75
|
|
76 try:
|
|
77 opts, args = getopt.getopt(sys.argv[1:], 'se', [ 'omit-static', 'add-extern' ])
|
|
78 except getopt.GetoptError as err:
|
|
79 print(err)
|
|
80 usage()
|
|
81 sys.exit(2)
|
|
82
|
|
83 for opt,a in opts:
|
|
84 if opt in ("-s", "--omit-static"):
|
|
85 omit_static=True
|
|
86 elif opt in ("-e", "--add-extern"):
|
|
87 add_extern="extern "
|
|
88 else:
|
|
89 print("unhandled option {0}".format(opt))
|
|
90 usage()
|
|
91
|
|
92 return args
|
|
93
|
|
94 def usage():
|
|
95 print( """\
|
|
96 Usage: {0:s} OPION... [FILE]...
|
|
97 OPTIONS:
|
|
98 -s, --omit-static omit static functions
|
|
99 -e, --add-extern add extern to all function declarations
|
|
100 """.format(sys.argv[0]))
|
|
101
|
|
102 def main():
|
|
103
|
|
104 # option handling.
|
|
105 args = getoptions()
|
|
106
|
|
107 for file in args:
|
|
108 # read function declaration from each file.
|
|
109 decls = read_decls(file)
|
|
110 if decls==None or len(decls)==0:
|
|
111 # no function found.
|
|
112 print("{0} have no function definition!".format(file))
|
|
113 continue
|
|
114
|
|
115 for decl in decls:
|
|
116 if omit_static and 0 <= decl["type"].find("static"):
|
|
117 # static function is ignored.
|
|
118 continue
|
|
119 #debug_print(decl)
|
|
120 format_print(decl, file)
|
|
121
|
|
122 #usage()
|
|
123 main()
|
|
124
|