diff --git a/scripts/process-text-files.py b/scripts/process-text-files.py index 9bccfd9..bb14c37 100644 --- a/scripts/process-text-files.py +++ b/scripts/process-text-files.py @@ -23,11 +23,61 @@ class Cmd(jwutils.Cmd): super(Cmd, self).__init__(name, help=help) @staticmethod - def _replace_pattern(line, src, target): + def _replace_pattern(line, src, target, context=None): return line.replace(src, target) @staticmethod - def _replace_cpp_symbol(data, src, target): + def _indent_pattern(data, src, target, context=None): + indent = 30 + pattern = '=' + right_align_match = 0 + skip_lhs_pattern = None + require_lhs_pattern = None + skip_short = None + min_assignments = None + if context is not None: + if 'indent' in context: + indent = context['indent'] + if 'pattern' in context: + pattern = context['pattern'] + if 'right-align-match' in context: + right_align_match = context['right-align-match'] + if 'skip-lhs-pattern' in context: + skip_lhs_pattern = context['skip-lhs-pattern'] + if 'require-lhs-pattern' in context: + require_lhs_pattern = context['require-lhs-pattern'] + if 'skip-short' in context: + skip_short = context['skip-short'] + if 'min-assignments' in context: + min_assignments = context['min-assignments'] + r = '' + assignments=0 + lines = data.splitlines() + if skip_short is not None and len(lines) < skip_short: + return data + for line in iter(lines): + #slog(NOTICE, "indenting pattern", pattern, "of", line) + parts = re.split(pattern, line) + if ( + len(parts) < 2 + or (skip_lhs_pattern is not None and re.match(skip_lhs_pattern, parts[0])) + or (require_lhs_pattern is not None and not re.match(require_lhs_pattern, parts[0])) + ): + r += line + '\n' + continue + #slog(NOTICE, "split into", parts) + if right_align_match > 0: + parts[1] = parts[1].rjust(right_align_match) + if len(parts) > 2: + parts[2] = ' ' + parts[2].strip() + r += parts[0].rstrip().ljust(indent) + ''.join(parts[1:]) + '\n' + assignments += 1 + if min_assignments is not None and assignments < min_assignments: + return data + return r + + @staticmethod + def _replace_cpp_symbol(data, src, target, context=None): stopc = "^a-zA-Z0-9_" stopa = "(^|[" + stopc + "])" stope = "([" + stopc + "]|$)" @@ -49,22 +99,27 @@ class Cmd(jwutils.Cmd): # slog(NOTICE, " resulted in ", data, "->", r) return r - def _replace_in_file(self, path, replacements, func=None, backup='rep'): + def _replace_in_file(self, path, replacements, func=None, backup='rep', context=None): if func is None: func = self._replace_pattern - tmp = path + '.' + backup + tmp_ext = backup + if tmp_ext is None: + tmp_ext = tmp + tmp = path + '.' + tmp_ext changed = False with open(path) as infile, open(tmp, 'w') as outfile: data = infile.read() + #slog(NOTICE, "-- opened", path) for src, target in replacements.iteritems(): + #slog(NOTICE, "replacing", src, "to", target) odata = data #data = data.replace(src, target) - data = func(data, src, target) + data = func(data, src, target, context) if data != odata: - #slog(NOTICE, "changed", odata, "to", data, "in", path) changed = True outfile.write(data) if not changed: + os.unlink(tmp) return False if backup is None: @@ -163,12 +218,11 @@ class Cmd(jwutils.Cmd): # overriding def run(self, args): self._init(args) - slog(NOTICE, "running") files = [] if args.name_regex is not None: for root, dirs, names in os.walk(args.root): for name in names: - if re.match(args.name_regex, name): + if re.search(args.name_regex, name): files.append((root, name)) self.process(args, files) @@ -204,7 +258,6 @@ class CmdReplaceCppSymbols(Cmd): if args.name_regex is not None: return super(CmdReplaceCppSymbols, self).run(args) self._init(args) - slog(NOTICE, "running") files = [] exts = _exts_h_cpp | set([ '.sh', '.py' ]) for root, dirs, names in os.walk(args.root): @@ -247,6 +300,35 @@ class CmdReplaceCppSymbols(Cmd): os.rename(path, new_path) self._fix_multiple_inclusion_preventer(args.mip_prefix, new_path) +class CmdIndentMakefileEquals(Cmd): + + def __init__(self): + super(CmdIndentMakefileEquals, self).__init__("indent-makefiles", "Indent and beautify makefiles") + + 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): + 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 + slog(NOTICE, "indenting equal signs in", len(files), "makefiles:") + for dir, name in files: + path = dir + '/' + name + if self._replace_in_file(path, replacements, func=self._indent_pattern, context=context): + slog(NOTICE, "+ changed", path) + class CmdAddCppNamespace(Cmd): def __init__(self): @@ -263,7 +345,6 @@ class CmdAddCppNamespace(Cmd): if args.name_regex is not None: return super(CmdAddCppNamespace, self).run(args) self._init(args) - slog(NOTICE, "running") files = [] exts = _exts_h_cpp | set([ '.sh', '.py' ]) for root, dirs, names in os.walk(args.root):