Update tooling to use clang-format (issue #2171)
This commit is contained in:
parent
816f700d3e
commit
a566549e04
|
@ -27,73 +27,6 @@ def wrap_text(text, indent = '', maxchars = 80):
|
|||
result += indent+line+'\n'
|
||||
return result
|
||||
|
||||
def wrap_code(code, indent = ' ', maxchars = 80, splitchars = '(=,'):
|
||||
""" Wrap the code lines to the specified number of characters. If
|
||||
necessary a line will be broken and wrapped after one of the split
|
||||
characters.
|
||||
"""
|
||||
output = ''
|
||||
|
||||
# normalize line endings
|
||||
code = code.replace("\r\n", "\n")
|
||||
|
||||
# break the code chunk into lines
|
||||
lines = string.split(code, '\n')
|
||||
for line in lines:
|
||||
if len(line) <= maxchars:
|
||||
# line is short enough that it doesn't need to be wrapped
|
||||
output += line + '\n'
|
||||
continue
|
||||
|
||||
# retrieve the whitespace at the beginning of the line for later use
|
||||
# as padding
|
||||
ws = ''
|
||||
for char in line:
|
||||
if char.isspace():
|
||||
ws += char
|
||||
else:
|
||||
break
|
||||
|
||||
# iterate over all characters in the string keeping track of where the
|
||||
# last valid break character was found and wrapping the line
|
||||
# accordingly
|
||||
lastsplit = 0
|
||||
nextsplit = -1
|
||||
splitct = 0
|
||||
pos = 0
|
||||
for char in line:
|
||||
if splitchars.find(char) >= 0:
|
||||
# a new split position has been found
|
||||
nextsplit = pos
|
||||
size = pos - lastsplit + 1
|
||||
if splitct > 0:
|
||||
size += len(ws) + len(indent)
|
||||
if size >= maxchars:
|
||||
# the line is too long
|
||||
section = line[lastsplit:nextsplit+1]
|
||||
if len(section) > 0:
|
||||
# output the line portion between the last split and the
|
||||
# next split
|
||||
if splitct > 0:
|
||||
# start a new line and trim the line section
|
||||
output += '\n'+ws+indent
|
||||
section = string.strip(section)
|
||||
output += section
|
||||
lastsplit = nextsplit + 1
|
||||
splitct += 1
|
||||
pos += 1
|
||||
if len(line) - lastsplit > 0:
|
||||
# output the remainder of the line
|
||||
section = line[lastsplit:]
|
||||
if splitct > 0:
|
||||
# start a new line and trim the line section
|
||||
output += '\n'+ws+indent
|
||||
section = string.strip(section)
|
||||
output += section
|
||||
output += '\n'
|
||||
|
||||
return output
|
||||
|
||||
def is_base_class(clsname):
|
||||
""" Returns true if |clsname| is a known base (root) class in the object
|
||||
hierarchy.
|
||||
|
@ -392,8 +325,8 @@ _cre_retval = '([A-Za-z0-9_<>:,\*\&]{1,})'
|
|||
_cre_typedef = '([A-Za-z0-9_<>:,\*\&\s]{1,})'
|
||||
# regex for matching function return value and name combination
|
||||
_cre_func = '([A-Za-z][A-Za-z0-9_<>:,\*\&\s]{1,})'
|
||||
# regex for matching virtual function modifiers
|
||||
_cre_vfmod = '([A-Za-z0-9_]{0,})'
|
||||
# regex for matching virtual function modifiers + arbitrary whitespace
|
||||
_cre_vfmod = '([\sA-Za-z0-9_]{0,})'
|
||||
# regex for matching arbitrary whitespace
|
||||
_cre_space = '[\s]{1,}'
|
||||
# regex for matching optional virtual keyword
|
||||
|
@ -502,6 +435,8 @@ def get_copyright():
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=$$HASH$$$
|
||||
//
|
||||
|
||||
"""
|
||||
# add the copyright year
|
||||
|
@ -598,12 +533,36 @@ class obj_header:
|
|||
|
||||
# build the class objects
|
||||
for attrib, name, parent_name, body in list:
|
||||
# Style may place the ':' on the next line.
|
||||
comment = get_comment(data, name+' :')
|
||||
if len(comment) == 0:
|
||||
comment = get_comment(data, name+"\n")
|
||||
validate_comment(filename, name, comment)
|
||||
self.classes.append(
|
||||
obj_class(self, filename, attrib, name, parent_name, body,
|
||||
comment, includes, forward_declares))
|
||||
|
||||
# extract empty classes
|
||||
p = re.compile('\n'+_cre_attrib+
|
||||
'\nclass'+_cre_space+_cre_cfname+_cre_space+
|
||||
':'+_cre_space+'public'+_cre_virtual+
|
||||
_cre_space+_cre_cfname+_cre_space+
|
||||
'{};', re.MULTILINE | re.DOTALL)
|
||||
list = p.findall(data)
|
||||
if len(list) > 0:
|
||||
added = True
|
||||
|
||||
# build the class objects
|
||||
for attrib, name, parent_name in list:
|
||||
# Style may place the ':' on the next line.
|
||||
comment = get_comment(data, name+' :')
|
||||
if len(comment) == 0:
|
||||
comment = get_comment(data, name+"\n")
|
||||
validate_comment(filename, name, comment)
|
||||
self.classes.append(
|
||||
obj_class(self, filename, attrib, name, parent_name, "",
|
||||
comment, includes, forward_declares))
|
||||
|
||||
if added:
|
||||
# a global function or class was read from the header file
|
||||
self.filenames.append(filename)
|
||||
|
@ -800,7 +759,7 @@ class obj_class:
|
|||
|
||||
# extract virtual functions
|
||||
p = re.compile('\n'+_cre_space+_cre_attrib+'\n'+_cre_space+'virtual'+
|
||||
_cre_space+_cre_func+'\((.*?)\)'+_cre_space+_cre_vfmod,
|
||||
_cre_space+_cre_func+'\((.*?)\)'+_cre_vfmod,
|
||||
re.MULTILINE | re.DOTALL)
|
||||
list = p.findall(body)
|
||||
|
||||
|
@ -811,7 +770,7 @@ class obj_class:
|
|||
validate_comment(filename, retval, comment)
|
||||
self.virtualfuncs.append(
|
||||
obj_function_virtual(self, attrib, retval, argval, comment,
|
||||
vfmod))
|
||||
vfmod.strip()))
|
||||
|
||||
def __repr__(self):
|
||||
result = '/* '+dict_to_str(self.attribs)+' */ class '+self.name+"\n{"
|
||||
|
@ -2038,7 +1997,7 @@ if __name__ == "__main__":
|
|||
sys.stdout.write('\n')
|
||||
|
||||
# output the parsed C++ data
|
||||
sys.stdout.write(wrap_code(str(header), '\t'))
|
||||
sys.stdout.write(str(header))
|
||||
|
||||
# output the C API formatted data
|
||||
defined_names = header.get_defined_structs()
|
||||
|
@ -2069,4 +2028,4 @@ if __name__ == "__main__":
|
|||
for func in funcs:
|
||||
result += func.get_capi_proto(defined_names)+';\n'
|
||||
result += '\n'
|
||||
sys.stdout.write(wrap_code(result, '\t'))
|
||||
sys.stdout.write(result)
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
@echo off
|
||||
python.bat check_style.py %*
|
|
@ -1,121 +0,0 @@
|
|||
# Copyright (c) 2012 The Chromium Embedded Framework Authors.
|
||||
# Portions copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import os, re, string, sys
|
||||
from file_util import *
|
||||
import git_util as git
|
||||
|
||||
# script directory
|
||||
script_dir = os.path.dirname(__file__)
|
||||
|
||||
# CEF root directory
|
||||
cef_dir = os.path.abspath(os.path.join(script_dir, os.pardir))
|
||||
|
||||
# Valid extensions for files we want to lint.
|
||||
DEFAULT_LINT_WHITELIST_REGEX = r"(.*\.cpp|.*\.cc|.*\.h)"
|
||||
DEFAULT_LINT_BLACKLIST_REGEX = r"$^"
|
||||
|
||||
try:
|
||||
# depot_tools may already be in the import path.
|
||||
import cpplint
|
||||
import cpplint_chromium
|
||||
except ImportError, e:
|
||||
# Search the PATH environment variable to find the depot_tools folder.
|
||||
depot_tools = None;
|
||||
paths = os.environ.get('PATH').split(os.pathsep)
|
||||
for path in paths:
|
||||
if os.path.exists(os.path.join(path, 'cpplint_chromium.py')):
|
||||
depot_tools = path
|
||||
break
|
||||
|
||||
if depot_tools is None:
|
||||
print >> sys.stderr, 'Error: could not find depot_tools in PATH.'
|
||||
sys.exit(2)
|
||||
|
||||
# Add depot_tools to import path.
|
||||
sys.path.append(depot_tools)
|
||||
import cpplint
|
||||
import cpplint_chromium
|
||||
|
||||
# The default implementation of FileInfo.RepositoryName looks for the top-most
|
||||
# directory that contains a .git folder. This is a problem for CEF because the
|
||||
# CEF root folder (which may have an arbitrary name) lives inside the Chromium
|
||||
# src folder. Reimplement in a dumb but sane way.
|
||||
def patch_RepositoryName(self):
|
||||
fullname = self.FullName()
|
||||
project_dir = os.path.dirname(fullname)
|
||||
if os.path.exists(fullname):
|
||||
root_dir = project_dir
|
||||
while os.path.basename(project_dir) != "src":
|
||||
project_dir = os.path.dirname(project_dir)
|
||||
prefix = os.path.commonprefix([root_dir, project_dir])
|
||||
components = fullname[len(prefix) + 1:].split('/')
|
||||
return string.join(["cef"] + components[1:], '/')
|
||||
return fullname
|
||||
|
||||
def check_style(args, white_list = None, black_list = None):
|
||||
""" Execute cpplint with the specified arguments. """
|
||||
|
||||
# Apply patches.
|
||||
cpplint.FileInfo.RepositoryName = patch_RepositoryName
|
||||
|
||||
# Process cpplint arguments.
|
||||
filenames = cpplint.ParseArguments(args)
|
||||
|
||||
if not white_list:
|
||||
white_list = DEFAULT_LINT_WHITELIST_REGEX
|
||||
white_regex = re.compile(white_list)
|
||||
if not black_list:
|
||||
black_list = DEFAULT_LINT_BLACKLIST_REGEX
|
||||
black_regex = re.compile(black_list)
|
||||
|
||||
extra_check_functions = [cpplint_chromium.CheckPointerDeclarationWhitespace]
|
||||
|
||||
for filename in filenames:
|
||||
if white_regex.match(filename):
|
||||
if black_regex.match(filename):
|
||||
print "Ignoring file %s" % filename
|
||||
else:
|
||||
cpplint.ProcessFile(filename, cpplint._cpplint_state.verbose_level,
|
||||
extra_check_functions)
|
||||
else:
|
||||
print "Skipping file %s" % filename
|
||||
|
||||
print "Total errors found: %d\n" % cpplint._cpplint_state.error_count
|
||||
return 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Start with the default parameters.
|
||||
args = [
|
||||
# * Disable the 'build/class' test because it errors uselessly with C
|
||||
# structure pointers and template declarations.
|
||||
# * Disable the 'runtime/references' test because CEF allows non-const
|
||||
# arguments passed by reference.
|
||||
# * Disable the 'runtime/sizeof' test because it has a high number of
|
||||
# false positives and adds marginal value.
|
||||
'--filter=-build/class,-runtime/references,-runtime/sizeof',
|
||||
]
|
||||
|
||||
# Add anything passed on the command-line.
|
||||
args += sys.argv[1:]
|
||||
|
||||
# Pre-process the arguments before passing to the linter.
|
||||
new_args = []
|
||||
changed = []
|
||||
for arg in args:
|
||||
if arg == '--changed':
|
||||
# Add any changed files.
|
||||
changed = git.get_changed_files(cef_dir)
|
||||
elif arg[:2] == '--' or not os.path.isdir(arg):
|
||||
# Pass argument unchanged.
|
||||
new_args.append(arg)
|
||||
else:
|
||||
# Add all files in the directory.
|
||||
new_args += get_files(os.path.join(arg, '*'))
|
||||
|
||||
if len(changed) > 0:
|
||||
new_args += changed
|
||||
|
||||
check_style(new_args)
|
|
@ -1,2 +0,0 @@
|
|||
#!/bin/sh
|
||||
python check_style.py $@
|
|
@ -0,0 +1,22 @@
|
|||
# Copyright (c) 2017 The Chromium Embedded Framework Authors. All rights
|
||||
# reserved. Use of this source code is governed by a BSD-style license that
|
||||
# can be found in the LICENSE file
|
||||
|
||||
from exec_util import exec_cmd
|
||||
import sys
|
||||
|
||||
if sys.platform == 'win32':
|
||||
# Force use of the clang-format version bundled with depot_tools.
|
||||
clang_format_exe = 'clang-format.bat'
|
||||
else:
|
||||
clang_format_exe = 'clang-format'
|
||||
|
||||
def clang_format(file_contents):
|
||||
result = exec_cmd(clang_format_exe, ".", file_contents)
|
||||
if result['out'] != '':
|
||||
output = result['out']
|
||||
if sys.platform == 'win32':
|
||||
# Convert to Unix line endings.
|
||||
output = output.replace("\r", "")
|
||||
return output
|
||||
return None
|
|
@ -0,0 +1,2 @@
|
|||
@echo off
|
||||
python.bat tools\fix_style.py %*
|
|
@ -0,0 +1,101 @@
|
|||
# Copyright (c) 2017 The Chromium Embedded Framework Authors.
|
||||
# Portions copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import os, re, sys
|
||||
from clang_util import clang_format
|
||||
from file_util import *
|
||||
from git_util import get_changed_files
|
||||
|
||||
# Valid extensions for files we want to clang-format.
|
||||
DEFAULT_LINT_WHITELIST_REGEX = r"(.*\.cpp|.*\.cc|.*\.h|.*\.mm)$"
|
||||
DEFAULT_LINT_BLACKLIST_REGEX = r"$^"
|
||||
|
||||
def msg(filename, status):
|
||||
if sys.platform == 'win32':
|
||||
# Use Unix path separator.
|
||||
filename = filename.replace("\\", "/")
|
||||
|
||||
if len(filename) > 60:
|
||||
# Truncate the file path in a nice way.
|
||||
filename = filename[-57:]
|
||||
pos = filename.find("/")
|
||||
if pos > 0:
|
||||
filename = filename[pos:]
|
||||
filename = "..." + filename
|
||||
|
||||
print "%-60s %s" % (filename, status)
|
||||
|
||||
updatect = 0
|
||||
def update_file(filename):
|
||||
oldcontents = read_file(filename)
|
||||
if len(oldcontents) == 0:
|
||||
msg(filename, "empty")
|
||||
return;
|
||||
|
||||
newcontents = clang_format(oldcontents)
|
||||
if newcontents is None:
|
||||
raise Exception("Failed to process %s" % filename)
|
||||
|
||||
if newcontents != oldcontents:
|
||||
msg(filename, "fixed")
|
||||
global updatect
|
||||
updatect += 1
|
||||
write_file(filename, newcontents)
|
||||
else:
|
||||
msg(filename, "ok")
|
||||
return
|
||||
|
||||
def fix_style(filenames, white_list = None, black_list = None):
|
||||
""" Execute clang-format with the specified arguments. """
|
||||
if not white_list:
|
||||
white_list = DEFAULT_LINT_WHITELIST_REGEX
|
||||
white_regex = re.compile(white_list)
|
||||
if not black_list:
|
||||
black_list = DEFAULT_LINT_BLACKLIST_REGEX
|
||||
black_regex = re.compile(black_list)
|
||||
|
||||
for filename in filenames:
|
||||
if filename.find('*') > 0:
|
||||
# Expand wildcards.
|
||||
filenames.extend(get_files(filename))
|
||||
continue
|
||||
|
||||
if os.path.isdir(filename):
|
||||
# Add directory contents.
|
||||
filenames.extend(get_files(os.path.join(filename, "*")))
|
||||
continue
|
||||
|
||||
if not os.path.exists(filename):
|
||||
files = get_changed_files(".", filename)
|
||||
if len(files) > 0:
|
||||
filenames.extend(files)
|
||||
else:
|
||||
msg(filename, "missing")
|
||||
continue
|
||||
|
||||
if white_regex.match(filename):
|
||||
if black_regex.match(filename):
|
||||
msg(filename, "ignored")
|
||||
else:
|
||||
update_file(filename)
|
||||
else:
|
||||
msg(filename, "skipped")
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) == 1:
|
||||
print "Usage: %s [file-path|git-hash|unstaged|staged] ..." % sys.argv[0]
|
||||
print "\n Format C, C++ and ObjC files using Chromium's clang-format style."
|
||||
print "\nOptions:"
|
||||
print " file-path\tProcess the specified file or directory."
|
||||
print " \t\tDirectories will be processed recursively."
|
||||
print " \t\tThe \"*\" wildcard character is supported."
|
||||
print " git-hash\tProcess all files changed in the specified Git commit."
|
||||
print " unstaged\tProcess all unstaged files in the Git repo."
|
||||
print " staged\t\tProcess all staged files in the Git repo."
|
||||
sys.exit(1)
|
||||
|
||||
# Process anything passed on the command-line.
|
||||
fix_style(sys.argv[1:])
|
||||
print 'Done - Wrote %d files.' % updatect
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
python tools/fix_style.py $@
|
|
@ -40,9 +40,21 @@ def get_commit_number(path = '.', branch = 'HEAD'):
|
|||
return result['out'].strip()
|
||||
return '0'
|
||||
|
||||
def get_changed_files(path = '.'):
|
||||
def get_changed_files(path, hash):
|
||||
""" Retrieves the list of changed files. """
|
||||
# not implemented
|
||||
if hash == 'unstaged':
|
||||
cmd = "%s diff --name-only" % git_exe
|
||||
elif hash == 'staged':
|
||||
cmd = "%s diff --name-only --cached" % git_exe
|
||||
else:
|
||||
cmd = "%s diff-tree --no-commit-id --name-only -r %s" % (git_exe, hash)
|
||||
result = exec_cmd(cmd, path)
|
||||
if result['out'] != '':
|
||||
files = result['out']
|
||||
if sys.platform == 'win32':
|
||||
# Convert to Unix line endings.
|
||||
files = files.replace('\r\n', '\n')
|
||||
return files.strip().split("\n")
|
||||
return []
|
||||
|
||||
def write_indented_output(output):
|
||||
|
|
|
@ -14,8 +14,7 @@ def make_capi_global_funcs(funcs, defined_names, translate_map, indent):
|
|||
result += '\n'+format_comment(comment, indent, translate_map);
|
||||
if func.get_retval().get_type().is_result_string():
|
||||
result += indent+'// The resulting string must be freed by calling cef_string_userfree_free().\n'
|
||||
result += wrap_code(indent+'CEF_EXPORT '+
|
||||
func.get_capi_proto(defined_names)+';')
|
||||
result += indent+'CEF_EXPORT '+func.get_capi_proto(defined_names)+';\n'
|
||||
if first:
|
||||
first = False
|
||||
return result
|
||||
|
@ -30,9 +29,8 @@ def make_capi_member_funcs(funcs, defined_names, translate_map, indent):
|
|||
if func.get_retval().get_type().is_result_string():
|
||||
result += indent+'// The resulting string must be freed by calling cef_string_userfree_free().\n'
|
||||
parts = func.get_capi_parts()
|
||||
result += wrap_code(indent+parts['retval']+' (CEF_CALLBACK *'+
|
||||
parts['name']+')('+
|
||||
string.join(parts['args'], ', ')+');')
|
||||
result += indent+parts['retval']+' (CEF_CALLBACK *'+parts['name']+ \
|
||||
')('+string.join(parts['args'], ', ')+');\n'
|
||||
if first:
|
||||
first = False
|
||||
return result
|
||||
|
@ -81,6 +79,8 @@ def make_capi_header(header, filename):
|
|||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=$$HASH$$$
|
||||
//
|
||||
|
||||
#ifndef $GUARD$
|
||||
#define $GUARD$
|
||||
|
@ -118,7 +118,10 @@ def make_capi_header(header, filename):
|
|||
translated_includes.add(include)
|
||||
declares = cls.get_forward_declares()
|
||||
for declare in declares:
|
||||
all_declares.add(header.get_class(declare).get_capi_name())
|
||||
declare_cls = header.get_class(declare)
|
||||
if declare_cls is None:
|
||||
raise Exception('Unknown class: %s' % declare)
|
||||
all_declares.add(declare_cls.get_capi_name())
|
||||
|
||||
# output translated includes
|
||||
if len(translated_includes) > 0:
|
||||
|
@ -195,24 +198,10 @@ extern "C" {
|
|||
return result
|
||||
|
||||
|
||||
def write_capi_header(header, header_dir, filename, backup):
|
||||
capi_path = get_capi_file_name(os.path.join(header_dir, filename))
|
||||
if path_exists(capi_path):
|
||||
oldcontents = read_file(capi_path)
|
||||
else:
|
||||
oldcontents = ''
|
||||
|
||||
def write_capi_header(header, header_dir, filename):
|
||||
file = get_capi_file_name(os.path.join(header_dir, filename))
|
||||
newcontents = make_capi_header(header, filename)
|
||||
if newcontents != oldcontents:
|
||||
if backup and oldcontents != '':
|
||||
backup_file(capi_path)
|
||||
capi_dir = os.path.split(capi_path)[0]
|
||||
if not os.path.isdir(capi_dir):
|
||||
make_dir(capi_dir)
|
||||
write_file(capi_path, newcontents)
|
||||
return True
|
||||
|
||||
return False
|
||||
return (file, newcontents)
|
||||
|
||||
|
||||
# test the module
|
||||
|
|
|
@ -76,31 +76,17 @@ def make_cpptoc_header(header, clsname):
|
|||
|
||||
result += '#endif // CEF_LIBCEF_DLL_CPPTOC_'+defname+'_CPPTOC_H_'
|
||||
|
||||
return wrap_code(result)
|
||||
return result
|
||||
|
||||
|
||||
def write_cpptoc_header(header, clsname, dir, backup):
|
||||
def write_cpptoc_header(header, clsname, dir):
|
||||
# give the output file the same directory offset as the input file
|
||||
cls = header.get_class(clsname)
|
||||
dir = os.path.dirname(os.path.join(dir, cls.get_file_name()))
|
||||
file = os.path.join(dir, get_capi_name(clsname[3:], False)+'_cpptoc.h')
|
||||
|
||||
if path_exists(file):
|
||||
oldcontents = read_file(file)
|
||||
else:
|
||||
oldcontents = ''
|
||||
|
||||
newcontents = make_cpptoc_header(header, clsname)
|
||||
if newcontents != oldcontents:
|
||||
if backup and oldcontents != '':
|
||||
backup_file(file)
|
||||
file_dir = os.path.split(file)[0]
|
||||
if not os.path.isdir(file_dir):
|
||||
make_dir(file_dir)
|
||||
write_file(file, newcontents)
|
||||
return True
|
||||
|
||||
return False
|
||||
return (file, newcontents)
|
||||
|
||||
|
||||
# test the module
|
||||
|
|
|
@ -23,9 +23,7 @@ def make_cpptoc_function_impl_existing(cls, name, func, impl, defined_names):
|
|||
if len(changes) > 0:
|
||||
notify(name+' prototype changed')
|
||||
|
||||
return wrap_code(make_cpptoc_impl_proto(name, func, parts))+'{'+ \
|
||||
changes+impl['body']+'\n}\n'
|
||||
return result
|
||||
return make_cpptoc_impl_proto(name, func, parts)+'{'+changes+impl['body']+'\n}\n\n'
|
||||
|
||||
def make_cpptoc_function_impl_new(cls, name, func, defined_names):
|
||||
# retrieve the C API prototype parts
|
||||
|
@ -62,7 +60,7 @@ def make_cpptoc_function_impl_new(cls, name, func, defined_names):
|
|||
result += '\n #pragma message("Warning: "__FILE__": '+name+' is not implemented")'
|
||||
result += '\n // END DELETE BEFORE MODIFYING'
|
||||
result += '\n}\n\n'
|
||||
return wrap_code(result)
|
||||
return result
|
||||
|
||||
result += '\n // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING\n'
|
||||
|
||||
|
@ -454,8 +452,8 @@ def make_cpptoc_function_impl_new(cls, name, func, defined_names):
|
|||
if len(result) != result_len:
|
||||
result += '\n'
|
||||
|
||||
result += '}\n'
|
||||
return wrap_code(result)
|
||||
result += '}\n\n'
|
||||
return result
|
||||
|
||||
def make_cpptoc_function_impl(cls, funcs, existing, prefixname, defined_names):
|
||||
impl = ''
|
||||
|
@ -633,7 +631,7 @@ def make_cpptoc_class_impl(header, clsname, impl):
|
|||
'#endif\n\n'+ \
|
||||
'template<> CefWrapperType '+parent_sig+'::kWrapperType = '+get_wrapper_type_enum(clsname)+';'
|
||||
|
||||
result += '\n\n'+wrap_code(const)
|
||||
result += '\n\n'+const
|
||||
|
||||
return result
|
||||
|
||||
|
@ -671,7 +669,7 @@ def make_cpptoc_global_impl(header, impl):
|
|||
|
||||
return result
|
||||
|
||||
def write_cpptoc_impl(header, clsname, dir, backup):
|
||||
def write_cpptoc_impl(header, clsname, dir):
|
||||
if clsname is None:
|
||||
# global file
|
||||
file = dir
|
||||
|
@ -691,16 +689,7 @@ def write_cpptoc_impl(header, clsname, dir, backup):
|
|||
newcontents = make_cpptoc_global_impl(header, oldcontents)
|
||||
else:
|
||||
newcontents = make_cpptoc_class_impl(header, clsname, oldcontents)
|
||||
if newcontents != oldcontents:
|
||||
if backup and oldcontents != '':
|
||||
backup_file(file)
|
||||
file_dir = os.path.split(file)[0]
|
||||
if not os.path.isdir(file_dir):
|
||||
make_dir(file_dir)
|
||||
write_file(file, newcontents)
|
||||
return True
|
||||
|
||||
return False
|
||||
return (file, newcontents)
|
||||
|
||||
|
||||
# test the module
|
||||
|
|
|
@ -119,31 +119,17 @@ def make_ctocpp_header(header, clsname):
|
|||
|
||||
result += '#endif // CEF_LIBCEF_DLL_CTOCPP_'+defname+'_CTOCPP_H_'
|
||||
|
||||
return wrap_code(result)
|
||||
return result
|
||||
|
||||
|
||||
def write_ctocpp_header(header, clsname, dir, backup):
|
||||
def write_ctocpp_header(header, clsname, dir):
|
||||
# give the output file the same directory offset as the input file
|
||||
cls = header.get_class(clsname)
|
||||
dir = os.path.dirname(os.path.join(dir, cls.get_file_name()))
|
||||
file = os.path.join(dir, get_capi_name(clsname[3:], False)+'_ctocpp.h')
|
||||
|
||||
if path_exists(file):
|
||||
oldcontents = read_file(file)
|
||||
else:
|
||||
oldcontents = ''
|
||||
|
||||
newcontents = make_ctocpp_header(header, clsname)
|
||||
if newcontents != oldcontents:
|
||||
if backup and oldcontents != '':
|
||||
backup_file(file)
|
||||
file_dir = os.path.split(file)[0]
|
||||
if not os.path.isdir(file_dir):
|
||||
make_dir(file_dir)
|
||||
write_file(file, newcontents)
|
||||
return True
|
||||
|
||||
return False
|
||||
return (file, newcontents)
|
||||
|
||||
|
||||
# test the module
|
||||
|
|
|
@ -31,8 +31,8 @@ def make_ctocpp_function_impl_existing(clsname, name, func, impl):
|
|||
if len(changes) > 0:
|
||||
notify(name+' prototype changed')
|
||||
|
||||
return wrap_code(make_ctocpp_impl_proto(clsname, name, func, parts))+'{'+ \
|
||||
changes+impl['body']+'\n}\n'
|
||||
return make_ctocpp_impl_proto(clsname, name, func, parts)+'{'+ \
|
||||
changes+impl['body']+'\n}\n\n'
|
||||
|
||||
def make_ctocpp_function_impl_new(clsname, name, func):
|
||||
# build the C++ prototype
|
||||
|
@ -91,7 +91,7 @@ def make_ctocpp_function_impl_new(clsname, name, func):
|
|||
result += '\n #pragma message("Warning: "__FILE__": '+name+' is not implemented")'
|
||||
result += '\n // END DELETE BEFORE MODIFYING'
|
||||
result += '\n}\n\n'
|
||||
return wrap_code(result)
|
||||
return result
|
||||
|
||||
result += '\n // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING\n'
|
||||
|
||||
|
@ -493,8 +493,8 @@ def make_ctocpp_function_impl_new(clsname, name, func):
|
|||
if len(result) != result_len:
|
||||
result += '\n'
|
||||
|
||||
result += '}\n'
|
||||
return wrap_code(result)
|
||||
result += '}\n\n'
|
||||
return result
|
||||
|
||||
def make_ctocpp_function_impl(clsname, funcs, existing):
|
||||
impl = ''
|
||||
|
@ -634,7 +634,7 @@ def make_ctocpp_class_impl(header, clsname, impl):
|
|||
'#endif\n\n'+ \
|
||||
'template<> CefWrapperType '+parent_sig+'::kWrapperType = '+get_wrapper_type_enum(clsname)+';'
|
||||
|
||||
result += wrap_code(const)
|
||||
result += const
|
||||
|
||||
return result
|
||||
|
||||
|
@ -669,7 +669,7 @@ def make_ctocpp_global_impl(header, impl):
|
|||
|
||||
return result
|
||||
|
||||
def write_ctocpp_impl(header, clsname, dir, backup):
|
||||
def write_ctocpp_impl(header, clsname, dir):
|
||||
if clsname is None:
|
||||
# global file
|
||||
file = dir
|
||||
|
@ -689,16 +689,7 @@ def write_ctocpp_impl(header, clsname, dir, backup):
|
|||
newcontents = make_ctocpp_global_impl(header, oldcontents)
|
||||
else:
|
||||
newcontents = make_ctocpp_class_impl(header, clsname, oldcontents)
|
||||
if newcontents != oldcontents:
|
||||
if backup and oldcontents != '':
|
||||
backup_file(file)
|
||||
file_dir = os.path.split(file)[0]
|
||||
if not os.path.isdir(file_dir):
|
||||
make_dir(file_dir)
|
||||
write_file(file, newcontents)
|
||||
return True
|
||||
|
||||
return False
|
||||
return (file, newcontents)
|
||||
|
||||
|
||||
# test the module
|
||||
|
|
|
@ -17,6 +17,8 @@ def make_gypi_file(header):
|
|||
# by hand. See the translator.README.txt file in the tools directory for
|
||||
# more information.
|
||||
#
|
||||
# $hash=$$HASH$$$
|
||||
#
|
||||
|
||||
{
|
||||
'variables': {
|
||||
|
@ -81,20 +83,9 @@ def make_gypi_file(header):
|
|||
|
||||
return result
|
||||
|
||||
def write_gypi_file(header, file, backup):
|
||||
if path_exists(file):
|
||||
oldcontents = read_file(file)
|
||||
else:
|
||||
oldcontents = ''
|
||||
|
||||
def write_gypi_file(header, file):
|
||||
newcontents = make_gypi_file(header)
|
||||
if newcontents != oldcontents:
|
||||
if backup and oldcontents != '':
|
||||
backup_file(file)
|
||||
write_file(file, newcontents)
|
||||
return True
|
||||
|
||||
return False
|
||||
return (file, newcontents)
|
||||
|
||||
|
||||
# test the module
|
||||
|
|
|
@ -28,9 +28,9 @@ def make_views_function_stub_impl(clsname, func):
|
|||
if retval_default != '':
|
||||
result += '\n return ' + retval_default + ';'
|
||||
|
||||
result += '\n}\n'
|
||||
result += '\n}\n\n'
|
||||
|
||||
return wrap_code(result)
|
||||
return result
|
||||
|
||||
def make_views_class_stub_impl(header, cls):
|
||||
impl = ''
|
||||
|
@ -64,23 +64,9 @@ def make_views_stub_impl(header):
|
|||
result += impl
|
||||
return result
|
||||
|
||||
def write_views_stub_impl(header, file, backup):
|
||||
if path_exists(file):
|
||||
oldcontents = read_file(file)
|
||||
else:
|
||||
oldcontents = ''
|
||||
|
||||
def write_views_stub_impl(header, file):
|
||||
newcontents = make_views_stub_impl(header)
|
||||
if newcontents != oldcontents:
|
||||
if backup and oldcontents != '':
|
||||
backup_file(file)
|
||||
file_dir = os.path.split(file)[0]
|
||||
if not os.path.isdir(file_dir):
|
||||
make_dir(file_dir)
|
||||
write_file(file, newcontents)
|
||||
return True
|
||||
|
||||
return False
|
||||
return (file, newcontents)
|
||||
|
||||
# Test the module.
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -21,23 +21,12 @@ def make_wrapper_types_header(header):
|
|||
result += '};\n\n' + \
|
||||
'#endif // CEF_LIBCEF_DLL_WRAPPER_TYPES_H_'
|
||||
|
||||
return wrap_code(result)
|
||||
return result
|
||||
|
||||
|
||||
def write_wrapper_types_header(header, file, backup):
|
||||
if path_exists(file):
|
||||
oldcontents = read_file(file)
|
||||
else:
|
||||
oldcontents = ''
|
||||
|
||||
def write_wrapper_types_header(header, file):
|
||||
newcontents = make_wrapper_types_header(header)
|
||||
if newcontents != oldcontents:
|
||||
if backup and oldcontents != '':
|
||||
backup_file(file)
|
||||
write_file(file, newcontents)
|
||||
return True
|
||||
|
||||
return False
|
||||
return (file, newcontents)
|
||||
|
||||
|
||||
# test the module
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
@echo off
|
||||
call python.bat translator.py --root-dir ..
|
||||
call python.bat translator.py --root-dir .. %*
|
||||
pause
|
|
@ -4,6 +4,9 @@
|
|||
|
||||
import sys
|
||||
from cef_parser import *
|
||||
from clang_util import clang_format
|
||||
from file_util import *
|
||||
import hashlib
|
||||
from make_capi_header import *
|
||||
from make_cpptoc_header import *
|
||||
from make_cpptoc_impl import *
|
||||
|
@ -32,6 +35,9 @@ parser.add_option('--root-dir', dest='rootdir', metavar='DIR',
|
|||
parser.add_option('--backup',
|
||||
action='store_true', dest='backup', default=False,
|
||||
help='create a backup of modified files')
|
||||
parser.add_option('--force',
|
||||
action='store_true', dest='force', default=False,
|
||||
help='force rewrite of the file')
|
||||
parser.add_option('-c', '--classes', dest='classes', action='append',
|
||||
help='only translate the specified classes')
|
||||
parser.add_option('-q', '--quiet',
|
||||
|
@ -76,24 +82,80 @@ header.add_directory(cpp_header_dir, excluded_files)
|
|||
header.add_directory(cpp_header_test_dir)
|
||||
header.add_directory(cpp_header_views_dir)
|
||||
|
||||
|
||||
# Track the number of files that were written.
|
||||
writect = 0
|
||||
|
||||
#output the C API header
|
||||
def update_file(file, newcontents):
|
||||
""" Replaces the contents of |file| with |newcontents| if necessary. """
|
||||
oldcontents = ''
|
||||
oldhash = ''
|
||||
|
||||
if newcontents[-1:] != "\n":
|
||||
# Add newline at end of file.
|
||||
newcontents += "\n"
|
||||
|
||||
# clang-format is slow so we don't want to apply it if the pre-formatted
|
||||
# content hasn't changed. To check for changes we embed a hash of the pre-
|
||||
# formatted content in the resulting file.
|
||||
hash_start = "$hash="
|
||||
hash_end = "$"
|
||||
hash_token = "$$HASH$$"
|
||||
|
||||
if not options.force and path_exists(file):
|
||||
oldcontents = read_file(file)
|
||||
|
||||
# Extract the existing hash.
|
||||
start = oldcontents.find(hash_start)
|
||||
if start > 0:
|
||||
end = oldcontents.find(hash_end, start + len(hash_start))
|
||||
if end > 0:
|
||||
oldhash = oldcontents[start + len(hash_start):end]
|
||||
|
||||
# Compute the new hash.
|
||||
rev = hashlib.sha1(newcontents).digest();
|
||||
newhash = ''.join(format(ord(i),'0>2x') for i in rev)
|
||||
|
||||
if oldhash == newhash:
|
||||
# Pre-formatted contents have not changed.
|
||||
return
|
||||
|
||||
newcontents = newcontents.replace(hash_token, newhash, 1)
|
||||
|
||||
# Apply clang-format for C/C++ files.
|
||||
if os.path.splitext(file)[1][1:] in ('cc', 'cpp', 'h'):
|
||||
result = clang_format(newcontents)
|
||||
if result != None:
|
||||
newcontents = result
|
||||
else:
|
||||
raise Exception("Call to clang-format failed")
|
||||
|
||||
if options.backup and oldcontents != '':
|
||||
backup_file(file)
|
||||
|
||||
filedir = os.path.split(file)[0]
|
||||
if not os.path.isdir(filedir):
|
||||
make_dir(filedir)
|
||||
|
||||
write_file(file, newcontents)
|
||||
|
||||
global writect
|
||||
writect += 1
|
||||
|
||||
|
||||
# output the C API header
|
||||
if not options.quiet:
|
||||
sys.stdout.write('In C API header directory '+capi_header_dir+'...\n')
|
||||
filenames = sorted(header.get_file_names())
|
||||
for filename in filenames:
|
||||
if not options.quiet:
|
||||
sys.stdout.write('Generating '+filename+' C API header...\n')
|
||||
writect += write_capi_header(header, capi_header_dir, filename,
|
||||
options.backup)
|
||||
update_file(*write_capi_header(header, capi_header_dir, filename))
|
||||
|
||||
# output the wrapper types header
|
||||
if not options.quiet:
|
||||
sys.stdout.write('Generating wrapper types header...\n')
|
||||
writect += write_wrapper_types_header(header,
|
||||
wrapper_types_header,
|
||||
options.backup)
|
||||
update_file(*write_wrapper_types_header(header, wrapper_types_header))
|
||||
|
||||
# build the list of classes to parse
|
||||
allclasses = header.get_class_names()
|
||||
|
@ -111,12 +173,12 @@ classes = sorted(classes)
|
|||
# output CppToC global file
|
||||
if not options.quiet:
|
||||
sys.stdout.write('Generating CppToC global implementation...\n')
|
||||
writect += write_cpptoc_impl(header, None, cpptoc_global_impl, options.backup)
|
||||
update_file(*write_cpptoc_impl(header, None, cpptoc_global_impl))
|
||||
|
||||
# output CToCpp global file
|
||||
if not options.quiet:
|
||||
sys.stdout.write('Generating CToCpp global implementation...\n')
|
||||
writect += write_ctocpp_impl(header, None, ctocpp_global_impl, options.backup)
|
||||
update_file(*write_ctocpp_impl(header, None, ctocpp_global_impl))
|
||||
|
||||
# output CppToC class files
|
||||
if not options.quiet:
|
||||
|
@ -124,10 +186,10 @@ if not options.quiet:
|
|||
for cls in classes:
|
||||
if not options.quiet:
|
||||
sys.stdout.write('Generating '+cls+'CppToC class header...\n')
|
||||
writect += write_cpptoc_header(header, cls, cpptoc_dir, options.backup)
|
||||
update_file(*write_cpptoc_header(header, cls, cpptoc_dir))
|
||||
if not options.quiet:
|
||||
sys.stdout.write('Generating '+cls+'CppToC class implementation...\n')
|
||||
writect += write_cpptoc_impl(header, cls, cpptoc_dir, options.backup)
|
||||
update_file(*write_cpptoc_impl(header, cls, cpptoc_dir))
|
||||
|
||||
# output CppToC class files
|
||||
if not options.quiet:
|
||||
|
@ -135,20 +197,20 @@ if not options.quiet:
|
|||
for cls in classes:
|
||||
if not options.quiet:
|
||||
sys.stdout.write('Generating '+cls+'CToCpp class header...\n')
|
||||
writect += write_ctocpp_header(header, cls, ctocpp_dir, options.backup)
|
||||
update_file(*write_ctocpp_header(header, cls, ctocpp_dir))
|
||||
if not options.quiet:
|
||||
sys.stdout.write('Generating '+cls+'CToCpp class implementation...\n')
|
||||
writect += write_ctocpp_impl(header, cls, ctocpp_dir, options.backup)
|
||||
update_file(*write_ctocpp_impl(header, cls, ctocpp_dir))
|
||||
|
||||
# output the gypi file
|
||||
if not options.quiet:
|
||||
sys.stdout.write('Generating '+gypi_file+' file...\n')
|
||||
writect += write_gypi_file(header, gypi_file, options.backup)
|
||||
update_file(*write_gypi_file(header, gypi_file))
|
||||
|
||||
# output the views stub file
|
||||
if not options.quiet:
|
||||
sys.stdout.write('Generating '+views_stub_impl+' file...\n')
|
||||
writect += write_views_stub_impl(header, views_stub_impl, options.backup)
|
||||
update_file(*write_views_stub_impl(header, views_stub_impl))
|
||||
|
||||
if not options.quiet:
|
||||
sys.stdout.write('Done - Wrote '+str(writect)+' files.\n')
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#!/bin/sh
|
||||
python translator.py --root-dir ..
|
||||
python translator.py --root-dir .. $@
|
||||
|
|
Loading…
Reference in New Issue