blob: 88d95c247c0630b6f9b49cb24c092374b30bd78c [file] [log] [blame]
serge-sans-paille515bc8c2020-07-15 07:31:131#!/usr/bin/env python3
Michael Krusec0a19b02016-02-29 14:58:132# -*- coding: UTF-8 -*-
3
4# Polly/LLVM update_check.py
5# Update lit FileCheck files by replacing the 'CHECK:' lines by the actual output of the 'RUN:' command.
6
7import argparse
8import os
9import subprocess
10import shlex
11import re
12
13
Tobias Hietaf98ee402023-05-17 14:59:4114polly_src_dir = """@POLLY_SOURCE_DIR@"""
15polly_lib_dir = """@POLLY_LIB_DIR@"""
16shlibext = """@LLVM_SHLIBEXT@"""
17llvm_tools_dir = """@LLVM_TOOLS_DIR@"""
18llvm_polly_link_into_tools = not """@LLVM_POLLY_LINK_INTO_TOOLS@""".lower() in {
19 "",
20 "0",
21 "n",
22 "no",
23 "off",
24 "false",
25 "notfound",
26 "llvm_polly_link_into_tools-notfound",
27}
Michael Krusec0a19b02016-02-29 14:58:1328
Tobias Hietaf98ee402023-05-17 14:59:4129runre = re.compile(r"\s*\;\s*RUN\s*\:(?P<tool>.*)")
30filecheckre = re.compile(r"\s*(?P<tool>.*)\|\s*(?P<filecheck>FileCheck\s[^|]*)")
31emptyline = re.compile(r"\s*(\;\s*)?")
32commentline = re.compile(r"\s*(\;.*)?")
Michael Krusec0a19b02016-02-29 14:58:1333
34
Tobias Hietaf98ee402023-05-17 14:59:4135def ltrim_emptylines(lines, meta=None):
Michael Krusec0a19b02016-02-29 14:58:1336 while len(lines) and emptyline.fullmatch(lines[0]):
37 del lines[0]
38 if meta is not None:
39 del meta[0]
40
41
42def rtrim_emptylines(lines):
43 while len(lines) and emptyline.fullmatch(lines[-1]):
44 del lines[-1]
45
46
47def trim_emptylines(lines):
48 ltrim_emptylines(lines)
49 rtrim_emptylines(lines)
50
51
52def complete_exename(path, filename):
53 complpath = os.path.join(path, filename)
54 if os.path.isfile(complpath):
55 return complpath
Tobias Hietaf98ee402023-05-17 14:59:4156 elif os.path.isfile(complpath + ".exe"):
57 return complpath + ".exe"
Michael Krusec0a19b02016-02-29 14:58:1358 return filename
59
60
61def indention(line):
Tobias Hietaf98ee402023-05-17 14:59:4162 for i, c in enumerate(line):
63 if c != " " and c != "\t":
Michael Krusec0a19b02016-02-29 14:58:1364 return i
65 return None
66
67
68def common_indent(lines):
69 indentions = (indention(line) for line in lines)
70 indentions = (indent for indent in indentions if indent is not None)
Tobias Hietaf98ee402023-05-17 14:59:4171 return min(indentions, default=0)
Michael Krusec0a19b02016-02-29 14:58:1372
73
Tobias Hietaf98ee402023-05-17 14:59:4174funcre = re.compile(r"^ Function: \S*$")
75regionre = re.compile(r"^ Region: \S*$")
76depthre = re.compile(r"^ Max Loop Depth: .*")
77paramre = re.compile(r" [0-9a-z-A-Z_]+\: .*")
78
Michael Krusec0a19b02016-02-29 14:58:1379
80def classyfier1(lines):
81 i = iter(lines)
82 line = i.__next__()
83 while True:
Tobias Hietaf98ee402023-05-17 14:59:4184 if line.startswith(
85 "Printing analysis 'Polly - Calculate dependences' for region: "
86 ):
87 yield {"PrintingDependenceInfo"}
Michael Krusec0a19b02016-02-29 14:58:1388 elif line.startswith("remark: "):
Tobias Hietaf98ee402023-05-17 14:59:4189 yield {"Remark"}
Michael Krusec0a19b02016-02-29 14:58:1390 elif funcre.fullmatch(line):
Tobias Hietaf98ee402023-05-17 14:59:4191 yield {"Function"}
Michael Krusec0a19b02016-02-29 14:58:1392 elif regionre.fullmatch(line):
Tobias Hietaf98ee402023-05-17 14:59:4193 yield {"Region"}
Michael Krusec0a19b02016-02-29 14:58:1394 elif depthre.fullmatch(line):
Tobias Hietaf98ee402023-05-17 14:59:4195 yield {"MaxLoopDepth"}
96 elif line == " Invariant Accesses: {":
Michael Krusec0a19b02016-02-29 14:58:1397 while True:
Tobias Hietaf98ee402023-05-17 14:59:4198 yield {"InvariantAccesses"}
99 if line == " }":
Michael Krusec0a19b02016-02-29 14:58:13100 break
101 line = i.__next__()
Tobias Hietaf98ee402023-05-17 14:59:41102 elif line == " Context:":
103 yield {"Context"}
Michael Krusec0a19b02016-02-29 14:58:13104 line = i.__next__()
Tobias Hietaf98ee402023-05-17 14:59:41105 yield {"Context"}
106 elif line == " Assumed Context:":
107 yield {"AssumedContext"}
Michael Krusec0a19b02016-02-29 14:58:13108 line = i.__next__()
Tobias Hietaf98ee402023-05-17 14:59:41109 yield {"AssumedContext"}
110 elif line == " Invalid Context:":
111 yield {"InvalidContext"}
Michael Kruseb931d4c2016-04-14 15:22:04112 line = i.__next__()
Tobias Hietaf98ee402023-05-17 14:59:41113 yield {"InvalidContext"}
114 elif line == " Boundary Context:":
115 yield {"BoundaryContext"}
Michael Krusec0a19b02016-02-29 14:58:13116 line = i.__next__()
Tobias Hietaf98ee402023-05-17 14:59:41117 yield {"BoundaryContext"}
Michael Krusec0a19b02016-02-29 14:58:13118 line = i.__next__()
119 while paramre.fullmatch(line):
Tobias Hietaf98ee402023-05-17 14:59:41120 yield {"Param"}
Michael Krusec0a19b02016-02-29 14:58:13121 line = i.__next__()
122 continue
Tobias Hietaf98ee402023-05-17 14:59:41123 elif line == " Arrays {":
Michael Krusec0a19b02016-02-29 14:58:13124 while True:
Tobias Hietaf98ee402023-05-17 14:59:41125 yield {"Arrays"}
126 if line == " }":
Michael Krusec0a19b02016-02-29 14:58:13127 break
128 line = i.__next__()
Tobias Hietaf98ee402023-05-17 14:59:41129 elif line == " Arrays (Bounds as pw_affs) {":
Michael Krusec0a19b02016-02-29 14:58:13130 while True:
Tobias Hietaf98ee402023-05-17 14:59:41131 yield {"PwAffArrays"}
132 if line == " }":
Michael Krusec0a19b02016-02-29 14:58:13133 break
134 line = i.__next__()
Tobias Hietaf98ee402023-05-17 14:59:41135 elif line.startswith(" Alias Groups ("):
Michael Krusec0a19b02016-02-29 14:58:13136 while True:
Tobias Hietaf98ee402023-05-17 14:59:41137 yield {"AliasGroups"}
Michael Krusec0a19b02016-02-29 14:58:13138 line = i.__next__()
Tobias Hietaf98ee402023-05-17 14:59:41139 if not line.startswith(" "):
Michael Krusec0a19b02016-02-29 14:58:13140 break
141 continue
Tobias Hietaf98ee402023-05-17 14:59:41142 elif line == " Statements {":
Michael Krusec0a19b02016-02-29 14:58:13143 while True:
Tobias Hietaf98ee402023-05-17 14:59:41144 yield {"Statements"}
145 if line == " }":
Michael Krusec0a19b02016-02-29 14:58:13146 break
147 line = i.__next__()
Tobias Hietaf98ee402023-05-17 14:59:41148 elif line == " RAW dependences:":
149 yield {"RAWDep", "BasicDep", "Dep", "DepInfo"}
Michael Krusec0a19b02016-02-29 14:58:13150 line = i.__next__()
Tobias Hietaf98ee402023-05-17 14:59:41151 while line.startswith(" "):
152 yield {"RAWDep", "BasicDep", "Dep", "DepInfo"}
Michael Krusec0a19b02016-02-29 14:58:13153 line = i.__next__()
154 continue
Tobias Hietaf98ee402023-05-17 14:59:41155 elif line == " WAR dependences:":
156 yield {"WARDep", "BasicDep", "Dep", "DepInfo"}
Michael Krusec0a19b02016-02-29 14:58:13157 line = i.__next__()
Tobias Hietaf98ee402023-05-17 14:59:41158 while line.startswith(" "):
159 yield {"WARDep", "BasicDep", "Dep", "DepInfo"}
Michael Krusec0a19b02016-02-29 14:58:13160 line = i.__next__()
161 continue
Tobias Hietaf98ee402023-05-17 14:59:41162 elif line == " WAW dependences:":
163 yield {"WAWDep", "BasicDep", "Dep", "DepInfo"}
Michael Krusec0a19b02016-02-29 14:58:13164 line = i.__next__()
Tobias Hietaf98ee402023-05-17 14:59:41165 while line.startswith(" "):
166 yield {"WAWDep", "BasicDep", "Dep", "DepInfo"}
Michael Krusec0a19b02016-02-29 14:58:13167 line = i.__next__()
168 continue
Tobias Hietaf98ee402023-05-17 14:59:41169 elif line == " Reduction dependences:":
170 yield {"RedDep", "Dep", "DepInfo"}
Michael Krusec0a19b02016-02-29 14:58:13171 line = i.__next__()
Tobias Hietaf98ee402023-05-17 14:59:41172 while line.startswith(" "):
173 yield {"RedDep", "Dep", "DepInfo"}
Michael Krusec0a19b02016-02-29 14:58:13174 line = i.__next__()
175 continue
Tobias Hietaf98ee402023-05-17 14:59:41176 elif line == " Transitive closure of reduction dependences:":
177 yield {"TransitiveClosureDep", "DepInfo"}
Michael Krusec0a19b02016-02-29 14:58:13178 line = i.__next__()
Tobias Hietaf98ee402023-05-17 14:59:41179 while line.startswith(" "):
180 yield {"TransitiveClosureDep", "DepInfo"}
Michael Krusec0a19b02016-02-29 14:58:13181 line = i.__next__()
182 continue
Michael Kruse6b6e38d2016-08-26 15:43:43183 elif line.startswith("New access function '"):
Tobias Hietaf98ee402023-05-17 14:59:41184 yield {"NewAccessFunction"}
185 elif line == "Schedule before flattening {":
Michael Kruse7886bd72016-09-08 15:02:36186 while True:
Tobias Hietaf98ee402023-05-17 14:59:41187 yield {"ScheduleBeforeFlattening"}
188 if line == "}":
Michael Kruse7886bd72016-09-08 15:02:36189 break
190 line = i.__next__()
Tobias Hietaf98ee402023-05-17 14:59:41191 elif line == "Schedule after flattening {":
Michael Kruse7886bd72016-09-08 15:02:36192 while True:
Tobias Hietaf98ee402023-05-17 14:59:41193 yield {"ScheduleAfterFlattening"}
194 if line == "}":
Michael Kruse7886bd72016-09-08 15:02:36195 break
196 line = i.__next__()
Michael Krusec0a19b02016-02-29 14:58:13197 else:
198 yield set()
199 line = i.__next__()
200
201
202def classyfier2(lines):
203 i = iter(lines)
204 line = i.__next__()
205 while True:
206 if funcre.fullmatch(line):
Tobias Hietaf98ee402023-05-17 14:59:41207 while line.startswith(" "):
208 yield {"FunctionDetail"}
Michael Krusec0a19b02016-02-29 14:58:13209 line = i.__next__()
210 continue
Tobias Hietaf98ee402023-05-17 14:59:41211 elif line.startswith(
212 "Printing analysis 'Polly - Generate an AST from the SCoP (isl)' for region: "
213 ):
214 yield {"PrintingIslAst"}
Michael Krusec0a19b02016-02-29 14:58:13215 line = i.__next__()
Tobias Hietaf98ee402023-05-17 14:59:41216 while not line.startswith("Printing analysis"):
217 yield {"AstDetail"}
Michael Krusec0a19b02016-02-29 14:58:13218 line = i.__next__()
219 continue
220 else:
221 yield set()
222 line = i.__next__()
223
224
Tobias Hietaf98ee402023-05-17 14:59:41225replrepl = {"{{": "{{[{][{]}}", "}}": "{{[}][}]}}", "[[": "{{\[\[}}", "]]": "{{\]\]}}"}
226replre = re.compile("|".join(re.escape(k) for k in replrepl.keys()))
227
Michael Krusec0a19b02016-02-29 14:58:13228
229def main():
230 parser = argparse.ArgumentParser(description="Update CHECK lines")
Tobias Hietaf98ee402023-05-17 14:59:41231 parser.add_argument(
232 "testfile", help="File to update (absolute or relative to --testdir)"
233 )
234 parser.add_argument(
235 "--check-style",
236 choices=["CHECK", "CHECK-NEXT"],
237 default="CHECK-NEXT",
238 help="What kind of checks lines to generate",
239 )
240 parser.add_argument(
241 "--check-position",
242 choices=["end", "before-content", "autodetect"],
243 default="autodetect",
244 help="Where to add the CHECK lines into the file; 'autodetect' searches for the first 'CHECK' line ind inserts it there",
245 )
246 parser.add_argument(
247 "--check-include",
248 action="append",
249 default=[],
250 help="What parts of the output lines to check; use syntax 'CHECK=include' to apply to one CHECK-prefix only (by default, everything)",
251 )
252 parser.add_argument(
253 "--check-label-include",
254 action="append",
255 default=[],
256 help="Use CHECK-LABEL for these includes",
257 )
258 parser.add_argument(
259 "--check-part-newline",
260 action="store_true",
261 help="Add empty line between different check parts",
262 )
263 parser.add_argument(
264 "--prefix-only",
265 action="append",
266 default=None,
267 help="Update only these prefixes (default: all)",
268 )
269 parser.add_argument("--bindir", help="Location of the opt program")
270 parser.add_argument("--testdir", help="Root dir for unit tests")
271 parser.add_argument(
272 "--inplace", "-i", action="store_true", help="Replace input file"
273 )
274 parser.add_argument("--output", "-o", help="Write changed input to this file")
Michael Krusec0a19b02016-02-29 14:58:13275 known = parser.parse_args()
276
277 if not known.inplace and known.output is None:
278 print("Must specify what to do with output (--output or --inplace)")
279 exit(1)
280 if known.inplace and known.output is not None:
281 print("--inplace and --output are mutually exclusive")
282 exit(1)
283
284 outfile = known.output
285
286 filecheckparser = argparse.ArgumentParser(add_help=False)
Tobias Hietaf98ee402023-05-17 14:59:41287 filecheckparser.add_argument("-check-prefix", "--check-prefix", default="CHECK")
Michael Krusec0a19b02016-02-29 14:58:13288
289 filename = known.testfile
Tobias Hietaf98ee402023-05-17 14:59:41290 for dir in [".", known.testdir, os.path.join(polly_src_dir, "test"), polly_src_dir]:
Michael Krusec0a19b02016-02-29 14:58:13291 if not dir:
292 continue
Tobias Hietaf98ee402023-05-17 14:59:41293 testfilename = os.path.join(dir, filename)
Michael Krusec0a19b02016-02-29 14:58:13294 if os.path.isfile(testfilename):
295 filename = testfilename
296 break
297
298 if known.inplace:
299 outfile = filename
300
301 allchecklines = []
302 checkprefixes = []
303
Tobias Hietaf98ee402023-05-17 14:59:41304 with open(filename, "r") as file:
305 oldlines = [line.rstrip("\r\n") for line in file.readlines()]
Michael Krusec0a19b02016-02-29 14:58:13306
307 runlines = []
308 for line in oldlines:
309 m = runre.match(line)
310 if m:
Tobias Hietaf98ee402023-05-17 14:59:41311 runlines.append(m.group("tool"))
Michael Krusec0a19b02016-02-29 14:58:13312
Tobias Hietaf98ee402023-05-17 14:59:41313 continuation = ""
Michael Krusec0a19b02016-02-29 14:58:13314 newrunlines = []
315 for line in runlines:
Tobias Hietaf98ee402023-05-17 14:59:41316 if line.endswith("\\"):
317 continuation += line[:-2] + " "
Michael Krusec0a19b02016-02-29 14:58:13318 else:
319 newrunlines.append(continuation + line)
Tobias Hietaf98ee402023-05-17 14:59:41320 continuation = ""
Michael Krusec0a19b02016-02-29 14:58:13321 if continuation:
322 newrunlines.append(continuation)
323
324 for line in newrunlines:
325 m = filecheckre.match(line)
326 if not m:
327 continue
328
Tobias Hietaf98ee402023-05-17 14:59:41329 tool, filecheck = m.group("tool", "filecheck")
Michael Krusec0a19b02016-02-29 14:58:13330 filecheck = shlex.split(filecheck)
331 tool = shlex.split(tool)
332 if known.bindir is not None:
333 tool[0] = complete_exename(known.bindir, tool[0])
334 if os.path.isdir(llvm_tools_dir):
335 tool[0] = complete_exename(llvm_tools_dir, tool[0])
336 check_prefix = filecheckparser.parse_known_args(filecheck)[0].check_prefix
337 if known.prefix_only is not None and not check_prefix in known.prefix_only:
338 continue
339 if check_prefix in checkprefixes:
340 continue
341 checkprefixes.append(check_prefix)
342
343 newtool = []
344 optstderr = None
345 for toolarg in tool:
Tobias Hietaf98ee402023-05-17 14:59:41346 toolarg = toolarg.replace("%s", filename)
347 toolarg = toolarg.replace("%S", os.path.dirname(filename))
348 if toolarg == "%loadPolly":
serge_sans_paille24ab9b52019-06-08 15:37:47349 if not llvm_polly_link_into_tools:
Tobias Hietaf98ee402023-05-17 14:59:41350 newtool += [
351 "-load",
352 os.path.join(polly_lib_dir, "LLVMPolly" + shlibext),
353 ]
354 newtool.append("-polly-process-unprofitable")
355 newtool.append("-polly-remarks-minimal")
356 elif toolarg == "2>&1":
Michael Krusec0a19b02016-02-29 14:58:13357 optstderr = subprocess.STDOUT
358 else:
359 newtool.append(toolarg)
360 tool = newtool
361
362 inpfile = None
363 i = 1
Tobias Hietaf98ee402023-05-17 14:59:41364 while i < len(tool):
365 if tool[i] == "<":
Michael Krusec0a19b02016-02-29 14:58:13366 inpfile = tool[i + 1]
Tobias Hietaf98ee402023-05-17 14:59:41367 del tool[i : i + 2]
Michael Krusec0a19b02016-02-29 14:58:13368 continue
369 i += 1
370 if inpfile:
371 with open(inpfile) as inp:
Tobias Hietaf98ee402023-05-17 14:59:41372 retlines = subprocess.check_output(
373 tool, universal_newlines=True, stdin=inp, stderr=optstderr
374 )
Michael Krusec0a19b02016-02-29 14:58:13375 else:
Tobias Hietaf98ee402023-05-17 14:59:41376 retlines = subprocess.check_output(
377 tool, universal_newlines=True, stderr=optstderr
378 )
379 retlines = [line.replace("\t", " ") for line in retlines.splitlines()]
Michael Krusec0a19b02016-02-29 14:58:13380 check_include = []
381 for checkme in known.check_include + known.check_label_include:
Tobias Hietaf98ee402023-05-17 14:59:41382 parts = checkme.split("=")
Michael Krusec0a19b02016-02-29 14:58:13383 if len(parts) == 2:
384 if parts[0] == check_prefix:
385 check_include.append(parts[1])
386 else:
387 check_include.append(checkme)
388
389 if check_include:
390 filtered_retlines = []
391 classified_retlines = []
392 lastmatch = None
Tobias Hietaf98ee402023-05-17 14:59:41393 for line, kind in (
394 (line, class1.union(class2))
395 for line, class1, class2 in zip(
396 retlines, classyfier1(retlines), classyfier2(retlines)
397 )
398 ):
Michael Krusec0a19b02016-02-29 14:58:13399 match = kind.intersection(check_include)
400 if match:
401 if lastmatch != match:
Tobias Hietaf98ee402023-05-17 14:59:41402 filtered_retlines.append("")
403 classified_retlines.append({"Separator"})
Michael Krusec0a19b02016-02-29 14:58:13404 filtered_retlines.append(line)
405 classified_retlines.append(kind)
406 lastmatch = match
407
408 retlines = filtered_retlines
409 else:
410 classified_retlines = (set() for line in retlines)
411
412 rtrim_emptylines(retlines)
Tobias Hietaf98ee402023-05-17 14:59:41413 ltrim_emptylines(retlines, classified_retlines)
414 retlines = [
415 replre.sub(lambda m: replrepl[m.group(0)], line) for line in retlines
416 ]
Michael Krusec0a19b02016-02-29 14:58:13417 indent = common_indent(retlines)
418 retlines = [line[indent:] for line in retlines]
419 checklines = []
420 previous_was_empty = True
Tobias Hietaf98ee402023-05-17 14:59:41421 for line, kind in zip(retlines, classified_retlines):
Michael Krusec0a19b02016-02-29 14:58:13422 if line:
Tobias Hietaf98ee402023-05-17 14:59:41423 if known.check_style == "CHECK" and known.check_label_include:
Michael Krusec0a19b02016-02-29 14:58:13424 if not kind.isdisjoint(known.check_label_include):
Tobias Hietaf98ee402023-05-17 14:59:41425 checklines.append("; " + check_prefix + "-LABEL: " + line)
Michael Krusec0a19b02016-02-29 14:58:13426 else:
Tobias Hietaf98ee402023-05-17 14:59:41427 checklines.append("; " + check_prefix + ": " + line)
428 elif known.check_style == "CHECK":
429 checklines.append("; " + check_prefix + ": " + line)
Michael Krusec0a19b02016-02-29 14:58:13430 elif known.check_label_include and known.check_label_include:
431 if not kind.isdisjoint(known.check_label_include):
Tobias Hietaf98ee402023-05-17 14:59:41432 checklines.append("; " + check_prefix + "-LABEL: " + line)
Michael Krusec0a19b02016-02-29 14:58:13433 elif previous_was_empty:
Tobias Hietaf98ee402023-05-17 14:59:41434 checklines.append("; " + check_prefix + ": " + line)
Michael Krusec0a19b02016-02-29 14:58:13435 else:
Tobias Hietaf98ee402023-05-17 14:59:41436 checklines.append("; " + check_prefix + "-NEXT: " + line)
Michael Krusec0a19b02016-02-29 14:58:13437 else:
438 if previous_was_empty:
Tobias Hietaf98ee402023-05-17 14:59:41439 checklines.append("; " + check_prefix + ": " + line)
Michael Krusec0a19b02016-02-29 14:58:13440 else:
Tobias Hietaf98ee402023-05-17 14:59:41441 checklines.append("; " + check_prefix + "-NEXT: " + line)
Michael Krusec0a19b02016-02-29 14:58:13442 previous_was_empty = False
443 else:
Tobias Hietaf98ee402023-05-17 14:59:41444 if not "Separator" in kind or known.check_part_newline:
445 checklines.append(";")
Michael Krusec0a19b02016-02-29 14:58:13446 previous_was_empty = True
447 allchecklines.append(checklines)
448
449 if not checkprefixes:
450 return
451
Tobias Hietaf98ee402023-05-17 14:59:41452 checkre = re.compile(
453 r"^\s*\;\s*("
454 + "|".join([re.escape(s) for s in checkprefixes])
455 + ")(\-NEXT|\-DAG|\-NOT|\-LABEL|\-SAME)?\s*\:"
456 )
Michael Krusec0a19b02016-02-29 14:58:13457 firstcheckline = None
458 firstnoncommentline = None
459 headerlines = []
460 newlines = []
461 uptonowlines = []
462 emptylines = []
463 lastwascheck = False
464 for line in oldlines:
465 if checkre.match(line):
466 if firstcheckline is None:
467 firstcheckline = len(newlines) + len(emptylines)
468 if not lastwascheck:
469 uptonowlines += emptylines
470 emptylines = []
471 lastwascheck = True
472 elif emptyline.fullmatch(line):
473 emptylines.append(line)
474 else:
475 newlines += uptonowlines
476 newlines += emptylines
477 newlines.append(line)
478 emptylines = []
479 uptonowlines = []
480 lastwascheck = False
481
Tobias Hietaf98ee402023-05-17 14:59:41482 for i, line in enumerate(newlines):
Michael Krusec0a19b02016-02-29 14:58:13483 if not commentline.fullmatch(line):
484 firstnoncommentline = i
485 break
486
Tobias Hietaf98ee402023-05-17 14:59:41487 with open(outfile, "w", newline="") as file:
488
Michael Krusec0a19b02016-02-29 14:58:13489 def writelines(lines):
490 for line in lines:
491 file.write(line)
Tobias Hietaf98ee402023-05-17 14:59:41492 file.write("\n")
Michael Krusec0a19b02016-02-29 14:58:13493
Tobias Hietaf98ee402023-05-17 14:59:41494 if firstcheckline is not None and known.check_position == "autodetect":
Michael Krusec0a19b02016-02-29 14:58:13495 writelines(newlines[:firstcheckline])
496 writelines(uptonowlines)
Tobias Hietaf98ee402023-05-17 14:59:41497 for i, checklines in enumerate(allchecklines):
Michael Krusec0a19b02016-02-29 14:58:13498 if i != 0:
Tobias Hietaf98ee402023-05-17 14:59:41499 file.write("\n")
Michael Krusec0a19b02016-02-29 14:58:13500 writelines(checklines)
501 writelines(newlines[firstcheckline:])
502 writelines(emptylines)
Tobias Hietaf98ee402023-05-17 14:59:41503 elif (
504 firstnoncommentline is not None and known.check_position == "before-content"
505 ):
Michael Krusec0a19b02016-02-29 14:58:13506 headerlines = newlines[:firstnoncommentline]
507 rtrim_emptylines(headerlines)
508 contentlines = newlines[firstnoncommentline:]
509 ltrim_emptylines(contentlines)
510
511 writelines(headerlines)
512 for checklines in allchecklines:
Tobias Hietaf98ee402023-05-17 14:59:41513 file.write("\n")
Michael Krusec0a19b02016-02-29 14:58:13514 writelines(checklines)
Tobias Hietaf98ee402023-05-17 14:59:41515 file.write("\n")
Michael Krusec0a19b02016-02-29 14:58:13516 writelines(contentlines)
517 writelines(uptonowlines)
518 writelines(emptylines)
519 else:
520 writelines(newlines)
521 rtrim_emptylines(newlines)
522 for checklines in allchecklines:
Tobias Hietaf98ee402023-05-17 14:59:41523 file.write("\n\n")
Michael Krusec0a19b02016-02-29 14:58:13524 writelines(checklines)
525
526
Tobias Hietaf98ee402023-05-17 14:59:41527if __name__ == "__main__":
Michael Krusec0a19b02016-02-29 14:58:13528 main()