mirror of
ssh://git.janware.com/srv/git/janware/proj/jw-python
synced 2026-01-15 01:52:56 +01:00
process-text-files.py: Add command indent-makefiles
The command is intended to reformat makefiles in a general fashion. It currently only vertically aligns equal signs in makefiles. Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
parent
0cb09081eb
commit
a4b447375a
1 changed files with 91 additions and 10 deletions
|
|
@ -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):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue