📄 mkheader.py
字号:
#!/usr/bin/env python
"""
Make Header
C to C++ conversion tools (c) 2001-2003 by D.G. Sureau
This script builds or completes the .h header file to include,
from a C source file.
Uses a list of files, or processes recursively all files from the
main file of a project.
C++ files are no handled.
This script should be used before converting a C program to C++,
or to update automatically header files when changes are performed
in a C source.
Syntax is: python mkheader.py filename.c
Requires: - the python interpreter (look at www.python.org)
- wstring.py, pattern.py, lexer.py (included)
Processing:
- A prototype is created for functions which don't has one.
- Prototypes are corrected to match definitions of functions.
- Multi-lines declarations are changed to one-lines ones.
- Variables defined as static are declared static in header.
They are not added to header if not already present since they
are local to the file.
- Other variables (no static) are added to the header if
not already declared, to become attributes at class making.
- Prototypes and declaration of variables are corrected in
the header file to match the definitions in the source file.
License:
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
webmaster@scriptol.org
http://www.scriptol.org
"""
import sys
import os
import string
import wstring
import pattern
import lexer
DEBUG = 0
TRUE = 1
FALSE = 0
# --- Processing a c source file and its header file
def processfile(cfile):
global extension
node, ext = os.path.splitext(cfile)
headername = node + ".h"
print "mkheader - processing", cfile, "and" , headername
infile = open(cfile, "rb")
if infile is None:
print "Enable to open", cfile
sys.exit(0)
varlist = [] # list of declarations
funclist = [] # list of prototypes
defdict = {} # define statements may be needed
defflag = {} # flags for things to be inside header
defline = {} # the original line
linecount = 0
defcount = 0
# Pass 1 - Processing the C file
# ------------------------------
# make a list of
# - each function definition
# - each global variable declaration (simple or array)
# - make also a dictionary of define statements
COMMENT = FALSE # This flag is true inside a comment
INSBLK = FALSE # This one inside a function's body
while(1):
line = infile.readline()
if not line: break
linecount = linecount + 1
line = wstring.chop(line) # Removing line separators
line = wstring.strip(line) # Removing spaces (with better strip)
if len(line) == 0: continue # Empty line ignored
# If we enter a comment block, remove it
if not COMMENT: COMMENT = lexer.opencomment(line)
if COMMENT:
i = string.find(line, "/*")
left = line[:i]
while COMMENT:
COMMENT = lexer.closecomment(line)
if COMMENT:
line = infile.readline()
if not line: COMMENT = FALSE
linecount = linecount + 1
if not COMMENT:
i = string.find(line, "*/")
right = line[i + 2:]
line = left + right
# If we are inside a compound block, skip the content
# print linecount, ') [' + str(lexer.blocklevel) + ']', line
if not INSBLK: INSBLK = lexer.openblock(line)
if INSBLK:
i = string.find(line, '{')
left = line[:i] # Getting the code at left of {
while(INSBLK):
INSBLK = lexer.closeblock(line)
if INSBLK:
line = infile.readline() # Skipping the content
linecount = linecount + 1
# print "skiping", lexer.blocklevel, wstring.chop(line)
if not line: INSBLK = FALSE
if not INSBLK:
i = string.find(line, '}')
right = line[i + 1:] # Getting the code at right of }
line = left + right
# "shortened" may change inside the call of the test functions
if line is None: continue
if line == "": continue
# A define statement
if line[0] == '#': # Define or pragma statement
if line[0:7] == "#define":
key, value = lexer.splitdefine(line)
if key != None:
defdict[key] = value # Add to dictionary
defflag[key] = FALSE # By default not to be included in header
defline[key] = line
#print "define added", line, "value=", value
continue
if not lexer.isdefinition(line): continue
#print "is typed", line
# Simple keywords of type on the line
if lexer.typeonly(line):
while(1):
next = infile.readline()
if not next: break
next = wstring.clean(next)
if next == "": continue
linecount = linecount + 1
line = line + ' ' + next
break
# A function prototype: ignore it
if lexer.isprototype(line): continue
# A function definition
if lexer.isfunction(line) == TRUE:
line = lexer.shortened
#print "is function ", line
# The heading may use several lines
while string.find(line, ')') == -1:
next = infile.readline()
linecount = linecount + 1
if next == None:
print "Error, function uncomplete"
exit()
next = wstring.chop(next)
next = wstring.strip(next)
line = line + next
# Handling the old format with declarations on next lines
if lexer.oldformat(line):
#print "old format", line
tlist = []
while(1):
l = infile.readline()
if not l: break
linecount = linecount + 1
l = wstring.chop(l)
l = wstring.strip(l)
l = lexer.getdecl(l)
if lexer.isvardef(l):
tlist.append(l)
else: break
if '{' in l: break
# Rebuilding the heading according to the new format
line = lexer.argreplace(line, tlist)
#print "args replace", line, "with list", tlist
i = string.find(line, '{')
if i != -1: line = line[:i]
line = lexer.removecomment(line)
line = lexer.addsemicolon(line)
#print "append to funclist", line
# There is no prototype for the main function
funcname = lexer.getident(line)
if funcname is None:
print "Error in (" + linecount + ')', line
sys.exit(0)
funcname = string.lower(funcname)
if funcname == "main": continue
funclist.append(line)
defcount = defcount + 1
#print line
continue
# An array declaration
# is static, ignored
# Removing from = to end of line
# Adding each size parameter to defdict (done in processarray)
# if initializer, become static for C++
line = lexer.getdecl(line) # removing extra codes
if lexer.isarray(line):
#print "is array", line
# Udate defflag
vlist = []
if lexer.multivar(line):
vlist = lexer.splitvardef(line)
#print "multivar", vlist
else:
vlist.append(line)
for vardef in vlist:
j = string.find(vardef, '=')
k = string.find(vardef, ';')
if k == -1: k = len(vardef)
if j < k:
vardef = vardef[:j] + ';'
lexer.processarray(vardef, defdict, defflag)
var = lexer.shortened
#print "in main shortened", var
var = lexer.addextern(var)
varlist.append(var)
#print "added array", var
defcount = defcount + 1
#print line
continue
# A variable declaration
if lexer.isvardef(line):
#print "255 var", line
vlist = []
if lexer.multivar(line):
vlist = lexer.splitvardef(line)
#print "multivar", vlist
else:
vlist.append(line)
for vardef in vlist:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -