axmol/tools/cpp-best-practise-formatter/cpp-best-practise-formatter.py

253 lines
6.6 KiB
Python
Executable File

#!/usr/bin/env python
import os
import re
import sys
# list of extensions to replace
replace_extensions = [".cpp", ".h", ".hpp", ".cc", ".mm"]
files_to_skip = None
replace_type = None
skip_contents = ["CCPointMake", "CCSizeMake", "CCRectMake", "CCLOG", \
"CCLog", "CCAssert", "CCSkeleton"]
def try_to_replace(fname):
if replace_type == "add_namespace":
if fname.lower().endswith(".h"):
return True
return False
else:
if replace_extensions:
for replace_extension in replace_extensions:
if fname.lower().endswith(replace_extension):
return True
return False
def replacement_member_variable(m):
# print "group 2: ", m.group(2)
name_prefix = m.group(3)
first = name_prefix[0]
second = ""
if len(name_prefix) > 1:
second = name_prefix[1]
if first.isupper() and second.islower():
first = first.lower()
name_prefix = first + name_prefix[1:]
return m.group(1) + "_" + name_prefix
elif first.isupper() and second.isupper():
return m.group(1) + "_" + name_prefix
else:
print "don't convert: ", m.group(1) + m.group(2) + m.group(3)
if m.group(2) == "m_":
return m.group(1) + "_" + name_prefix
return m.group(1) + m.group(2) + m.group(3)
def remove_prefix_callback(m):
pos = 0
for skip_content in skip_contents:
start = 0
while True:
pos = m.string.find(skip_content, start)
if pos == -1:
break
if pos == m.end(1):
return m.group(1) + "CC" + m.group(2)
start = pos + 1
return m.group(1) + m.group(2)
def add_namespace_callback(m):
"""
Arguments:
- `m`:
"""
return m.group(1) + "cocos2d::" + m.group(2)
def replace_callback(m):
if replace_type == "replace_variable":
return replacement_member_variable(m)
elif replace_type == "remove_prefix":
return remove_prefix_callback(m)
elif replace_type == "add_namespace":
return add_namespace_callback(m)
else:
raise Exception("type error.")
def file_replace(fname, pat):
# first, see if the pattern is even in the file.
with open(fname) as f:
if not any(re.search(pat, line) for line in f):
# print "can't find the string..."
return # pattern does not occur in file so we are done.
# pattern is in the file, so perform replace operation.
with open(fname) as f:
out_fname = fname + ".tmp"
out = open(out_fname, "w")
for line in f:
repl = line
m = re.search(pat, line)
if m:
repl = re.sub(pat, replace_callback, line)
out.write(repl)
out.close()
os.rename(out_fname, fname)
def mass_replace(dir_name, s_before):
pat = re.compile(s_before)
for dirpath, dirnames, filenames in os.walk(dir_name):
for fname in filenames:
if try_to_replace(fname):
fullname = os.path.join(dirpath, fname)
need_skip = False
if files_to_skip != None:
for skip in files_to_skip:
if fullname.find(skip) != -1:
print "skip file: ", fullname
need_skip = True
break
if not need_skip:
file_replace(fullname, pat)
prefix_need_replace = [
"m_pob",
"m_ob",
"m_str",
"m_psz",
"m_sz",
"m_pfn",
"m_pf",
"m_s",
"m_p",
"m_b",
"m_n",
"m_h",
"m_u",
"m_c",
"m_e",
"m_f",
"m_d",
"m_t",
"m_i",
"m_"
]
def do_member_varible_replace(dir):
"""
Arguments:
- `dir`:
- `dir_skip`:
"""
for p in prefix_need_replace:
# mass_replace(".", p)
pat = "([^\w])(" + p + ')(\w{1,2})'
mass_replace(dir, pat)
pat = "(^)(" + p + ')(\w{1,2})'
mass_replace(dir, pat)
remove_prefix_patterns = [
"([^/_\"])CC([A-Z][a-z])", \
"(^)CC([A-Z][a-z])", \
"([^/_\"])CC(IME[A-Z][a-z])", \
"(^)CC(IME[A-Z][a-z])", \
"([^/_\"])CC(TMX)", \
"(^)CC(TMX)", \
"([^/_\"])CC(GL\w)", \
"(^)CC(GL\w)", \
"([^/_\"])CC(EGL)", \
"(^)CC(EGL)", \
"([^/_\"])CC(EGL)", \
"(^)CC(EGL)", \
"([^/_\"])CC(RGBA)", \
"(^)CC(RGBA)", \
"([^/_\"])CC(SAX)", \
"(^)CC(SAX)"
]
def do_remove_class_cc_prefix(dir):
for pat in remove_prefix_patterns:
mass_replace(dir, pat)
def do_add_namespace(dir):
"""
Arguments:
- `dir`:
"""
pat = "([\s(])(CC[A-Z][a-z])"
mass_replace(dir, pat)
def main():
"""
"""
from optparse import OptionParser
parser = OptionParser("usage: %prog cpp-best-practise-formatter -d DIR_NAME [-s FILES_TO_SKIP]")
parser.add_option("-t", "--type",
action="store", type="string", dest="type", default="all",
help='''all: Replaces hungary naming of member variables and removing CC prefix for classes.
remove_prefix: Only removes CC prefix for classes.
replace_variable: Replaces hungary naming of member variables.
''')
parser.add_option("-d", "--dir",
action="store", type="string", dest="dir_name", default=None,
help="The directory which contains sources to format")
parser.add_option("-s", "--skip",
action="append", type="string", dest="skips", default=None,
help="Files or directories to skip")
(options, args) = parser.parse_args(sys.argv)
if options.dir_name is None:
raise Exception("Don't set -d at the same time");
global replace_type
replace_type = options.type
global files_to_skip
files_to_skip = options.skips
if options.type == "all":
#replace_type = "add_namespace"
#do_add_namespace(options.dir_name)
replace_type = "replace_variable"
do_member_varible_replace(options.dir_name)
replace_type = "remove_prefix"
do_remove_class_cc_prefix(options.dir_name)
elif options.type == "replace_variable":
do_member_varible_replace(options.dir_name)
elif options.type == "remove_prefix":
do_remove_class_cc_prefix(options.dir_name)
elif options.type == "add_namespace":
do_add_namespace(options.dir_name)
else:
raise Exception("type error, please use correct -t opinion.")
if __name__ == '__main__':
try:
main()
except Exception as e:
print e
sys.exit(1)