diff --git a/scripts/process-text-files.py b/scripts/process-text-files.py index 12e9b32..6eba642 100644 --- a/scripts/process-text-files.py +++ b/scripts/process-text-files.py @@ -16,6 +16,8 @@ _exts_h = set([ '.h', '.H', '.hxx', '.HXX']) _exts_cpp = set([ '.cpp', '.CPP', '.c', '.C', '.cxx', '.CXX' ]) _exts_h_cpp = _exts_h | _exts_cpp +# ----------------------------------------------------------------------------------- Base class + class Cmd(jwutils.Cmd): def __init__(self, name, help): @@ -79,7 +81,7 @@ class Cmd(jwutils.Cmd): return r @staticmethod - def _indent_cpp_macros(data, src, target, context=None): + def _cpp_indent_macros(data, src, target, context=None): def __ctx(context, key, default): if key in context: @@ -242,7 +244,7 @@ class Cmd(jwutils.Cmd): raise Exception("Name space addition is not yet implemented") classname = re.sub('^ *#[ \t]*ifndef[\t ]+([^ ]+)($|[ \t/;])', '\\1', line) - def _fix_multiple_inclusion_preventer(self, prefix, path): + def _fix_include_guard(self, prefix, path): dir, name = os.path.split(path) if len(name) == 0: return False @@ -251,10 +253,10 @@ class Cmd(jwutils.Cmd): return False tok = re.sub('([A-Z])', '_\\1', name) tok = re.sub('\.', '_', tok) - mip = prefix + '_' + tok - mip = re.sub('__', '_', mip) - mip = mip.upper() - # find first old mip + ig = prefix + '_' + tok + ig = re.sub('__', '_', ig) + ig = ig.upper() + # find first old ig with open(path, 'r') as f: data = f.read() lines = data.splitlines() @@ -274,18 +276,18 @@ class Cmd(jwutils.Cmd): if re.match('^ *#[ \t]*if.?def[\t ]', line): level += 1 if re.match('^ *#[ \t]*ifndef[\t ]+' + old + '($|[ \t/;])', line): - data += '#ifndef ' + mip + '\n' + data += '#ifndef ' + ig + '\n' continue elif re.match('^ *#[ \t]*define[\t ]+' + old + '($|[ \t/;])', line): - data += '#define ' + mip + '\n' + data += '#define ' + ig + '\n' continue elif re.match('^ *#[ \t]*endif($|[ \t/;])', line): level -= 1 if level == 0: - data += '#endif /* ' + mip + ' */' + '\n' + data += '#endif /* ' + ig + ' */' + '\n' continue data += line + '\n' - tmp = path + '.mip' + tmp = path + '.ig' with open(tmp, 'w') as f: f.write(data) os.rename(tmp, path) @@ -323,6 +325,7 @@ class Cmd(jwutils.Cmd): def process(self, args, files): pass +# ----------------------------------------------------------------------------------- commands class CmdReplacePatterns(Cmd): @@ -335,21 +338,70 @@ class CmdReplacePatterns(Cmd): path = dir + '/' + name self._replace_in_file(path, self.replacements, func=self._replace_pattern) -class CmdReplaceCppSymbols(Cmd): +class CmdCleanupSpaces(Cmd): def __init__(self): - super(CmdReplaceCppSymbols, self).__init__("replace-cpp-symbols", "Replace C++ symbols in files") + super(CmdCleanupSpaces, self).__init__("cleanup-spaces", "Remove trailing empty lines") def add_parser(self, parsers): - p = super(CmdReplaceCppSymbols, self).add_parser(parsers) + p = super(CmdCleanupSpaces, self).add_parser(parsers) + return p + + def process(self, args, files): + slog(NOTICE, "Cleaning up unnecessary space in", len(files), "files:") + context = dict() + replacements = {"blah": "blub"} # just a dummy to use _replace_in_file, TODO: obviate the need + for dir, name in files: + path = dir + '/' + name + if self._replace_in_file(path, replacements, func=self._cleanup_spaces, context=context): + slog(NOTICE, "+ purged spaces :", path) + +class CmdMkIndentEquals(Cmd): + + def __init__(self): + super(CmdMkIndentEquals, self).__init__("mk-indent", "Indent and beautify makefiles") + + def add_parser(self, parsers): + p = super(CmdMkIndentEquals, self).add_parser(parsers) + p.add_argument('-e', "--equal-pos", help="Columns number of equal sign", type=int, default=40) + p.add_argument("--skip-short", help="Don't change makefiles with less lines of code", type=int, default=6) + p.add_argument("--min-assignments", help="Don't change makefiles with less assignment statements", type=int, default=4) + return p + + def process(self, args, files): + slog(NOTICE, "Beautifying", len(files), "makefiles:") + context = dict() + right_align_match = 2 + context["indent"] = args.equal_pos - right_align_match + context["pattern"] = "([?+:]*=|::=)" + context["right-align-match"] = right_align_match + context["skip-lhs-pattern"] = "[^A-Za-z0-9_# ]" + context["require-lhs-pattern"] = "^[ #]*[A-Za-z0-9_]" + context["skip-short"] = args.skip_short + context["min-assignments"] = args.min_assignments + replacements = {"blah": "blub"} # just a dummy to use _replace_in_file, TODO: obviate the need + for dir, name in files: + path = dir + '/' + name + if self._replace_in_file(path, replacements, func=self._cleanup_spaces): + slog(NOTICE, "+ purged spaces :", path) + if self._replace_in_file(path, replacements, func=self._indent_pattern, context=context): + slog(NOTICE, "+ aligned equals :", path) + +class CmdCppReplaceSymbols(Cmd): + + def __init__(self): + super(CmdCppReplaceSymbols, self).__init__("cpp-replace-symbols", "Replace C++ symbols in files") + + def add_parser(self, parsers): + p = super(CmdCppReplaceSymbols, self).add_parser(parsers) p.add_argument('-F', '--rename-files', help="Rename source files, too", action='store_true', default=False) - p.add_argument('-P', '--mip-prefix', help="Prefix to multiple-inclusion preventer", default='') + p.add_argument('-P', '--ig-prefix', help="Prefix to include guard", default='') return p # overriding def run(self, args): if args.name_regex is not None: - return super(CmdReplaceCppSymbols, self).run(args) + return super(CmdCppReplaceSymbols, self).run(args) self._init(args) files = [] exts = _exts_h_cpp | set([ '.sh', '.py' ]) @@ -362,7 +414,7 @@ class CmdReplaceCppSymbols(Cmd): # overriding def _init(self, args): - r = super(CmdReplaceCppSymbols, self)._init(args) + r = super(CmdCppReplaceSymbols, self)._init(args) self.file_truncs = set() if self.replacements is not None: for patt in self.replacements: @@ -391,46 +443,15 @@ class CmdReplaceCppSymbols(Cmd): subprocess.call(['git', 'mv', path, new_path]) else: os.rename(path, new_path) - self._fix_multiple_inclusion_preventer(args.mip_prefix, new_path) + self._fix_include_guard(args.ig_prefix, new_path) -class CmdIndentMakefileEquals(Cmd): +class CmdCppIndentMacros(Cmd): def __init__(self): - super(CmdIndentMakefileEquals, self).__init__("indent-makefiles", "Indent and beautify makefiles") + super(CmdCppIndentMacros, self).__init__("cpp-indent-macros", "Indent and beautify C/C++ preprocessor macros") def add_parser(self, parsers): - p = super(CmdIndentMakefileEquals, self).add_parser(parsers) - p.add_argument('-e', "--equal-pos", help="Columns number of equal sign", type=int, default=40) - p.add_argument("--skip-short", help="Don't change makefiles with less lines of code", type=int, default=6) - p.add_argument("--min-assignments", help="Don't change makefiles with less assignment statements", type=int, default=4) - return p - - def process(self, args, files): - slog(NOTICE, "Beautifying", len(files), "makefiles:") - context = dict() - right_align_match = 2 - context["indent"] = args.equal_pos - right_align_match - context["pattern"] = "([?+:]*=|::=)" - context["right-align-match"] = right_align_match - context["skip-lhs-pattern"] = "[^A-Za-z0-9_# ]" - context["require-lhs-pattern"] = "^[ #]*[A-Za-z0-9_]" - context["skip-short"] = args.skip_short - context["min-assignments"] = args.min_assignments - replacements = {"blah": "blub"} # just a dummy to use _replace_in_file, TODO: obviate the need - for dir, name in files: - path = dir + '/' + name - if self._replace_in_file(path, replacements, func=self._cleanup_spaces): - slog(NOTICE, "+ purged spaces :", path) - if self._replace_in_file(path, replacements, func=self._indent_pattern, context=context): - slog(NOTICE, "+ aligned equals :", path) - -class CmdIndentCppMacros(Cmd): - - def __init__(self): - super(CmdIndentCppMacros, self).__init__("indent-cpp-macros", "Indent and beautify C/C++ preprocessor macros") - - def add_parser(self, parsers): - p = super(CmdIndentCppMacros, self).add_parser(parsers) + p = super(CmdCppIndentMacros, self).add_parser(parsers) p.add_argument('-w', "--spaces", help="Number of spaces per indentation level", type=int, default=2) p.add_argument('-s', "--skip-outer", help="Skip the outmost macro (read multiple-inclusion guards)", action='store_true', default=True) p.add_argument('-S', "--skip-outer-name-regex", help="Regex for file names that --skip-outer should be applied to", default="\.h$|\.H$|\.hpp$") @@ -449,34 +470,16 @@ class CmdIndentCppMacros(Cmd): context["skip-outer"] = True else: context["skip-outer"] = False - if self._replace_in_file(path, replacements, func=self._indent_cpp_macros, context=context): + if self._replace_in_file(path, replacements, func=self._cpp_indent_macros, context=context): slog(NOTICE, "+ indented C++ macros :", path) -class CmdCleanupSpaces(Cmd): +class CmdCppAddNamespace(Cmd): def __init__(self): - super(CmdCleanupSpaces, self).__init__("cleanup-spaces", "Remove trailing empty lines") + super(CmdCppAddNamespace, self).__init__("cpp-add-namespace", "Enclose C++ classes in namespace") def add_parser(self, parsers): - p = super(CmdCleanupSpaces, self).add_parser(parsers) - return p - - def process(self, args, files): - slog(NOTICE, "Cleaning up unnecessary space in", len(files), "files:") - context = dict() - replacements = {"blah": "blub"} # just a dummy to use _replace_in_file, TODO: obviate the need - for dir, name in files: - path = dir + '/' + name - if self._replace_in_file(path, replacements, func=self._cleanup_spaces, context=context): - slog(NOTICE, "+ purged spaces :", path) - -class CmdAddCppNamespace(Cmd): - - def __init__(self): - super(CmdAddCppNamespace, self).__init__("add-cpp-namespace", "Enclose C++ classes in namespace") - - def add_parser(self, parsers): - p = super(CmdAddCppNamespace, self).add_parser(parsers) + p = super(CmdCppAddNamespace, self).add_parser(parsers) p.add_argument('-n', '--namespace', help="Namespace", default=None) p.add_argument('-p', '--package', help="Package", default=None) return p @@ -484,7 +487,7 @@ class CmdAddCppNamespace(Cmd): # overriding def run(self, args): if args.name_regex is not None: - return super(CmdAddCppNamespace, self).run(args) + return super(CmdCppAddNamespace, self).run(args) self._init(args) files = [] exts = _exts_h_cpp | set([ '.sh', '.py' ]) @@ -497,7 +500,7 @@ class CmdAddCppNamespace(Cmd): # overriding def _init(self, args): - r = super(CmdAddCppNamespace, self)._init(args) + r = super(CmdCppAddNamespace, self)._init(args) self.file_truncs = set() if self.replacements is not None: for patt in self.replacements: @@ -523,4 +526,4 @@ class CmdAddCppNamespace(Cmd): with open(tmp, 'w') as outfile: outfile.write(data) -jwutils.run_sub_commands('process text files') +jwutils.run_sub_commands('Process text files')