aboutsummaryrefslogtreecommitdiff
path: root/tools/cppmerge/main.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/cppmerge/main.py')
-rw-r--r--tools/cppmerge/main.py115
1 files changed, 102 insertions, 13 deletions
diff --git a/tools/cppmerge/main.py b/tools/cppmerge/main.py
index ed06a2f7..76966a47 100644
--- a/tools/cppmerge/main.py
+++ b/tools/cppmerge/main.py
@@ -5,7 +5,7 @@ import re
import sys
parser = argparse.ArgumentParser()
-parser.add_argument("-o", "--output", required=True, help="The name of output header and source files excluding extension.")
+parser.add_argument("-o", "--output", required=True, help="The path of output header and source files excluding extension.")
parser.add_argument("input", nargs="+", help="The input source files or folders to scan.")
parser.add_argument("-e", "--exclude", nargs="+", help="Filenames that exludes from merging.")
args = parser.parse_args()
@@ -23,25 +23,23 @@ def add_header_file(path):
print("find header file: {}".format(path))
header_file_list.append(path)
-cpp_header_file_regex = re.compile(r".*\.(h|hpp)")
-cpp_source_file_regex = re.compile(r".*\.(cpp|cc|cxx)")
+cpp_header_file_regex = re.compile(r"^.*\.(h|hpp)$")
+cpp_source_file_regex = re.compile(r"^.*\.(cpp|cc|cxx)$")
+def is_exclude(file_name):
+ return args.exclude and file_name in args.exclude
for path in args.input:
if os.path.isdir(path):
input_dirs.append(path)
elif os.path.isfile(path):
file_name = os.path.basename(path)
+ if is_exclude(file_name):
+ sys.exit("{} is specified excluding.")
if cpp_source_file_regex.match(file_name):
- if file_name in args.exclude:
- sys.exit("{} is specified excluding.")
- else:
- add_source_file(path)
- elif cpp_header_file_regex.match(file_name):
- if file_name in args.exclude:
- sys.exit("{} is specified excluding.")
- else:
- add_header_file(path)
+ add_source_file(path)
+ elif cpp_header_file_regex.match(file_name):
+ add_header_file(path)
else:
sys.exit("{} is a file but it is neither c++ source nor header.".format(path))
else:
@@ -52,7 +50,7 @@ actual_exclude_count = 0
for input_dir in input_dirs:
for root, subdirs, files in os.walk(input_dir):
for f in files:
- if f in args.exclude:
+ if is_exclude(f):
actual_exclude_count += 1
else:
if cpp_source_file_regex.match(f):
@@ -68,3 +66,94 @@ print("total find {} source file(s)".format(len(source_file_list)))
print("total actual exclude {} file(s)".format(actual_exclude_count))
print()
+norm_source_file_list = [os.path.normpath(path) for path in source_file_list]
+norm_header_file_list = [os.path.normpath(path) for path in header_file_list]
+
+output_header_file_path = args.output + '.hpp'
+output_source_file_path = args.output + '.cpp'
+
+
+output_header_file = open(output_header_file_path, 'w')
+output_source_file = open(output_source_file_path, 'w')
+
+
+processed_headers = []
+
+header_pragma_once_regex = re.compile(r'#\s*pragma\s*once')
+header_include_command_regex = re.compile(r'#\s*include\s*"([\w.\-_/\\]+)"')
+
+def process_line(line):
+ match_result = header_include_command_regex.match(line)
+ if match_result:
+ return match_result.group(1)
+ else:
+ return None
+
+def find_header_path(base_path, header_path):
+ path = os.path.join(base_path, header_path)
+ if os.path.isfile(path):
+ return path
+ else:
+ for d in input_dirs:
+ path = os.path.join(d, header_path)
+ if os.path.isfile(path):
+ return path
+ raise RuntimeError("Header not found.\nBase path: {}\nHeader path: {}".format(base_path, header_path))
+
+def process_header_file(base_path, header_path):
+ path = find_header_path(base_path, header_path)
+ path = os.path.normpath(path)
+ if path in processed_headers:
+ return
+ processed_headers.append(path)
+
+ output_header_file.write("//--------------------------------------------------------\n")
+ output_header_file.write("//-------begin of file: {}\n".format(path))
+ output_header_file.write("//--------------------------------------------------------\n")
+ header_f = open(path, 'r')
+ found_pragma_once = False
+ for line in header_f:
+ if (not found_pragma_once):
+ if header_pragma_once_regex.match(line):
+ found_pragma_once = True
+ continue
+ new_header_name = process_line(line)
+ if not new_header_name is None:
+ process_header_file(os.path.dirname(path), new_header_name)
+ else:
+ output_header_file.write(line)
+ output_header_file.write("//--------------------------------------------------------\n")
+ output_header_file.write("//-------end of file: {}\n".format(path))
+ output_header_file.write("//--------------------------------------------------------\n")
+
+
+output_header_file.write("#pragma once\n")
+
+output_source_file.write('#include "{}"\n'.format(os.path.basename(output_header_file_path)))
+
+
+for source_path in source_file_list:
+ output_source_file.write("//--------------------------------------------------------\n")
+ output_source_file.write("//-------begin of file: {}\n".format(source_path))
+ output_source_file.write("//--------------------------------------------------------\n")
+ source_f = open(source_path, 'r')
+ for line in source_f:
+ new_header_name = process_line(line)
+ if not new_header_name is None:
+ process_header_file(os.path.dirname(source_path), new_header_name)
+ else:
+ output_source_file.write(line)
+ output_source_file.write("//--------------------------------------------------------\n")
+ output_source_file.write("//-------end of file: {}\n".format(source_path))
+ output_source_file.write("//--------------------------------------------------------\n")
+
+rest_header_count = len(norm_header_file_list) - len(processed_headers)
+
+if rest_header_count > 0:
+ print("{} header files are not included in any sources. Add them to header now.".format(rest_header_count))
+ print()
+ for header_path in norm_header_file_list:
+ if header_path not in processed_headers:
+ process_header_file('.', header_path)
+
+print("Done!")