summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/dietcc63
1 files changed, 55 insertions, 8 deletions
diff --git a/scripts/dietcc b/scripts/dietcc
index 540d168..e404397 100755
--- a/scripts/dietcc
+++ b/scripts/dietcc
@@ -21,23 +21,25 @@ if "-E" in sys.argv[1:]:
# https://stackoverflow.com/questions/595305
dietc_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
-def check_result(spr):
+def check_result(spr, debug):
if not spr.returncode: return spr.stdout
print("Failed to run gcc wrapper:", ' '.join(sys.argv), file=sys.stderr)
if spr.stderr:
print(spr.stderr.decode("utf-8"), file=sys.stderr)
+ open("/tmp/dietc.error.c", "wb").write(debug)
assert False
def preprocess_pass(c, meta):
with tempfile.TemporaryDirectory() as tmpdir:
t_file = open(f"{tmpdir}/file.c", "wb")
+ t_file.write(f"#line 1 \"{meta['c_path']}\"\n".encode("utf-8"))
t_file.write(f"#include \"{dietc_dir}/scripts/stdincludes/dietc_defines.h\"\n".encode("utf-8"))
t_file.write(c)
t_file.flush()
dirname = os.path.dirname(os.path.realpath(meta["c_path"]))
return check_result(
subprocess.run(f"{CC} -I{dirname} -E {meta['argstr']} {t_file.name}",
- shell=True, capture_output=True))
+ shell=True, capture_output=True), c)
def strip_after_preprocess_pass(c, meta):
c = re.sub(rb"\[\[[^\]]*\]\]", b"", c)
@@ -45,14 +47,16 @@ def strip_after_preprocess_pass(c, meta):
return c
def dietc_pass(c, meta):
+ c = c.replace(b"# ", b"#line ")
with tempfile.TemporaryDirectory() as tmpdir:
t_file = open(f"{tmpdir}/file.c", "wb")
t_file.write(c)
t_file.flush()
dirname = os.path.dirname(os.path.realpath(meta["c_path"]))
+ args = ' '.join(meta["dietc_args"])
return check_result(
- subprocess.run(f"timeout 5s {dietc_dir}/dietc {t_file.name}",
- shell=True, capture_output=True))
+ subprocess.run(f"timeout 5s {dietc_dir}/dietc {t_file.name} {args}",
+ shell=True, stdout=subprocess.PIPE, stderr=sys.stderr), c)
def final_cleanup_pass(dietc, meta):
# (1) treat builtins as builtins
@@ -134,13 +138,48 @@ def make_external_pass(command):
t_file.write(dietc)
t_file.flush()
return check_result(subprocess.run(f"{command} {t_file.name}",
- shell=True, capture_output=True))
+ shell=True, stdout=subprocess.PIPE, stderr=sys.stderr), dietc)
return pass_
+def strip_line_info(dietc, meta):
+ if "--line-numbers" not in meta["dietc_args"]: return dietc
+ lines = dietc.split(b"\n")
+ insert_after = dict()
+ insert_before = dict()
+ for i, line in enumerate(lines):
+ if not line.startswith(b"#line"): continue
+ before_line, after_line = lines[i-1], lines[i+1]
+ insert_after[before_line] = line
+ insert_before[after_line] = line
+ meta["lineinfo_insert_after"] = insert_after
+ meta["lineinfo_insert_before"] = insert_before
+ return b"\n".join(l for l in lines if not l.startswith(b"#line"))
+
+def reinsert_line_info(dietc, meta):
+ if "--line-numbers" not in meta["dietc_args"]: return dietc
+ lines = dietc.split(b"\n")
+ insert_after = meta["lineinfo_insert_after"]
+ insert_before = meta["lineinfo_insert_before"]
+ final_lines = []
+ for line in lines:
+ if final_lines and final_lines[-1].startswith(b"#line"):
+ final_lines.append(line)
+ elif line in insert_before:
+ final_lines.append(insert_before[line])
+ final_lines.append(line)
+ elif line in insert_after:
+ final_lines.append(line)
+ final_lines.append(insert_after[line])
+ else:
+ final_lines.append(line)
+ return b"\n".join(final_lines)
+
PASSES = [preprocess_pass,
strip_after_preprocess_pass,
dietc_pass,
- final_cleanup_pass]
+ strip_line_info,
+ final_cleanup_pass,
+ reinsert_line_info]
def main():
args = list(map(shlex.quote, sys.argv[1:]))
@@ -150,6 +189,11 @@ def main():
i = args.index("--dietc-pass")
args.pop(i)
PASSES.insert(-1, make_external_pass(args.pop(i)))
+ dietc_args = []
+ while "--dietc-arg" in args:
+ i = args.index("--dietc-arg")
+ args.pop(i)
+ dietc_args.append(args.pop(i))
# then process all of the C files
out_dir = tempfile.TemporaryDirectory()
@@ -163,9 +207,12 @@ def main():
subargs.pop(i_)
argstr = " ".join(subargs)
+ pass_history = []
last = open(c_file, "rb").read()
+ meta = {"c_path": c_file, "argstr": argstr, "dietc_args": dietc_args}
for dietpass in PASSES:
- last = dietpass(last, {"c_path": c_file, "argstr": argstr})
+ last = dietpass(last, meta)
+ pass_history.append(last)
diet_files.append(f"{out_dir.name}/file{i}.c")
with open(diet_files[-1], "wb") as f:
@@ -178,6 +225,6 @@ def main():
if "-c" in args:
args += ["-o", c_files[0].replace(".c", ".o")]
gcc = subprocess.run(f"{CC} {' '.join(args)} -Wno-int-to-pointer-cast -Wno-builtin-declaration-mismatch", shell=True)
- check_result(gcc)
+ check_result(gcc, pass_history[-1] if c_files else b"")
main()
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback