diff --git a/build.zig b/build.zig index 461b9868..b513f1d4 100644 --- a/build.zig +++ b/build.zig @@ -4,26 +4,53 @@ pub fn build(b: *std.build.Builder) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - const arocc_dep = b.anonymousDependency("arocc", @import("arocc/build.zig"), .{ - .target = target, - .optimize = optimize, - }); + const textual = true; + if (!textual) { + const arocc_dep = b.anonymousDependency("arocc", @import("arocc/build.zig"), .{ + .target = target, + .optimize = optimize, + }); - const exe = b.addExecutable(.{ - .name = "universal-headers", - .root_source_file = .{ .path = "src/main.zig" }, - .target = target, - .optimize = optimize, - }); - exe.addModule("arocc", arocc_dep.module("aro")); - b.installArtifact(exe); + const exe = b.addExecutable(.{ + .name = "universal-headers", + .root_source_file = .{ .path = "src/main.zig" }, + .target = target, + .optimize = optimize, + }); + exe.addModule("arocc", arocc_dep.module("aro")); + b.installArtifact(exe); - const run_cmd = b.addRunArtifact(exe); - run_cmd.step.dependOn(b.getInstallStep()); - if (b.args) |args| { - run_cmd.addArgs(args); - } + const run_cmd = b.addRunArtifact(exe); + run_cmd.step.dependOn(b.getInstallStep()); + if (b.args) |args| { + run_cmd.addArgs(args); + } + + const run_step = b.step("run", "Run the app"); + run_step.dependOn(&run_cmd.step); + } else { + const addHeaders = b.addExecutable(.{ + .name = "addHeaders", + .root_source_file = .{ .path = "src/textdiff/addHeaders.zig" }, + .target = target, + .optimize = optimize, + }); + b.installArtifact(addHeaders); - const run_step = b.step("run", "Run the app"); - run_step.dependOn(&run_cmd.step); + const outputHeaders = b.addExecutable(.{ + .name = "outputHeaders", + .root_source_file = .{ .path = "src/textdiff/outputHeaders.zig" }, + .target = target, + .optimize = optimize, + }); + b.installArtifact(outputHeaders); + + const testHeaders = b.addExecutable(.{ + .name = "testHeaders", + .root_source_file = .{ .path = "src/textdiff/testHeaders.zig" }, + .target = target, + .optimize = optimize, + }); + b.installArtifact(testHeaders); + } } diff --git a/src/textdiff/HOWTO.txt b/src/textdiff/HOWTO.txt new file mode 100644 index 00000000..d9159a2a --- /dev/null +++ b/src/textdiff/HOWTO.txt @@ -0,0 +1,31 @@ + +zig build +- should give you (in zig-out/bin): addHeaders, outputHeaders, testHeaders +- also shells out to diff + + +for the whole thing, run (for me this takes ~30min): +./src/textdiff/compile.bash headers/* + +then to test (takes ~5min): +./src/textdiff/test.bash headers/* + + +What's going on: + +1. addHeaders headers/foo +- takes files from foo +- normalizes them into uh_norm +- for each file: + - adds context prefix to each line + - outputs to uh_workfile + - diffs with file in uh_workspace and modifies uh_workspace + +2. outputHeaders uh_headers +- reads files from uh_workspace and outputs universal headers in uh_headers +- uses reductions.zig to reduce #if statements + +3. testHeaders headers/foo +- partially evaluates uh_headers for version foo and outputs to uh_test +- can then diff uh_test uh_norm/foo + diff --git a/src/textdiff/addHeaders.zig b/src/textdiff/addHeaders.zig new file mode 100644 index 00000000..279cf688 --- /dev/null +++ b/src/textdiff/addHeaders.zig @@ -0,0 +1,504 @@ +const std = @import("std"); + +const debug = false; + +pub fn main() !void { + var arena_allocator = std.heap.ArenaAllocator.init(std.heap.page_allocator); + const arena = arena_allocator.allocator(); + + var args = try std.process.argsWithAllocator(arena); + + { + var i: usize = 0; + while (args.skip()) { + i += 1; + } + + if (i != 2) { + std.debug.print("usage: addHeaders \n", .{}); + std.debug.print("normalizes headers from into uh_norm/\n", .{}); + std.debug.print("adds headers from uh_norm/ into uh_workspace\n", .{}); + return; + } + } + + args = try std.process.argsWithAllocator(arena); + _ = args.skip(); + const headerDir = args.next() orelse return; + + var buf = try arena.alloc(u8, 1000); + + const normalized_dir = try std.fmt.bufPrint(buf, "uh_norm/{s}", .{std.fs.path.basename(headerDir)}); + std.fs.cwd().makePath(normalized_dir) catch {}; + + buf = try arena.alloc(u8, 1000); + const versionStr = try std.fmt.bufPrint(buf, "{s}|", .{std.fs.path.basename(headerDir)}); + + var dir = try std.fs.cwd().openIterableDir(headerDir, .{}); + defer dir.close(); + + std.fs.cwd().makeDir("uh_workspace") catch {}; + + var walker = try dir.walk(arena); + while (try walker.next()) |entry| { + + // only process files and sym links - right now we copy the sym links into regular files + if (entry.kind != .file and entry.kind != .sym_link) { + continue; + } + + //if (!std.mem.eql(u8, entry.basename, "ucontext.h")) continue; + + //std.debug.print("entry: base {s} path {s}\n", .{ entry.basename, entry.path }); + + // file extension for our sidecar version information + const extra = ".uhversion.txt"; + + var filepath = try std.fs.path.join(arena, &.{ headerDir, entry.path }); + var workpath = try std.fs.path.join(arena, &.{ "uh_workspace", entry.path }); + var normalized_path = try std.fs.path.join(arena, &.{ normalized_dir, entry.path }); + + // read all the lines of our work-in-progress file + var worklines = std.ArrayList([]const u8).init(arena); + { + if (debug) std.debug.print("createFile {s}\n", .{workpath}); + if (std.fs.path.dirname(workpath)) |dirname| { + try std.fs.cwd().makePath(dirname); + } + var file = try std.fs.cwd().createFile(workpath, .{ .read = true, .truncate = false }); + defer file.close(); + var contents = try file.reader().readAllAlloc(arena, 100 * 1024 * 1024); + + while (contents.len > 0 and contents[contents.len - 1] == '\n') { + contents = contents[0 .. contents.len - 1]; + } + + if (contents.len > 0) { + var it = std.mem.splitScalar(u8, contents, '\n'); + + while (it.next()) |line| { + try worklines.append(line); + } + } + } + + // read all the lines of our work-in-progress sidecar version file + buf = try arena.alloc(u8, 1000); + const versionpath = try std.fmt.bufPrint(buf, "{s}{s}", .{ workpath, extra }); + var versionlines = std.ArrayList([]const u8).init(arena); + { + var file = try std.fs.cwd().createFile(versionpath, .{ .read = true, .truncate = false }); + defer file.close(); + var contents = try file.reader().readAllAlloc(arena, 100 * 1024 * 1024); + while (contents.len > 0 and contents[contents.len - 1] == '\n') { + contents = contents[0 .. contents.len - 1]; + } + + if (contents.len > 0) { + var it = std.mem.splitScalar(u8, contents, '\n'); + while (it.next()) |line| { + try versionlines.append(line); + } + } + } + + // read all the lines of the new file we are going to merge + var filelines = std.ArrayList([]const u8).init(arena); + { + var file = try std.fs.cwd().openFile(filepath, .{}); + defer file.close(); + var contents = try file.reader().readAllAlloc(arena, 100 * 1024 * 1024); + + // filter out comments (both /**/ and // styles) + var i: usize = 0; + var k: usize = 0; + var in_comment = false; + while (i < contents.len) { + if (i + 1 < contents.len) { + if (!in_comment and std.mem.eql(u8, contents[i..][0..2], "/*")) { + in_comment = true; + i += 2; + continue; + } + + if (in_comment and std.mem.eql(u8, contents[i..][0..2], "*/")) { + in_comment = false; + i += 2; + continue; + } + + if (!in_comment and std.mem.eql(u8, contents[i..][0..2], "//")) { + // skip until we get to a newline + while (contents[i] != '\n') { + i += 1; + } + continue; + } + } + + if (!in_comment) { + contents[k] = contents[i]; + k += 1; + } + + i += 1; + } + + contents.len = k; + + while (contents.len > 0 and contents[contents.len - 1] == '\n') { + contents = contents[0 .. contents.len - 1]; + } + + if (contents.len > 0) { + var it = std.mem.splitScalar(u8, contents, '\n'); + while (it.next()) |line| { + // normalize whitespace (replace tabs with spaces) + buf = try arena.alloc(u8, line.len); + _ = std.mem.replace(u8, line, "\t", " ", buf); + + // filter out empty lines + var empty = true; + for (buf) |ch| { + if (ch != ' ') { + empty = false; + break; + } + } + + if (!empty) { + try filelines.append(buf); + } + } + } + + // write out normalized file back to disk for debugging + { + if (std.fs.path.dirname(normalized_path)) |dirname| { + try std.fs.cwd().makePath(dirname); + } + var nfile = try std.fs.cwd().createFile(normalized_path, .{}); + defer nfile.close(); + var writer = nfile.writer(); + for (filelines.items) |line| { + try writer.print("{s}\n", .{line}); + } + } + } + + // first add context to the new file + // - this prepends each line with a hash value + // - solves diff problems later by keeping #if-#endif blocks and comment blocks together + try addContext(arena, &filelines); + + // write out the new file with added context to a temp file + { + var file = try std.fs.cwd().createFile("uh_workfile", .{}); + defer file.close(); + var writer = file.writer(); + for (filelines.items) |line| { + try writer.print("{s}\n", .{line}); + } + } + + //std.debug.print("filepath: {s}, workpath: {s}\n", .{ filepath, workpath }); + + // run diff and get the output + var diff_stdout = std.ArrayList(u8).init(arena); + var diff_stderr = std.ArrayList(u8).init(arena); + var diff_child = std.process.Child.init(&.{ "diff", "-wdN", workpath, "uh_workfile" }, arena); + diff_child.stdout_behavior = .Pipe; + diff_child.stderr_behavior = .Pipe; + try diff_child.spawn(); + try diff_child.collectOutput(&diff_stdout, &diff_stderr, 20 * 1024 * 1024); + _ = try diff_child.wait(); + + //std.debug.print("diff says:\n{s}\n", .{diff_stdout.items}); + + // worklines has all lines accumulated from headers so far + // versionlines has versions for all lines in worklines + // filelines has new header lines + + // go through diff output and adjust worklines and versionlines + var line_adj: isize = 0; + var ignore: usize = 0; + var last_line: usize = 0; + + var it = std.mem.splitScalar(u8, diff_stdout.items, '\n'); + while (it.next()) |line| { + if (ignore > 0) { + if (debug) std.debug.print("ignore {d} {s}\n", .{ ignore, line }); + ignore -= 1; + continue; + } + + if (std.mem.eql(u8, line, "")) { + // diff might be empty or end with an empty line + } else if (std.mem.indexOfScalar(u8, line, 'a')) |p| { + const before = line[0..p]; + const after = line[p + 1 ..]; + const addafter = try std.fmt.parseInt(usize, before, 10); + var start: usize = undefined; + var end: usize = undefined; + if (std.mem.indexOfScalar(u8, after, ',')) |pc| { + start = try std.fmt.parseInt(usize, after[0..pc], 10); + end = try std.fmt.parseInt(usize, after[pc + 1 ..], 10); + } else { + start = try std.fmt.parseInt(usize, after, 10); + end = start; + } + + start -= 1; + + if (debug) std.debug.print("diff a says {s} -> {d}-{d}\n", .{ line, start, end }); + + // from line_adj to addafter, the lines were the same, so add the version + for (last_line..@intCast(line_adj + @as(isize, @intCast(addafter)))) |i| { + const old = versionlines.items[i]; + buf = try arena.alloc(u8, old.len + versionStr.len); + versionlines.items[i] = try std.fmt.bufPrint(buf, "{s}{s}", .{ old, versionStr }); + } + + // add lines start..end from new header after line addafter + const where: usize = @intCast(line_adj + @as(isize, @intCast(addafter))); + try worklines.insertSlice(where, filelines.items[start..end]); + //std.debug.print("versionlines.len {d}\n", .{versionlines.items.len}); + for (0..end - start) |_| { + try versionlines.insert(where, versionStr); + } + + //std.debug.print("versionlines.len {d}\n", .{versionlines.items.len}); + + last_line = where + end - start; + line_adj += @intCast(end - start); + ignore = end - start; + } else if (std.mem.indexOfScalar(u8, line, 'c')) |p| { + var start1: usize = undefined; + var end1: usize = undefined; + var start2: usize = undefined; + var end2: usize = undefined; + + const before = line[0..p]; + if (std.mem.indexOfScalar(u8, before, ',')) |pc| { + start1 = try std.fmt.parseInt(usize, before[0..pc], 10); + end1 = try std.fmt.parseInt(usize, before[pc + 1 ..], 10); + } else { + start1 = try std.fmt.parseInt(usize, before, 10); + end1 = start1; + } + start1 -= 1; + + const after = line[p + 1 ..]; + if (std.mem.indexOfScalar(u8, after, ',')) |pc| { + start2 = try std.fmt.parseInt(usize, after[0..pc], 10); + end2 = try std.fmt.parseInt(usize, after[pc + 1 ..], 10); + } else { + start2 = try std.fmt.parseInt(usize, after, 10); + end2 = start2; + } + start2 -= 1; + + if (debug) std.debug.print("diff c says {s} -> {d}-{d} to {d}-{d}\n", .{ line, start1, end1, start2, end2 }); + + // from line_adj to start1, the lines were the same, so add the version + for (last_line..@intCast(line_adj + @as(isize, @intCast(start1)))) |i| { + const old = versionlines.items[i]; + buf = try arena.alloc(u8, old.len + versionStr.len); + versionlines.items[i] = try std.fmt.bufPrint(buf, "{s}{s}", .{ old, versionStr }); + } + + const where: usize = @intCast(line_adj + @as(isize, @intCast(end1))); + try worklines.insertSlice(where, filelines.items[start2..end2]); + for (0..end2 - start2) |_| { + try versionlines.insert(where, versionStr); + } + last_line = where + end2 - start2; + line_adj += @intCast(end2 - start2); + ignore = end1 - start1 + end2 - start2 + 1; + //std.debug.print("setting ignore to {d} {d} {d} {d} {d}\n", .{ ignore, start1, end1, start2, end2 }); + } else if (std.mem.indexOfScalar(u8, line, 'd')) |p| { + const before = line[0..p]; + + var start: usize = undefined; + var end: usize = undefined; + if (std.mem.indexOfScalar(u8, before, ',')) |pc| { + start = try std.fmt.parseInt(usize, before[0..pc], 10); + end = try std.fmt.parseInt(usize, before[pc + 1 ..], 10); + } else { + start = try std.fmt.parseInt(usize, before, 10); + end = start; + } + + start -= 1; + + if (debug) std.debug.print("diff d says {s} -> {d}-{d}\n", .{ line, start, end }); + + for (last_line..@intCast(line_adj + @as(isize, @intCast(start)))) |i| { + const old = versionlines.items[i]; + buf = try arena.alloc(u8, old.len + versionStr.len); + versionlines.items[i] = try std.fmt.bufPrint(buf, "{s}{s}", .{ old, versionStr }); + } + + // we just skip over the lines + ignore = end - start; + last_line = @intCast(line_adj + @as(isize, @intCast(end))); + } else { + //std.debug.print("diff says {s}\n", .{line}); + return error.asdf; + } + } + + // from line_adj to the end, the lines must have been the same + //std.debug.print("last_line {d} {d}\n", .{ last_line, versionlines.items.len }); + for (last_line..versionlines.items.len) |i| { + const old = versionlines.items[i]; + buf = try arena.alloc(u8, old.len + versionStr.len); + versionlines.items[i] = try std.fmt.bufPrint(buf, "{s}{s}", .{ old, versionStr }); + } + + // write out work-in-progress file back to disk + { + var file = try std.fs.cwd().createFile(workpath, .{}); + defer file.close(); + var writer = file.writer(); + for (worklines.items) |line| { + try writer.print("{s}\n", .{line}); + } + } + + // write out work-in-progress sidecar version file back to disk + { + var file = try std.fs.cwd().createFile(versionpath, .{}); + defer file.close(); + var writer = file.writer(); + for (versionlines.items) |line| { + try writer.print("{s}\n", .{line}); + } + } + } +} + +// Prepend each line of this file with a hash to prevent the diff from splitting #if/#endif into separate versions +pub fn addContext(arena: std.mem.Allocator, lines: *std.ArrayList([]const u8)) !void { + var seen_contexts = std.ArrayList(u32).init(arena); + var context = std.ArrayList(u32).init(arena); + try context.append(0); + var in_comment: bool = false; + for (lines.items, 0..) |line, i| { + if ((i + 1) == lines.items.len and std.mem.eql(u8, line, "")) { + // don't add a line after last newline + break; + } + + var pop_context: bool = false; + + var com = in_comment; + if (!in_comment and std.mem.indexOf(u8, line, "/*") != null and std.mem.indexOf(u8, line, "*/") == null) { + in_comment = true; + } else if (in_comment and std.mem.indexOf(u8, line, "/*") == null and std.mem.indexOf(u8, line, "*/") != null) { + in_comment = false; // next line will be out of comment + pop_context = true; + } + + if (!com) { + // could be spaces between # and directive + var trimmed = std.mem.trimLeft(u8, line, " "); + if (std.mem.startsWith(u8, trimmed, "#")) { + trimmed = trimmed[1..]; + trimmed = std.mem.trimLeft(u8, trimmed, " "); + if (std.mem.startsWith(u8, trimmed, "if")) { + var ctx = newContext(lines.items, i, context.items[context.items.len - 1]); + for (seen_contexts.items) |sc| { + if (ctx == sc) { + ctx += 1; + } + } + try context.append(ctx); + try seen_contexts.append(ctx); + } else if (std.mem.startsWith(u8, trimmed, "endif")) { + pop_context = true; + } + } + } + + if (!com and in_comment) { + // just transitioned into a comment + // need to context the comments as well otherwise it might break into two pieces + var ii = i; + const fnv = std.hash.Fnv1a_32; + var h = fnv.init(); + h.value = context.items[context.items.len - 1]; + while (true) : (ii += 1) { + h.update(lines.items[ii]); + h.update("1"); // update even on an empty line + if (std.mem.indexOf(u8, lines.items[ii], "/*") == null and std.mem.indexOf(u8, lines.items[ii], "*/") != null) { + break; + } + } + var ctx = h.final(); + for (seen_contexts.items) |sc| { + if (ctx == sc) { + ctx += 1; + } + } + try context.append(ctx); + try seen_contexts.append(ctx); + } + + var buf = try arena.alloc(u8, 9 + line.len); + lines.items[i] = try std.fmt.bufPrint(buf, "{x:0<8} {s}", .{ context.items[context.items.len - 1], line }); + + if (pop_context) { + _ = context.pop(); + } + } +} + +// We are given the line containing the first #if +// - hash that line, any #elif, and the #endif line together +// - must skip over any nested #if blocks (and comments) +pub fn newContext(lines: [][]const u8, i: usize, ctx: u32) u32 { + const fnv = std.hash.Fnv1a_32; + var h = fnv.init(); + h.value = ctx; + if (debug) std.debug.print("updating hash: {s}\n", .{lines[i]}); + h.update(lines[i]); + var ii = i + 1; + var depth: usize = 0; + var in_comment: bool = false; + while (ii < lines.len) : (ii += 1) { + const line = lines[ii]; + var com = in_comment; + if (!in_comment and std.mem.indexOf(u8, line, "/*") != null and std.mem.indexOf(u8, line, "*/") == null) { + in_comment = true; + } else if (in_comment and std.mem.indexOf(u8, line, "/*") == null and std.mem.indexOf(u8, line, "*/") != null) { + in_comment = false; // next line will be out of comment + } + if (debug) std.debug.print("{s} {d} {s}\n", .{ if (com) "c" else " ", depth, line }); + if (com) { + continue; + } + var trimmed = std.mem.trimLeft(u8, line, " "); + if (std.mem.startsWith(u8, trimmed, "#")) { + trimmed = trimmed[1..]; + trimmed = std.mem.trimLeft(u8, trimmed, " "); + if (std.mem.startsWith(u8, trimmed, "if")) { + depth += 1; + } else if (std.mem.startsWith(u8, trimmed, "elif")) { + if (depth == 0) { + if (debug) std.debug.print("updating hash: {s}\n", .{line}); + h.update(line); + } + } else if (std.mem.startsWith(u8, trimmed, "endif")) { + if (depth == 0) { + if (debug) std.debug.print("updating hash: {s}\n", .{line}); + h.update(line); + break; + } + depth -|= 1; + } + } + } + + return h.final(); +} diff --git a/src/textdiff/compile.bash b/src/textdiff/compile.bash new file mode 100755 index 00000000..5b69735b --- /dev/null +++ b/src/textdiff/compile.bash @@ -0,0 +1,32 @@ + +# example: ./src/textdiff/compile.bash headers/* +# +# then run ./src/textdiff/test.bash headers/* + +HEADER_LIST="$@" + +# check that all headers exist somewhere in reductions.zig - this check is to +# make sure when new headers are added reductions.zig is updated +for i in $HEADER_LIST; +do + grep -q `basename $i` src/textdiff/reductions.zig || { echo "couldn't find '`basename $i`' in reductions.zig, is it new?"; exit 1; } +done + +if [ -d uh_workspace ]; +then + echo "directory uh_workspace already exists, need to remove it - rm -r uh_* ?" + exit 1 +fi + +for i in $HEADER_LIST; +do + echo "addHeaders $i" + ./zig-out/bin/addHeaders $i || exit 1 +done + + +echo "outputHeaders" +./zig-out/bin/outputHeaders uh_headers || exit 1 + + +exit 0 diff --git a/src/textdiff/outputHeaders.zig b/src/textdiff/outputHeaders.zig new file mode 100644 index 00000000..872436bd --- /dev/null +++ b/src/textdiff/outputHeaders.zig @@ -0,0 +1,220 @@ +const std = @import("std"); +const reductions = @import("reductions.zig"){}; + +pub fn main() !void { + var arena_allocator = std.heap.ArenaAllocator.init(std.heap.page_allocator); + const arena = arena_allocator.allocator(); + + var args = try std.process.argsWithAllocator(arena); + + { + var i: usize = 0; + while (args.skip()) { + i += 1; + } + + if (i != 2 and i != 3) { + std.debug.print("usage: outputHeaders [version]\n", .{}); + std.debug.print("takes headers from uh_workspace and outputs to \n", .{}); + std.debug.print("if version is given, only output lines matching that version (for testing)\n", .{}); + return; + } + } + + args = try std.process.argsWithAllocator(arena); + _ = args.skip(); + const outDir = args.next() orelse return; + const versionStr = args.next(); + + var dir = try std.fs.cwd().openIterableDir("uh_workspace", .{}); + defer dir.close(); + + var walker = try dir.walk(arena); + while (try walker.next()) |entry| { + if (entry.kind != .file) { + continue; + } + + const extra = ".uhversion.txt"; + + if (std.mem.endsWith(u8, entry.path, extra)) { + continue; + } + + //if (!std.mem.eql(u8, entry.basename, "features.h")) continue; + + //std.debug.print("entry: base {s} path {s}\n", .{ entry.basename, entry.path }); + + // read work-in-progress file into memory + var workpath = try std.fs.path.join(arena, &.{ "uh_workspace", entry.path }); + var worklines = std.ArrayList([]const u8).init(arena); + { + var file = try std.fs.cwd().openFile(workpath, .{}); + defer file.close(); + var contents = try file.reader().readAllAlloc(arena, 100 * 1024 * 1024); + while (contents.len > 0 and contents[contents.len - 1] == '\n') { + contents = contents[0 .. contents.len - 1]; + } + + if (contents.len > 0) { + var it = std.mem.splitScalar(u8, contents, '\n'); + while (it.next()) |line| { + try worklines.append(line); + } + } + } + + // read work-in-progress sidecar version file into memory + var buf = try arena.alloc(u8, 1000); + const versionpath = try std.fmt.bufPrint(buf, "{s}{s}", .{ workpath, extra }); + var versionlines = std.ArrayList([]const u8).init(arena); + { + var file = try std.fs.cwd().openFile(versionpath, .{}); + defer file.close(); + var contents = try file.reader().readAllAlloc(arena, 100 * 1024 * 1024); + while (contents.len > 0 and contents[contents.len - 1] == '\n') { + contents = contents[0 .. contents.len - 1]; + } + + if (contents.len > 0) { + var it = std.mem.splitScalar(u8, contents, '\n'); + while (it.next()) |line| { + try versionlines.append(line); + } + } + } + + // make writer to output file that will be our universal header + var filepath = try std.fs.path.join(arena, &.{ outDir, entry.path }); + if (std.fs.path.dirname(filepath)) |dirname| { + try std.fs.cwd().makePath(dirname); + } + //std.debug.print("createFile {s}\n", .{filepath}); + var outfile = try std.fs.cwd().createFile(filepath, .{}); + defer outfile.close(); + var outwriter = outfile.writer(); + + if (versionStr) |version| { + // this is for debugging + for (worklines.items, versionlines.items) |workline, versionline| { + if (std.mem.indexOf(u8, versionline, version) != null) { + try outwriter.print("{s}\n", .{workline[9..]}); + } + } + } else { + // output the universal header + // - we maintain a stack of the version #if blocks we are inside of + // - if the version changes, then either: + // - - it is a subset of the previous version, so we can add a new nested #if block + // - - it is not a subset, so #endif the block and start a new one + var versionstack = std.ArrayList([]const u8).init(arena); + for (worklines.items, versionlines.items) |workline, versionline| { + if (versionstack.items.len > 0 and std.mem.eql(u8, versionline, versionstack.items[versionstack.items.len - 1])) { + // line is a continuation + try outwriter.print("{s}\n", .{workline[9..]}); + } else { + // version changed + + // are we changing to a subset? + var subset: bool = false; + while (versionstack.items.len > 0) { + subset = true; + var vit = std.mem.splitScalar(u8, versionline, '|'); + while (vit.next()) |version| { + if (std.mem.eql(u8, version, "")) { + continue; + } + + if (std.mem.indexOf(u8, versionstack.items[versionstack.items.len - 1], version) == null) { + subset = false; + break; + } + } + + if (subset) { + break; + } else { + _ = versionstack.pop(); + try outwriter.print("#endif /*_ZIG_UH_*/\n", .{}); + } + } + + if (versionstack.items.len > 0 and std.mem.eql(u8, versionline, versionstack.items[versionstack.items.len - 1])) { + // we popped to an exact match of our version, so can continue without a new #if + try outwriter.print("{s}\n", .{workline[9..]}); + } else { + + // we've put any #endif we need, now start a new #if + try outputIfLine(arena, outwriter, versionline); + + try versionstack.append(versionline); + + //for (versionstack.items) |vline| { + // try outwriter.print("//vline {s}\n", .{vline}); + //} + + try outwriter.print("{s}\n", .{workline[9..]}); + } + } + } + + while (versionstack.items.len > 0) { + _ = versionstack.pop(); + try outwriter.print("#endif /*_ZIG_UH_*/\n", .{}); + } + } + } +} + +pub fn outputIfLine(arena: std.mem.Allocator, writer: anytype, versionline: []const u8) !void { + var vit = std.mem.splitScalar(u8, versionline, '|'); + var versions = std.StringArrayHashMap(void).init(arena); + while (vit.next()) |version| { + if (std.mem.eql(u8, version, "")) { + continue; + } + + try versions.put(version, {}); + } + + var replacements = std.ArrayList([]const u8).init(arena); + + inline for (@typeInfo(@TypeOf(reductions)).Struct.fields) |f| { + const field = @field(reductions, f.name); + var found_all = true; + for (0..field.len - 1) |i| { + // are all of this reduction's versions here? + if (!versions.contains(field[i])) { + found_all = false; + break; + } + } + + if (found_all) { + // we can replace all these versions with the reduction + for (0..field.len - 1) |i| { + _ = versions.orderedRemove(field[i]); + } + + try replacements.append(field[field.len - 1]); + } + } + + try writer.print("#if ", .{}); + var first_v: bool = true; + for (replacements.items) |rep| { + if (!first_v) { + try writer.print(" OR ", .{}); + } + first_v = false; + try writer.print("{s}", .{rep}); + } + for (versions.keys()) |version| { + if (!first_v) { + try writer.print(" OR ", .{}); + } + first_v = false; + try writer.print("defined {s}", .{version}); + } + try writer.print(" OR _ZIG_UH_\n", .{}); +} diff --git a/src/textdiff/reductions.zig b/src/textdiff/reductions.zig new file mode 100644 index 00000000..020feccf --- /dev/null +++ b/src/textdiff/reductions.zig @@ -0,0 +1,1352 @@ +/// For each field in this file, if all of the given versions are in the same +/// #if line, we replace it with the final line +aarch64_linux_gnu: []const []const u8 = &[_][]const u8{ + "aarch64_be-linux-gnu.2.32", + "aarch64_be-linux-gnu.2.33", + "aarch64_be-linux-gnu.2.34", + "aarch64_be-linux-gnu.2.35", + "aarch64_be-linux-gnu.2.36", + "aarch64_be-linux-gnu.2.37", + "aarch64_be-linux-gnu.2.38", + "aarch64-linux-gnu.2.32", + "aarch64-linux-gnu.2.33", + "aarch64-linux-gnu.2.34", + "aarch64-linux-gnu.2.35", + "aarch64-linux-gnu.2.36", + "aarch64-linux-gnu.2.37", + "aarch64-linux-gnu.2.38", + "(defined __aarch64__ AND defined __GLIBC__)", // FIXME +}, + +arc_linux_gnu: []const []const u8 = &[_][]const u8{ + "arc-linux-gnu.2.32", + "arc-linux-gnu.2.33", + "arc-linux-gnu.2.34", + "arc-linux-gnu.2.35", + "arc-linux-gnu.2.36", + "arc-linux-gnu.2.37", + "arc-linux-gnu.2.38", + "arc-linux-gnuhf.2.32", + "arc-linux-gnuhf.2.33", + "arc-linux-gnuhf.2.34", + "arc-linux-gnuhf.2.35", + "arc-linux-gnuhf.2.36", + "arc-linux-gnuhf.2.37", + "arc-linux-gnuhf.2.38", + "(defined __arc__ AND defined __GLIBC__)", // FIXME +}, + +arm_linux_gnu: []const []const u8 = &[_][]const u8{ + "armeb-linux-gnueabi.2.32", + "armeb-linux-gnueabi.2.33", + "armeb-linux-gnueabi.2.34", + "armeb-linux-gnueabi.2.35", + "armeb-linux-gnueabi.2.36", + "armeb-linux-gnueabi.2.37", + "armeb-linux-gnueabi.2.38", + "armeb-linux-gnueabihf.2.32", + "armeb-linux-gnueabihf.2.33", + "armeb-linux-gnueabihf.2.34", + "armeb-linux-gnueabihf.2.35", + "armeb-linux-gnueabihf.2.36", + "armeb-linux-gnueabihf.2.37", + "armeb-linux-gnueabihf.2.38", + "arm-linux-gnueabi.2.32", + "arm-linux-gnueabi.2.33", + "arm-linux-gnueabi.2.34", + "arm-linux-gnueabi.2.35", + "arm-linux-gnueabi.2.36", + "arm-linux-gnueabi.2.37", + "arm-linux-gnueabi.2.38", + "arm-linux-gnueabihf.2.32", + "arm-linux-gnueabihf.2.33", + "arm-linux-gnueabihf.2.34", + "arm-linux-gnueabihf.2.35", + "arm-linux-gnueabihf.2.36", + "arm-linux-gnueabihf.2.37", + "arm-linux-gnueabihf.2.38", + "arm-linux-gnueabihf-v7a.2.32", + "arm-linux-gnueabihf-v7a.2.33", + "arm-linux-gnueabihf-v7a.2.34", + "arm-linux-gnueabihf-v7a.2.35", + "arm-linux-gnueabihf-v7a.2.36", + "arm-linux-gnueabihf-v7a.2.37", + "arm-linux-gnueabihf-v7a.2.38", + "arm-linux-gnueabi-v4t.2.32", + "arm-linux-gnueabi-v4t.2.33", + "arm-linux-gnueabi-v4t.2.34", + "arm-linux-gnueabi-v4t.2.35", + "arm-linux-gnueabi-v4t.2.36", + "arm-linux-gnueabi-v4t.2.37", + "arm-linux-gnueabi-v4t.2.38", + "(defined __arm__ AND defined __GLIBC__)", // FIXME +}, + +csky_linux_gnu: []const []const u8 = &[_][]const u8{ + "csky-linux-gnuabiv2.2.33", + "csky-linux-gnuabiv2.2.34", + "csky-linux-gnuabiv2.2.35", + "csky-linux-gnuabiv2.2.36", + "csky-linux-gnuabiv2.2.37", + "csky-linux-gnuabiv2.2.38", + "csky-linux-gnuabiv2-soft.2.33", + "csky-linux-gnuabiv2-soft.2.34", + "csky-linux-gnuabiv2-soft.2.35", + "csky-linux-gnuabiv2-soft.2.36", + "csky-linux-gnuabiv2-soft.2.37", + "csky-linux-gnuabiv2-soft.2.38", + "(defined __csky__ AND defined __GLIBC__)", // FIXME +}, + +i_linux_gnu: []const []const u8 = &[_][]const u8{ + "i486-linux-gnu.2.32", + "i486-linux-gnu.2.33", + "i486-linux-gnu.2.34", + "i486-linux-gnu.2.35", + "i486-linux-gnu.2.36", + "i486-linux-gnu.2.37", + "i486-linux-gnu.2.38", + "i586-linux-gnu.2.32", + "i586-linux-gnu.2.33", + "i586-linux-gnu.2.34", + "i586-linux-gnu.2.35", + "i586-linux-gnu.2.36", + "i586-linux-gnu.2.37", + "i586-linux-gnu.2.38", + "i686-linux-gnu.2.32", + "i686-linux-gnu.2.33", + "i686-linux-gnu.2.34", + "i686-linux-gnu.2.35", + "i686-linux-gnu.2.36", + "i686-linux-gnu.2.37", + "i686-linux-gnu.2.38", + "ia64-linux-gnu.2.32", + "ia64-linux-gnu.2.33", + "ia64-linux-gnu.2.34", + "ia64-linux-gnu.2.35", + "ia64-linux-gnu.2.36", + "ia64-linux-gnu.2.37", + "ia64-linux-gnu.2.38", + "(defined __ISOME__ AND defined __GLIBC__)", // FIXME +}, + +m68k_linux_gnu: []const []const u8 = &[_][]const u8{ + "m68k-linux-gnu.2.32", + "m68k-linux-gnu.2.33", + "m68k-linux-gnu.2.34", + "m68k-linux-gnu.2.35", + "m68k-linux-gnu.2.36", + "m68k-linux-gnu.2.37", + "m68k-linux-gnu.2.38", + "(defined __M68K__ AND defined __GLIBC__)", // FIXME +}, + +mips64_linux_gnu: []const []const u8 = &[_][]const u8{ + "mips64el-linux-gnu-n32.2.32", + "mips64el-linux-gnu-n32.2.33", + "mips64el-linux-gnu-n32.2.34", + "mips64el-linux-gnu-n32.2.35", + "mips64el-linux-gnu-n32.2.36", + "mips64el-linux-gnu-n32.2.37", + "mips64el-linux-gnu-n32.2.38", + "mips64el-linux-gnu-n32-nan2008.2.32", + "mips64el-linux-gnu-n32-nan2008.2.33", + "mips64el-linux-gnu-n32-nan2008.2.34", + "mips64el-linux-gnu-n32-nan2008.2.35", + "mips64el-linux-gnu-n32-nan2008.2.36", + "mips64el-linux-gnu-n32-nan2008.2.37", + "mips64el-linux-gnu-n32-nan2008.2.38", + "mips64el-linux-gnu-n32-nan2008-soft.2.32", + "mips64el-linux-gnu-n32-nan2008-soft.2.33", + "mips64el-linux-gnu-n32-nan2008-soft.2.34", + "mips64el-linux-gnu-n32-nan2008-soft.2.35", + "mips64el-linux-gnu-n32-nan2008-soft.2.36", + "mips64el-linux-gnu-n32-nan2008-soft.2.37", + "mips64el-linux-gnu-n32-nan2008-soft.2.38", + "mips64el-linux-gnu-n32-soft.2.32", + "mips64el-linux-gnu-n32-soft.2.33", + "mips64el-linux-gnu-n32-soft.2.34", + "mips64el-linux-gnu-n32-soft.2.35", + "mips64el-linux-gnu-n32-soft.2.36", + "mips64el-linux-gnu-n32-soft.2.37", + "mips64el-linux-gnu-n32-soft.2.38", + "mips64el-linux-gnu-n64.2.32", + "mips64el-linux-gnu-n64.2.33", + "mips64el-linux-gnu-n64.2.34", + "mips64el-linux-gnu-n64.2.35", + "mips64el-linux-gnu-n64.2.36", + "mips64el-linux-gnu-n64.2.37", + "mips64el-linux-gnu-n64.2.38", + "mips64el-linux-gnu-n64-nan2008.2.32", + "mips64el-linux-gnu-n64-nan2008.2.33", + "mips64el-linux-gnu-n64-nan2008.2.34", + "mips64el-linux-gnu-n64-nan2008.2.35", + "mips64el-linux-gnu-n64-nan2008.2.36", + "mips64el-linux-gnu-n64-nan2008.2.37", + "mips64el-linux-gnu-n64-nan2008.2.38", + "mips64el-linux-gnu-n64-nan2008-soft.2.32", + "mips64el-linux-gnu-n64-nan2008-soft.2.33", + "mips64el-linux-gnu-n64-nan2008-soft.2.34", + "mips64el-linux-gnu-n64-nan2008-soft.2.35", + "mips64el-linux-gnu-n64-nan2008-soft.2.36", + "mips64el-linux-gnu-n64-nan2008-soft.2.37", + "mips64el-linux-gnu-n64-nan2008-soft.2.38", + "mips64el-linux-gnu-n64-soft.2.32", + "mips64el-linux-gnu-n64-soft.2.33", + "mips64el-linux-gnu-n64-soft.2.34", + "mips64el-linux-gnu-n64-soft.2.35", + "mips64el-linux-gnu-n64-soft.2.36", + "mips64el-linux-gnu-n64-soft.2.37", + "mips64el-linux-gnu-n64-soft.2.38", + "mips64-linux-gnu-n32.2.32", + "mips64-linux-gnu-n32.2.33", + "mips64-linux-gnu-n32.2.34", + "mips64-linux-gnu-n32.2.35", + "mips64-linux-gnu-n32.2.36", + "mips64-linux-gnu-n32.2.37", + "mips64-linux-gnu-n32.2.38", + "mips64-linux-gnu-n32-nan2008.2.32", + "mips64-linux-gnu-n32-nan2008.2.33", + "mips64-linux-gnu-n32-nan2008.2.34", + "mips64-linux-gnu-n32-nan2008.2.35", + "mips64-linux-gnu-n32-nan2008.2.36", + "mips64-linux-gnu-n32-nan2008.2.37", + "mips64-linux-gnu-n32-nan2008.2.38", + "mips64-linux-gnu-n32-nan2008-soft.2.32", + "mips64-linux-gnu-n32-nan2008-soft.2.33", + "mips64-linux-gnu-n32-nan2008-soft.2.34", + "mips64-linux-gnu-n32-nan2008-soft.2.35", + "mips64-linux-gnu-n32-nan2008-soft.2.36", + "mips64-linux-gnu-n32-nan2008-soft.2.37", + "mips64-linux-gnu-n32-nan2008-soft.2.38", + "mips64-linux-gnu-n32-soft.2.32", + "mips64-linux-gnu-n32-soft.2.33", + "mips64-linux-gnu-n32-soft.2.34", + "mips64-linux-gnu-n32-soft.2.35", + "mips64-linux-gnu-n32-soft.2.36", + "mips64-linux-gnu-n32-soft.2.37", + "mips64-linux-gnu-n32-soft.2.38", + "mips64-linux-gnu-n64.2.32", + "mips64-linux-gnu-n64.2.33", + "mips64-linux-gnu-n64.2.34", + "mips64-linux-gnu-n64.2.35", + "mips64-linux-gnu-n64.2.36", + "mips64-linux-gnu-n64.2.37", + "mips64-linux-gnu-n64.2.38", + "mips64-linux-gnu-n64-nan2008.2.32", + "mips64-linux-gnu-n64-nan2008.2.33", + "mips64-linux-gnu-n64-nan2008.2.34", + "mips64-linux-gnu-n64-nan2008.2.35", + "mips64-linux-gnu-n64-nan2008.2.36", + "mips64-linux-gnu-n64-nan2008.2.37", + "mips64-linux-gnu-n64-nan2008.2.38", + "mips64-linux-gnu-n64-nan2008-soft.2.32", + "mips64-linux-gnu-n64-nan2008-soft.2.33", + "mips64-linux-gnu-n64-nan2008-soft.2.34", + "mips64-linux-gnu-n64-nan2008-soft.2.35", + "mips64-linux-gnu-n64-nan2008-soft.2.36", + "mips64-linux-gnu-n64-nan2008-soft.2.37", + "mips64-linux-gnu-n64-nan2008-soft.2.38", + "mips64-linux-gnu-n64-soft.2.32", + "mips64-linux-gnu-n64-soft.2.33", + "mips64-linux-gnu-n64-soft.2.34", + "mips64-linux-gnu-n64-soft.2.35", + "mips64-linux-gnu-n64-soft.2.36", + "mips64-linux-gnu-n64-soft.2.37", + "mips64-linux-gnu-n64-soft.2.38", + "(defined __MIPS64__ AND defined __GLIBC__)", // FIXME +}, + +mipsel_linux_gnu: []const []const u8 = &[_][]const u8{ + "mipsel-linux-gnu.2.32", + "mipsel-linux-gnu.2.33", + "mipsel-linux-gnu.2.34", + "mipsel-linux-gnu.2.35", + "mipsel-linux-gnu.2.36", + "mipsel-linux-gnu.2.37", + "mipsel-linux-gnu.2.38", + "mipsel-linux-gnu-nan2008.2.32", + "mipsel-linux-gnu-nan2008.2.33", + "mipsel-linux-gnu-nan2008.2.34", + "mipsel-linux-gnu-nan2008.2.35", + "mipsel-linux-gnu-nan2008.2.36", + "mipsel-linux-gnu-nan2008.2.37", + "mipsel-linux-gnu-nan2008.2.38", + "mipsel-linux-gnu-nan2008-soft.2.32", + "mipsel-linux-gnu-nan2008-soft.2.33", + "mipsel-linux-gnu-nan2008-soft.2.34", + "mipsel-linux-gnu-nan2008-soft.2.35", + "mipsel-linux-gnu-nan2008-soft.2.36", + "mipsel-linux-gnu-nan2008-soft.2.37", + "mipsel-linux-gnu-nan2008-soft.2.38", + "mipsel-linux-gnu-soft.2.32", + "mipsel-linux-gnu-soft.2.33", + "mipsel-linux-gnu-soft.2.34", + "mipsel-linux-gnu-soft.2.35", + "mipsel-linux-gnu-soft.2.36", + "mipsel-linux-gnu-soft.2.37", + "mipsel-linux-gnu-soft.2.38", + "mipsisa32r6el-linux-gnu.2.32", + "mipsisa32r6el-linux-gnu.2.33", + "mipsisa32r6el-linux-gnu.2.34", + "mipsisa32r6el-linux-gnu.2.35", + "mipsisa32r6el-linux-gnu.2.36", + "mipsisa32r6el-linux-gnu.2.37", + "mipsisa32r6el-linux-gnu.2.38", + "mipsisa64r6el-linux-gnu-n32.2.32", + "mipsisa64r6el-linux-gnu-n32.2.33", + "mipsisa64r6el-linux-gnu-n32.2.34", + "mipsisa64r6el-linux-gnu-n32.2.35", + "mipsisa64r6el-linux-gnu-n32.2.36", + "mipsisa64r6el-linux-gnu-n32.2.37", + "mipsisa64r6el-linux-gnu-n32.2.38", + "mipsisa64r6el-linux-gnu-n64.2.32", + "mipsisa64r6el-linux-gnu-n64.2.33", + "mipsisa64r6el-linux-gnu-n64.2.34", + "mipsisa64r6el-linux-gnu-n64.2.35", + "mipsisa64r6el-linux-gnu-n64.2.36", + "mipsisa64r6el-linux-gnu-n64.2.37", + "mipsisa64r6el-linux-gnu-n64.2.38", + "(defined __MIPSEL__ AND defined __GLIBC__)", // FIXME +}, + +mips_linux_gnu: []const []const u8 = &[_][]const u8{ + "mips-linux-gnu.2.32", + "mips-linux-gnu.2.33", + "mips-linux-gnu.2.34", + "mips-linux-gnu.2.35", + "mips-linux-gnu.2.36", + "mips-linux-gnu.2.37", + "mips-linux-gnu.2.38", + "mips-linux-gnu-nan2008.2.32", + "mips-linux-gnu-nan2008.2.33", + "mips-linux-gnu-nan2008.2.34", + "mips-linux-gnu-nan2008.2.35", + "mips-linux-gnu-nan2008.2.36", + "mips-linux-gnu-nan2008.2.37", + "mips-linux-gnu-nan2008.2.38", + "mips-linux-gnu-nan2008-soft.2.32", + "mips-linux-gnu-nan2008-soft.2.33", + "mips-linux-gnu-nan2008-soft.2.34", + "mips-linux-gnu-nan2008-soft.2.35", + "mips-linux-gnu-nan2008-soft.2.36", + "mips-linux-gnu-nan2008-soft.2.37", + "mips-linux-gnu-nan2008-soft.2.38", + "mips-linux-gnu-soft.2.32", + "mips-linux-gnu-soft.2.33", + "mips-linux-gnu-soft.2.34", + "mips-linux-gnu-soft.2.35", + "mips-linux-gnu-soft.2.36", + "mips-linux-gnu-soft.2.37", + "mips-linux-gnu-soft.2.38", + "(defined __MIPS__ AND defined __GLIBC__)", // FIXME +}, + +powerpc64_linux_gnu: []const []const u8 = &[_][]const u8{ + "powerpc64le-linux-gnu.2.32", + "powerpc64le-linux-gnu.2.33", + "powerpc64le-linux-gnu.2.34", + "powerpc64le-linux-gnu.2.35", + "powerpc64le-linux-gnu.2.36", + "powerpc64le-linux-gnu.2.37", + "powerpc64le-linux-gnu.2.38", + "powerpc64-linux-gnu.2.32", + "powerpc64-linux-gnu.2.33", + "powerpc64-linux-gnu.2.34", + "powerpc64-linux-gnu.2.35", + "powerpc64-linux-gnu.2.36", + "powerpc64-linux-gnu.2.37", + "powerpc64-linux-gnu.2.38", + "(defined __PPC64__ AND defined __GLIBC__)", // FIXME +}, + +powerpc_linux_gnu: []const []const u8 = &[_][]const u8{ + "powerpc-linux-gnu.2.32", + "powerpc-linux-gnu.2.33", + "powerpc-linux-gnu.2.34", + "powerpc-linux-gnu.2.35", + "powerpc-linux-gnu.2.36", + "powerpc-linux-gnu.2.37", + "powerpc-linux-gnu.2.38", + "powerpc-linux-gnu-power4.2.32", + "powerpc-linux-gnu-power4.2.33", + "powerpc-linux-gnu-power4.2.34", + "powerpc-linux-gnu-power4.2.35", + "powerpc-linux-gnu-power4.2.36", + "powerpc-linux-gnu-power4.2.37", + "powerpc-linux-gnu-power4.2.38", + "powerpc-linux-gnu-soft.2.32", + "powerpc-linux-gnu-soft.2.33", + "powerpc-linux-gnu-soft.2.34", + "powerpc-linux-gnu-soft.2.35", + "powerpc-linux-gnu-soft.2.36", + "powerpc-linux-gnu-soft.2.37", + "powerpc-linux-gnu-soft.2.38", + "(defined __PPC__ AND defined __GLIBC__)", // FIXME +}, + +riscv32_linux_gnu: []const []const u8 = &[_][]const u8{ + "riscv32-linux-gnu-rv32imac-ilp32.2.33", + "riscv32-linux-gnu-rv32imac-ilp32.2.34", + "riscv32-linux-gnu-rv32imac-ilp32.2.35", + "riscv32-linux-gnu-rv32imac-ilp32.2.36", + "riscv32-linux-gnu-rv32imac-ilp32.2.37", + "riscv32-linux-gnu-rv32imac-ilp32.2.38", + "riscv32-linux-gnu-rv32imafdc-ilp32.2.33", + "riscv32-linux-gnu-rv32imafdc-ilp32.2.34", + "riscv32-linux-gnu-rv32imafdc-ilp32.2.35", + "riscv32-linux-gnu-rv32imafdc-ilp32.2.36", + "riscv32-linux-gnu-rv32imafdc-ilp32.2.37", + "riscv32-linux-gnu-rv32imafdc-ilp32.2.38", + "riscv32-linux-gnu-rv32imafdc-ilp32d.2.33", + "riscv32-linux-gnu-rv32imafdc-ilp32d.2.34", + "riscv32-linux-gnu-rv32imafdc-ilp32d.2.35", + "riscv32-linux-gnu-rv32imafdc-ilp32d.2.36", + "riscv32-linux-gnu-rv32imafdc-ilp32d.2.37", + "riscv32-linux-gnu-rv32imafdc-ilp32d.2.38", + "(defined __RISCV32__ AND defined __GLIBC__)", // FIXME +}, + +riscv64_linux_gnu: []const []const u8 = &[_][]const u8{ + "riscv64-linux-gnu-rv64imac-lp64.2.32", + "riscv64-linux-gnu-rv64imac-lp64.2.33", + "riscv64-linux-gnu-rv64imac-lp64.2.34", + "riscv64-linux-gnu-rv64imac-lp64.2.35", + "riscv64-linux-gnu-rv64imac-lp64.2.36", + "riscv64-linux-gnu-rv64imac-lp64.2.37", + "riscv64-linux-gnu-rv64imac-lp64.2.38", + "riscv64-linux-gnu-rv64imafdc-lp64.2.32", + "riscv64-linux-gnu-rv64imafdc-lp64.2.33", + "riscv64-linux-gnu-rv64imafdc-lp64.2.34", + "riscv64-linux-gnu-rv64imafdc-lp64.2.35", + "riscv64-linux-gnu-rv64imafdc-lp64.2.36", + "riscv64-linux-gnu-rv64imafdc-lp64.2.37", + "riscv64-linux-gnu-rv64imafdc-lp64.2.38", + "riscv64-linux-gnu-rv64imafdc-lp64d.2.32", + "riscv64-linux-gnu-rv64imafdc-lp64d.2.33", + "riscv64-linux-gnu-rv64imafdc-lp64d.2.34", + "riscv64-linux-gnu-rv64imafdc-lp64d.2.35", + "riscv64-linux-gnu-rv64imafdc-lp64d.2.36", + "riscv64-linux-gnu-rv64imafdc-lp64d.2.37", + "riscv64-linux-gnu-rv64imafdc-lp64d.2.38", + "(defined __RISCV64__ AND defined __GLIBC__)", // FIXME +}, + +s390x_linux_gnu: []const []const u8 = &[_][]const u8{ + "s390x-linux-gnu.2.32", + "s390x-linux-gnu.2.33", + "s390x-linux-gnu.2.34", + "s390x-linux-gnu.2.35", + "s390x-linux-gnu.2.36", + "s390x-linux-gnu.2.37", + "s390x-linux-gnu.2.38", + "(defined __S390X__ AND defined __GLIBC__)", // FIXME +}, + +sparc64_linux_gnu: []const []const u8 = &[_][]const u8{ + "sparc64-linux-gnu.2.32", + "sparc64-linux-gnu.2.33", + "sparc64-linux-gnu.2.34", + "sparc64-linux-gnu.2.35", + "sparc64-linux-gnu.2.36", + "sparc64-linux-gnu.2.37", + "sparc64-linux-gnu.2.38", + "(defined __SPARC64__ AND defined __GLIBC__)", // FIXME +}, + +sparcv8_linux_gnu: []const []const u8 = &[_][]const u8{ + "sparcv8-linux-gnu-leon3.2.32", + "sparcv8-linux-gnu-leon3.2.33", + "sparcv8-linux-gnu-leon3.2.34", + "sparcv8-linux-gnu-leon3.2.35", + "sparcv8-linux-gnu-leon3.2.36", + "sparcv8-linux-gnu-leon3.2.37", + "sparcv8-linux-gnu-leon3.2.38", + "(defined __SPARCV8__ AND defined __GLIBC__)", // FIXME +}, + +sparcv9_linux_gnu: []const []const u8 = &[_][]const u8{ + "sparcv9-linux-gnu.2.32", + "sparcv9-linux-gnu.2.33", + "sparcv9-linux-gnu.2.34", + "sparcv9-linux-gnu.2.35", + "sparcv9-linux-gnu.2.36", + "sparcv9-linux-gnu.2.37", + "sparcv9-linux-gnu.2.38", + "(defined __SPARCV9__ AND defined __GLIBC__)", // FIXME +}, + +x86_64_linux_gnu: []const []const u8 = &[_][]const u8{ + "x86_64-linux-gnu.2.32", + "x86_64-linux-gnu.2.33", + "x86_64-linux-gnu.2.34", + "x86_64-linux-gnu.2.35", + "x86_64-linux-gnu.2.36", + "x86_64-linux-gnu.2.37", + "x86_64-linux-gnu.2.38", + "x86_64-linux-gnu-x32.2.32", + "x86_64-linux-gnu-x32.2.33", + "x86_64-linux-gnu-x32.2.34", + "x86_64-linux-gnu-x32.2.35", + "x86_64-linux-gnu-x32.2.36", + "x86_64-linux-gnu-x32.2.37", + "x86_64-linux-gnu-x32.2.38", + "(defined __X86_64__ AND defined __GLIBC__)", // FIXME +}, + +freebsd_gnu: []const []const u8 = &[_][]const u8{ + "aarch64-freebsd.12.3-gnu", + "aarch64-freebsd.13.1-gnu", + "powerpc64-freebsd.12.3-gnu", + "powerpc64-freebsd.13.1-gnu", + "powerpc64le-freebsd.13.1-gnu", + "powerpc-freebsd.12.3-gnu", + "powerpc-freebsd.13.1-gnu", + "riscv64-freebsd.13.1-gnu", + "sparc64-freebsd.12.3-gnu", + "x86_64-freebsd.12.3-gnu", + "x86_64-freebsd.13.1-gnu", + "x86-freebsd.12.3-gnu", + "x86-freebsd.13.1-gnu", + "(defined __FreeBSD__ AND defined __GLIBC__)", // FIXME +}, + +freebsd_12_3: []const []const u8 = &[_][]const u8{ + "aarch64-freebsd.12.3-gnu", + "powerpc64-freebsd.12.3-gnu", + "powerpc-freebsd.12.3-gnu", + "sparc64-freebsd.12.3-gnu", + "x86_64-freebsd.12.3-gnu", + "x86-freebsd.12.3-gnu", + "(__FreeBSD__ > 1203500 AND __FreeBSD__ < 1204000)", +}, + +freebsd_13_1: []const []const u8 = &[_][]const u8{ + "aarch64-freebsd.13.1-gnu", + "powerpc64-freebsd.13.1-gnu", + "powerpc64le-freebsd.13.1-gnu", + "powerpc-freebsd.13.1-gnu", + "riscv64-freebsd.13.1-gnu", + "x86_64-freebsd.13.1-gnu", + "x86-freebsd.13.1-gnu", + "(__FreeBSD__ > 1301000 AND __FreeBSD__ < 1302000)", +}, + +macos: []const []const u8 = &[_][]const u8{ + "aarch64-macos.11-none", + "aarch64-macos.12-none", + "aarch64-macos.13-none", + "x86_64-macos.11-none", + "x86_64-macos.12-none", + "x86_64-macos.13-none", + "defined __MACOS__", // FIXME +}, + +musl: []const []const u8 = &[_][]const u8{ + "aarch64-linux-musl", + "arm-linux-musl", + "i386-linux-musl", + "mips64-linux-musl", + "mips-linux-musl", + "powerpc64-linux-musl", + "powerpc-linux-musl", + "riscv64-linux-musl", + "x86_64-linux-musl", + "defined __MUSL__", // FIXME +}, + +gnu_2_32: []const []const u8 = &[_][]const u8{ + "aarch64_be-linux-gnu.2.32", + "aarch64-linux-gnu.2.32", + "arc-linux-gnu.2.32", + "arc-linux-gnuhf.2.32", + "armeb-linux-gnueabi.2.32", + "armeb-linux-gnueabihf.2.32", + "arm-linux-gnueabi.2.32", + "arm-linux-gnueabihf.2.32", + "arm-linux-gnueabihf-v7a.2.32", + "arm-linux-gnueabi-v4t.2.32", + "i486-linux-gnu.2.32", + "i586-linux-gnu.2.32", + "i686-linux-gnu.2.32", + "ia64-linux-gnu.2.32", + "m68k-linux-gnu.2.32", + "mips64el-linux-gnu-n32.2.32", + "mips64el-linux-gnu-n32-nan2008.2.32", + "mips64el-linux-gnu-n32-nan2008-soft.2.32", + "mips64el-linux-gnu-n32-soft.2.32", + "mips64el-linux-gnu-n64.2.32", + "mips64el-linux-gnu-n64-nan2008.2.32", + "mips64el-linux-gnu-n64-nan2008-soft.2.32", + "mips64el-linux-gnu-n64-soft.2.32", + "mips64-linux-gnu-n32.2.32", + "mips64-linux-gnu-n32-nan2008.2.32", + "mips64-linux-gnu-n32-nan2008-soft.2.32", + "mips64-linux-gnu-n32-soft.2.32", + "mips64-linux-gnu-n64.2.32", + "mips64-linux-gnu-n64-nan2008.2.32", + "mips64-linux-gnu-n64-nan2008-soft.2.32", + "mips64-linux-gnu-n64-soft.2.32", + "mipsel-linux-gnu.2.32", + "mipsel-linux-gnu-nan2008.2.32", + "mipsel-linux-gnu-nan2008-soft.2.32", + "mipsel-linux-gnu-soft.2.32", + "mipsisa32r6el-linux-gnu.2.32", + "mipsisa64r6el-linux-gnu-n32.2.32", + "mipsisa64r6el-linux-gnu-n64.2.32", + "mips-linux-gnu.2.32", + "mips-linux-gnu-nan2008.2.32", + "mips-linux-gnu-nan2008-soft.2.32", + "mips-linux-gnu-soft.2.32", + "powerpc64le-linux-gnu.2.32", + "powerpc64-linux-gnu.2.32", + "powerpc-linux-gnu.2.32", + "powerpc-linux-gnu-power4.2.32", + "powerpc-linux-gnu-soft.2.32", + "riscv64-linux-gnu-rv64imac-lp64.2.32", + "riscv64-linux-gnu-rv64imafdc-lp64.2.32", + "riscv64-linux-gnu-rv64imafdc-lp64d.2.32", + "s390x-linux-gnu.2.32", + "sparc64-linux-gnu.2.32", + "sparcv8-linux-gnu-leon3.2.32", + "sparcv9-linux-gnu.2.32", + "x86_64-linux-gnu.2.32", + "x86_64-linux-gnu-x32.2.32", + "__GLIBC_MINOR__ == 32", +}, + +gnu_2_33: []const []const u8 = &[_][]const u8{ + "aarch64_be-linux-gnu.2.33", + "aarch64-linux-gnu.2.33", + "arc-linux-gnu.2.33", + "arc-linux-gnuhf.2.33", + "armeb-linux-gnueabi.2.33", + "armeb-linux-gnueabihf.2.33", + "arm-linux-gnueabi.2.33", + "arm-linux-gnueabihf.2.33", + "arm-linux-gnueabihf-v7a.2.33", + "arm-linux-gnueabi-v4t.2.33", + "csky-linux-gnuabiv2.2.33", + "csky-linux-gnuabiv2-soft.2.33", + "i486-linux-gnu.2.33", + "i586-linux-gnu.2.33", + "i686-linux-gnu.2.33", + "ia64-linux-gnu.2.33", + "m68k-linux-gnu.2.33", + "mips64el-linux-gnu-n32.2.33", + "mips64el-linux-gnu-n32-nan2008.2.33", + "mips64el-linux-gnu-n32-nan2008-soft.2.33", + "mips64el-linux-gnu-n32-soft.2.33", + "mips64el-linux-gnu-n64.2.33", + "mips64el-linux-gnu-n64-nan2008.2.33", + "mips64el-linux-gnu-n64-nan2008-soft.2.33", + "mips64el-linux-gnu-n64-soft.2.33", + "mips64-linux-gnu-n32.2.33", + "mips64-linux-gnu-n32-nan2008.2.33", + "mips64-linux-gnu-n32-nan2008-soft.2.33", + "mips64-linux-gnu-n32-soft.2.33", + "mips64-linux-gnu-n64.2.33", + "mips64-linux-gnu-n64-nan2008.2.33", + "mips64-linux-gnu-n64-nan2008-soft.2.33", + "mips64-linux-gnu-n64-soft.2.33", + "mipsel-linux-gnu.2.33", + "mipsel-linux-gnu-nan2008.2.33", + "mipsel-linux-gnu-nan2008-soft.2.33", + "mipsel-linux-gnu-soft.2.33", + "mipsisa32r6el-linux-gnu.2.33", + "mipsisa64r6el-linux-gnu-n32.2.33", + "mipsisa64r6el-linux-gnu-n64.2.33", + "mips-linux-gnu.2.33", + "mips-linux-gnu-nan2008.2.33", + "mips-linux-gnu-nan2008-soft.2.33", + "mips-linux-gnu-soft.2.33", + "powerpc64le-linux-gnu.2.33", + "powerpc64-linux-gnu.2.33", + "powerpc-linux-gnu.2.33", + "powerpc-linux-gnu-power4.2.33", + "powerpc-linux-gnu-soft.2.33", + "riscv32-linux-gnu-rv32imac-ilp32.2.33", + "riscv32-linux-gnu-rv32imafdc-ilp32.2.33", + "riscv32-linux-gnu-rv32imafdc-ilp32d.2.33", + "riscv64-linux-gnu-rv64imac-lp64.2.33", + "riscv64-linux-gnu-rv64imafdc-lp64.2.33", + "riscv64-linux-gnu-rv64imafdc-lp64d.2.33", + "s390x-linux-gnu.2.33", + "sparc64-linux-gnu.2.33", + "sparcv8-linux-gnu-leon3.2.33", + "sparcv9-linux-gnu.2.33", + "x86_64-linux-gnu.2.33", + "x86_64-linux-gnu-x32.2.33", + "__GLIBC_MINOR__ == 33", +}, + +gnu_2_34: []const []const u8 = &[_][]const u8{ + "aarch64_be-linux-gnu.2.34", + "aarch64-linux-gnu.2.34", + "arc-linux-gnu.2.34", + "arc-linux-gnuhf.2.34", + "armeb-linux-gnueabi.2.34", + "armeb-linux-gnueabihf.2.34", + "arm-linux-gnueabi.2.34", + "arm-linux-gnueabihf.2.34", + "arm-linux-gnueabihf-v7a.2.34", + "arm-linux-gnueabi-v4t.2.34", + "csky-linux-gnuabiv2.2.34", + "csky-linux-gnuabiv2-soft.2.34", + "i486-linux-gnu.2.34", + "i586-linux-gnu.2.34", + "i686-linux-gnu.2.34", + "ia64-linux-gnu.2.34", + "m68k-linux-gnu.2.34", + "mips64el-linux-gnu-n32.2.34", + "mips64el-linux-gnu-n32-nan2008.2.34", + "mips64el-linux-gnu-n32-nan2008-soft.2.34", + "mips64el-linux-gnu-n32-soft.2.34", + "mips64el-linux-gnu-n64.2.34", + "mips64el-linux-gnu-n64-nan2008.2.34", + "mips64el-linux-gnu-n64-nan2008-soft.2.34", + "mips64el-linux-gnu-n64-soft.2.34", + "mips64-linux-gnu-n32.2.34", + "mips64-linux-gnu-n32-nan2008.2.34", + "mips64-linux-gnu-n32-nan2008-soft.2.34", + "mips64-linux-gnu-n32-soft.2.34", + "mips64-linux-gnu-n64.2.34", + "mips64-linux-gnu-n64-nan2008.2.34", + "mips64-linux-gnu-n64-nan2008-soft.2.34", + "mips64-linux-gnu-n64-soft.2.34", + "mipsel-linux-gnu.2.34", + "mipsel-linux-gnu-nan2008.2.34", + "mipsel-linux-gnu-nan2008-soft.2.34", + "mipsel-linux-gnu-soft.2.34", + "mipsisa32r6el-linux-gnu.2.34", + "mipsisa64r6el-linux-gnu-n32.2.34", + "mipsisa64r6el-linux-gnu-n64.2.34", + "mips-linux-gnu.2.34", + "mips-linux-gnu-nan2008.2.34", + "mips-linux-gnu-nan2008-soft.2.34", + "mips-linux-gnu-soft.2.34", + "powerpc64le-linux-gnu.2.34", + "powerpc64-linux-gnu.2.34", + "powerpc-linux-gnu.2.34", + "powerpc-linux-gnu-power4.2.34", + "powerpc-linux-gnu-soft.2.34", + "riscv32-linux-gnu-rv32imac-ilp32.2.34", + "riscv32-linux-gnu-rv32imafdc-ilp32.2.34", + "riscv32-linux-gnu-rv32imafdc-ilp32d.2.34", + "riscv64-linux-gnu-rv64imac-lp64.2.34", + "riscv64-linux-gnu-rv64imafdc-lp64.2.34", + "riscv64-linux-gnu-rv64imafdc-lp64d.2.34", + "s390x-linux-gnu.2.34", + "sparc64-linux-gnu.2.34", + "sparcv8-linux-gnu-leon3.2.34", + "sparcv9-linux-gnu.2.34", + "x86_64-linux-gnu.2.34", + "x86_64-linux-gnu-x32.2.34", + "__GLIBC_MINOR__ == 34", +}, + +gnu_2_35: []const []const u8 = &[_][]const u8{ + "aarch64_be-linux-gnu.2.35", + "aarch64-linux-gnu.2.35", + "arc-linux-gnu.2.35", + "arc-linux-gnuhf.2.35", + "armeb-linux-gnueabi.2.35", + "armeb-linux-gnueabihf.2.35", + "arm-linux-gnueabi.2.35", + "arm-linux-gnueabihf.2.35", + "arm-linux-gnueabihf-v7a.2.35", + "arm-linux-gnueabi-v4t.2.35", + "csky-linux-gnuabiv2.2.35", + "csky-linux-gnuabiv2-soft.2.35", + "i486-linux-gnu.2.35", + "i586-linux-gnu.2.35", + "i686-linux-gnu.2.35", + "ia64-linux-gnu.2.35", + "m68k-linux-gnu.2.35", + "mips64el-linux-gnu-n32.2.35", + "mips64el-linux-gnu-n32-nan2008.2.35", + "mips64el-linux-gnu-n32-nan2008-soft.2.35", + "mips64el-linux-gnu-n32-soft.2.35", + "mips64el-linux-gnu-n64.2.35", + "mips64el-linux-gnu-n64-nan2008.2.35", + "mips64el-linux-gnu-n64-nan2008-soft.2.35", + "mips64el-linux-gnu-n64-soft.2.35", + "mips64-linux-gnu-n32.2.35", + "mips64-linux-gnu-n32-nan2008.2.35", + "mips64-linux-gnu-n32-nan2008-soft.2.35", + "mips64-linux-gnu-n32-soft.2.35", + "mips64-linux-gnu-n64.2.35", + "mips64-linux-gnu-n64-nan2008.2.35", + "mips64-linux-gnu-n64-nan2008-soft.2.35", + "mips64-linux-gnu-n64-soft.2.35", + "mipsel-linux-gnu.2.35", + "mipsel-linux-gnu-nan2008.2.35", + "mipsel-linux-gnu-nan2008-soft.2.35", + "mipsel-linux-gnu-soft.2.35", + "mipsisa32r6el-linux-gnu.2.35", + "mipsisa64r6el-linux-gnu-n32.2.35", + "mipsisa64r6el-linux-gnu-n64.2.35", + "mips-linux-gnu.2.35", + "mips-linux-gnu-nan2008.2.35", + "mips-linux-gnu-nan2008-soft.2.35", + "mips-linux-gnu-soft.2.35", + "powerpc64le-linux-gnu.2.35", + "powerpc64-linux-gnu.2.35", + "powerpc-linux-gnu.2.35", + "powerpc-linux-gnu-power4.2.35", + "powerpc-linux-gnu-soft.2.35", + "riscv32-linux-gnu-rv32imac-ilp32.2.35", + "riscv32-linux-gnu-rv32imafdc-ilp32.2.35", + "riscv32-linux-gnu-rv32imafdc-ilp32d.2.35", + "riscv64-linux-gnu-rv64imac-lp64.2.35", + "riscv64-linux-gnu-rv64imafdc-lp64.2.35", + "riscv64-linux-gnu-rv64imafdc-lp64d.2.35", + "s390x-linux-gnu.2.35", + "sparc64-linux-gnu.2.35", + "sparcv8-linux-gnu-leon3.2.35", + "sparcv9-linux-gnu.2.35", + "x86_64-linux-gnu.2.35", + "x86_64-linux-gnu-x32.2.35", + "__GLIBC_MINOR__ == 35", +}, + +gnu_2_36: []const []const u8 = &[_][]const u8{ + "aarch64_be-linux-gnu.2.36", + "aarch64-linux-gnu.2.36", + "arc-linux-gnu.2.36", + "arc-linux-gnuhf.2.36", + "armeb-linux-gnueabi.2.36", + "armeb-linux-gnueabihf.2.36", + "arm-linux-gnueabi.2.36", + "arm-linux-gnueabihf.2.36", + "arm-linux-gnueabihf-v7a.2.36", + "arm-linux-gnueabi-v4t.2.36", + "csky-linux-gnuabiv2.2.36", + "csky-linux-gnuabiv2-soft.2.36", + "i486-linux-gnu.2.36", + "i586-linux-gnu.2.36", + "i686-linux-gnu.2.36", + "ia64-linux-gnu.2.36", + "m68k-linux-gnu.2.36", + "mips64el-linux-gnu-n32.2.36", + "mips64el-linux-gnu-n32-nan2008.2.36", + "mips64el-linux-gnu-n32-nan2008-soft.2.36", + "mips64el-linux-gnu-n32-soft.2.36", + "mips64el-linux-gnu-n64.2.36", + "mips64el-linux-gnu-n64-nan2008.2.36", + "mips64el-linux-gnu-n64-nan2008-soft.2.36", + "mips64el-linux-gnu-n64-soft.2.36", + "mips64-linux-gnu-n32.2.36", + "mips64-linux-gnu-n32-nan2008.2.36", + "mips64-linux-gnu-n32-nan2008-soft.2.36", + "mips64-linux-gnu-n32-soft.2.36", + "mips64-linux-gnu-n64.2.36", + "mips64-linux-gnu-n64-nan2008.2.36", + "mips64-linux-gnu-n64-nan2008-soft.2.36", + "mips64-linux-gnu-n64-soft.2.36", + "mipsel-linux-gnu.2.36", + "mipsel-linux-gnu-nan2008.2.36", + "mipsel-linux-gnu-nan2008-soft.2.36", + "mipsel-linux-gnu-soft.2.36", + "mipsisa32r6el-linux-gnu.2.36", + "mipsisa64r6el-linux-gnu-n32.2.36", + "mipsisa64r6el-linux-gnu-n64.2.36", + "mips-linux-gnu.2.36", + "mips-linux-gnu-nan2008.2.36", + "mips-linux-gnu-nan2008-soft.2.36", + "mips-linux-gnu-soft.2.36", + "powerpc64le-linux-gnu.2.36", + "powerpc64-linux-gnu.2.36", + "powerpc-linux-gnu.2.36", + "powerpc-linux-gnu-power4.2.36", + "powerpc-linux-gnu-soft.2.36", + "riscv32-linux-gnu-rv32imac-ilp32.2.36", + "riscv32-linux-gnu-rv32imafdc-ilp32.2.36", + "riscv32-linux-gnu-rv32imafdc-ilp32d.2.36", + "riscv64-linux-gnu-rv64imac-lp64.2.36", + "riscv64-linux-gnu-rv64imafdc-lp64.2.36", + "riscv64-linux-gnu-rv64imafdc-lp64d.2.36", + "s390x-linux-gnu.2.36", + "sparc64-linux-gnu.2.36", + "sparcv8-linux-gnu-leon3.2.36", + "sparcv9-linux-gnu.2.36", + "x86_64-linux-gnu.2.36", + "x86_64-linux-gnu-x32.2.36", + "__GLIBC_MINOR__ == 36", +}, + +gnu_2_37: []const []const u8 = &[_][]const u8{ + "aarch64_be-linux-gnu.2.37", + "aarch64-linux-gnu.2.37", + "arc-linux-gnu.2.37", + "arc-linux-gnuhf.2.37", + "armeb-linux-gnueabi.2.37", + "armeb-linux-gnueabihf.2.37", + "arm-linux-gnueabi.2.37", + "arm-linux-gnueabihf.2.37", + "arm-linux-gnueabihf-v7a.2.37", + "arm-linux-gnueabi-v4t.2.37", + "csky-linux-gnuabiv2.2.37", + "csky-linux-gnuabiv2-soft.2.37", + "i486-linux-gnu.2.37", + "i586-linux-gnu.2.37", + "i686-linux-gnu.2.37", + "ia64-linux-gnu.2.37", + "m68k-linux-gnu.2.37", + "mips64el-linux-gnu-n32.2.37", + "mips64el-linux-gnu-n32-nan2008.2.37", + "mips64el-linux-gnu-n32-nan2008-soft.2.37", + "mips64el-linux-gnu-n32-soft.2.37", + "mips64el-linux-gnu-n64.2.37", + "mips64el-linux-gnu-n64-nan2008.2.37", + "mips64el-linux-gnu-n64-nan2008-soft.2.37", + "mips64el-linux-gnu-n64-soft.2.37", + "mips64-linux-gnu-n32.2.37", + "mips64-linux-gnu-n32-nan2008.2.37", + "mips64-linux-gnu-n32-nan2008-soft.2.37", + "mips64-linux-gnu-n32-soft.2.37", + "mips64-linux-gnu-n64.2.37", + "mips64-linux-gnu-n64-nan2008.2.37", + "mips64-linux-gnu-n64-nan2008-soft.2.37", + "mips64-linux-gnu-n64-soft.2.37", + "mipsel-linux-gnu.2.37", + "mipsel-linux-gnu-nan2008.2.37", + "mipsel-linux-gnu-nan2008-soft.2.37", + "mipsel-linux-gnu-soft.2.37", + "mipsisa32r6el-linux-gnu.2.37", + "mipsisa64r6el-linux-gnu-n32.2.37", + "mipsisa64r6el-linux-gnu-n64.2.37", + "mips-linux-gnu.2.37", + "mips-linux-gnu-nan2008.2.37", + "mips-linux-gnu-nan2008-soft.2.37", + "mips-linux-gnu-soft.2.37", + "powerpc64le-linux-gnu.2.37", + "powerpc64-linux-gnu.2.37", + "powerpc-linux-gnu.2.37", + "powerpc-linux-gnu-power4.2.37", + "powerpc-linux-gnu-soft.2.37", + "riscv32-linux-gnu-rv32imac-ilp32.2.37", + "riscv32-linux-gnu-rv32imafdc-ilp32.2.37", + "riscv32-linux-gnu-rv32imafdc-ilp32d.2.37", + "riscv64-linux-gnu-rv64imac-lp64.2.37", + "riscv64-linux-gnu-rv64imafdc-lp64.2.37", + "riscv64-linux-gnu-rv64imafdc-lp64d.2.37", + "s390x-linux-gnu.2.37", + "sparc64-linux-gnu.2.37", + "sparcv8-linux-gnu-leon3.2.37", + "sparcv9-linux-gnu.2.37", + "x86_64-linux-gnu.2.37", + "x86_64-linux-gnu-x32.2.37", + "__GLIBC_MINOR__ == 37", +}, + +gnu_2_38: []const []const u8 = &[_][]const u8{ + "aarch64_be-linux-gnu.2.38", + "aarch64-linux-gnu.2.38", + "arc-linux-gnu.2.38", + "arc-linux-gnuhf.2.38", + "armeb-linux-gnueabi.2.38", + "armeb-linux-gnueabihf.2.38", + "arm-linux-gnueabi.2.38", + "arm-linux-gnueabihf.2.38", + "arm-linux-gnueabihf-v7a.2.38", + "arm-linux-gnueabi-v4t.2.38", + "csky-linux-gnuabiv2.2.38", + "csky-linux-gnuabiv2-soft.2.38", + "i486-linux-gnu.2.38", + "i586-linux-gnu.2.38", + "i686-linux-gnu.2.38", + "ia64-linux-gnu.2.38", + "m68k-linux-gnu.2.38", + "mips64el-linux-gnu-n32.2.38", + "mips64el-linux-gnu-n32-nan2008.2.38", + "mips64el-linux-gnu-n32-nan2008-soft.2.38", + "mips64el-linux-gnu-n32-soft.2.38", + "mips64el-linux-gnu-n64.2.38", + "mips64el-linux-gnu-n64-nan2008.2.38", + "mips64el-linux-gnu-n64-nan2008-soft.2.38", + "mips64el-linux-gnu-n64-soft.2.38", + "mips64-linux-gnu-n32.2.38", + "mips64-linux-gnu-n32-nan2008.2.38", + "mips64-linux-gnu-n32-nan2008-soft.2.38", + "mips64-linux-gnu-n32-soft.2.38", + "mips64-linux-gnu-n64.2.38", + "mips64-linux-gnu-n64-nan2008.2.38", + "mips64-linux-gnu-n64-nan2008-soft.2.38", + "mips64-linux-gnu-n64-soft.2.38", + "mipsel-linux-gnu.2.38", + "mipsel-linux-gnu-nan2008.2.38", + "mipsel-linux-gnu-nan2008-soft.2.38", + "mipsel-linux-gnu-soft.2.38", + "mipsisa32r6el-linux-gnu.2.38", + "mipsisa64r6el-linux-gnu-n32.2.38", + "mipsisa64r6el-linux-gnu-n64.2.38", + "mips-linux-gnu.2.38", + "mips-linux-gnu-nan2008.2.38", + "mips-linux-gnu-nan2008-soft.2.38", + "mips-linux-gnu-soft.2.38", + "powerpc64le-linux-gnu.2.38", + "powerpc64-linux-gnu.2.38", + "powerpc-linux-gnu.2.38", + "powerpc-linux-gnu-power4.2.38", + "powerpc-linux-gnu-soft.2.38", + "riscv32-linux-gnu-rv32imac-ilp32.2.38", + "riscv32-linux-gnu-rv32imafdc-ilp32.2.38", + "riscv32-linux-gnu-rv32imafdc-ilp32d.2.38", + "riscv64-linux-gnu-rv64imac-lp64.2.38", + "riscv64-linux-gnu-rv64imafdc-lp64.2.38", + "riscv64-linux-gnu-rv64imafdc-lp64d.2.38", + "s390x-linux-gnu.2.38", + "sparc64-linux-gnu.2.38", + "sparcv8-linux-gnu-leon3.2.38", + "sparcv9-linux-gnu.2.38", + "x86_64-linux-gnu.2.38", + "x86_64-linux-gnu-x32.2.38", + "__GLIBC_MINOR__ == 38", +}, + +gnu_not_2_32: []const []const u8 = &[_][]const u8{ + "aarch64_be-linux-gnu.2.33", + "aarch64_be-linux-gnu.2.34", + "aarch64_be-linux-gnu.2.35", + "aarch64_be-linux-gnu.2.36", + "aarch64_be-linux-gnu.2.37", + "aarch64_be-linux-gnu.2.38", + "aarch64-linux-gnu.2.33", + "aarch64-linux-gnu.2.34", + "aarch64-linux-gnu.2.35", + "aarch64-linux-gnu.2.36", + "aarch64-linux-gnu.2.37", + "aarch64-linux-gnu.2.38", + "arc-linux-gnu.2.33", + "arc-linux-gnu.2.34", + "arc-linux-gnu.2.35", + "arc-linux-gnu.2.36", + "arc-linux-gnu.2.37", + "arc-linux-gnu.2.38", + "arc-linux-gnuhf.2.33", + "arc-linux-gnuhf.2.34", + "arc-linux-gnuhf.2.35", + "arc-linux-gnuhf.2.36", + "arc-linux-gnuhf.2.37", + "arc-linux-gnuhf.2.38", + "armeb-linux-gnueabi.2.33", + "armeb-linux-gnueabi.2.34", + "armeb-linux-gnueabi.2.35", + "armeb-linux-gnueabi.2.36", + "armeb-linux-gnueabi.2.37", + "armeb-linux-gnueabi.2.38", + "armeb-linux-gnueabihf.2.33", + "armeb-linux-gnueabihf.2.34", + "armeb-linux-gnueabihf.2.35", + "armeb-linux-gnueabihf.2.36", + "armeb-linux-gnueabihf.2.37", + "armeb-linux-gnueabihf.2.38", + "arm-linux-gnueabi.2.33", + "arm-linux-gnueabi.2.34", + "arm-linux-gnueabi.2.35", + "arm-linux-gnueabi.2.36", + "arm-linux-gnueabi.2.37", + "arm-linux-gnueabi.2.38", + "arm-linux-gnueabihf.2.33", + "arm-linux-gnueabihf.2.34", + "arm-linux-gnueabihf.2.35", + "arm-linux-gnueabihf.2.36", + "arm-linux-gnueabihf.2.37", + "arm-linux-gnueabihf.2.38", + "arm-linux-gnueabihf-v7a.2.33", + "arm-linux-gnueabihf-v7a.2.34", + "arm-linux-gnueabihf-v7a.2.35", + "arm-linux-gnueabihf-v7a.2.36", + "arm-linux-gnueabihf-v7a.2.37", + "arm-linux-gnueabihf-v7a.2.38", + "arm-linux-gnueabi-v4t.2.33", + "arm-linux-gnueabi-v4t.2.34", + "arm-linux-gnueabi-v4t.2.35", + "arm-linux-gnueabi-v4t.2.36", + "arm-linux-gnueabi-v4t.2.37", + "arm-linux-gnueabi-v4t.2.38", + "i486-linux-gnu.2.33", + "i486-linux-gnu.2.34", + "i486-linux-gnu.2.35", + "i486-linux-gnu.2.36", + "i486-linux-gnu.2.37", + "i486-linux-gnu.2.38", + "i586-linux-gnu.2.33", + "i586-linux-gnu.2.34", + "i586-linux-gnu.2.35", + "i586-linux-gnu.2.36", + "i586-linux-gnu.2.37", + "i586-linux-gnu.2.38", + "i686-linux-gnu.2.33", + "i686-linux-gnu.2.34", + "i686-linux-gnu.2.35", + "i686-linux-gnu.2.36", + "i686-linux-gnu.2.37", + "i686-linux-gnu.2.38", + "ia64-linux-gnu.2.33", + "ia64-linux-gnu.2.34", + "ia64-linux-gnu.2.35", + "ia64-linux-gnu.2.36", + "ia64-linux-gnu.2.37", + "ia64-linux-gnu.2.38", + "m68k-linux-gnu.2.33", + "m68k-linux-gnu.2.34", + "m68k-linux-gnu.2.35", + "m68k-linux-gnu.2.36", + "m68k-linux-gnu.2.37", + "m68k-linux-gnu.2.38", + "mips64el-linux-gnu-n32.2.33", + "mips64el-linux-gnu-n32.2.34", + "mips64el-linux-gnu-n32.2.35", + "mips64el-linux-gnu-n32.2.36", + "mips64el-linux-gnu-n32.2.37", + "mips64el-linux-gnu-n32.2.38", + "mips64el-linux-gnu-n32-nan2008.2.33", + "mips64el-linux-gnu-n32-nan2008.2.34", + "mips64el-linux-gnu-n32-nan2008.2.35", + "mips64el-linux-gnu-n32-nan2008.2.36", + "mips64el-linux-gnu-n32-nan2008.2.37", + "mips64el-linux-gnu-n32-nan2008.2.38", + "mips64el-linux-gnu-n32-nan2008-soft.2.33", + "mips64el-linux-gnu-n32-nan2008-soft.2.34", + "mips64el-linux-gnu-n32-nan2008-soft.2.35", + "mips64el-linux-gnu-n32-nan2008-soft.2.36", + "mips64el-linux-gnu-n32-nan2008-soft.2.37", + "mips64el-linux-gnu-n32-nan2008-soft.2.38", + "mips64el-linux-gnu-n32-soft.2.33", + "mips64el-linux-gnu-n32-soft.2.34", + "mips64el-linux-gnu-n32-soft.2.35", + "mips64el-linux-gnu-n32-soft.2.36", + "mips64el-linux-gnu-n32-soft.2.37", + "mips64el-linux-gnu-n32-soft.2.38", + "mips64el-linux-gnu-n64.2.33", + "mips64el-linux-gnu-n64.2.34", + "mips64el-linux-gnu-n64.2.35", + "mips64el-linux-gnu-n64.2.36", + "mips64el-linux-gnu-n64.2.37", + "mips64el-linux-gnu-n64.2.38", + "mips64el-linux-gnu-n64-nan2008.2.33", + "mips64el-linux-gnu-n64-nan2008.2.34", + "mips64el-linux-gnu-n64-nan2008.2.35", + "mips64el-linux-gnu-n64-nan2008.2.36", + "mips64el-linux-gnu-n64-nan2008.2.37", + "mips64el-linux-gnu-n64-nan2008.2.38", + "mips64el-linux-gnu-n64-nan2008-soft.2.33", + "mips64el-linux-gnu-n64-nan2008-soft.2.34", + "mips64el-linux-gnu-n64-nan2008-soft.2.35", + "mips64el-linux-gnu-n64-nan2008-soft.2.36", + "mips64el-linux-gnu-n64-nan2008-soft.2.37", + "mips64el-linux-gnu-n64-nan2008-soft.2.38", + "mips64el-linux-gnu-n64-soft.2.33", + "mips64el-linux-gnu-n64-soft.2.34", + "mips64el-linux-gnu-n64-soft.2.35", + "mips64el-linux-gnu-n64-soft.2.36", + "mips64el-linux-gnu-n64-soft.2.37", + "mips64el-linux-gnu-n64-soft.2.38", + "mips64-linux-gnu-n32.2.33", + "mips64-linux-gnu-n32.2.34", + "mips64-linux-gnu-n32.2.35", + "mips64-linux-gnu-n32.2.36", + "mips64-linux-gnu-n32.2.37", + "mips64-linux-gnu-n32.2.38", + "mips64-linux-gnu-n32-nan2008.2.33", + "mips64-linux-gnu-n32-nan2008.2.34", + "mips64-linux-gnu-n32-nan2008.2.35", + "mips64-linux-gnu-n32-nan2008.2.36", + "mips64-linux-gnu-n32-nan2008.2.37", + "mips64-linux-gnu-n32-nan2008.2.38", + "mips64-linux-gnu-n32-nan2008-soft.2.33", + "mips64-linux-gnu-n32-nan2008-soft.2.34", + "mips64-linux-gnu-n32-nan2008-soft.2.35", + "mips64-linux-gnu-n32-nan2008-soft.2.36", + "mips64-linux-gnu-n32-nan2008-soft.2.37", + "mips64-linux-gnu-n32-nan2008-soft.2.38", + "mips64-linux-gnu-n32-soft.2.33", + "mips64-linux-gnu-n32-soft.2.34", + "mips64-linux-gnu-n32-soft.2.35", + "mips64-linux-gnu-n32-soft.2.36", + "mips64-linux-gnu-n32-soft.2.37", + "mips64-linux-gnu-n32-soft.2.38", + "mips64-linux-gnu-n64.2.33", + "mips64-linux-gnu-n64.2.34", + "mips64-linux-gnu-n64.2.35", + "mips64-linux-gnu-n64.2.36", + "mips64-linux-gnu-n64.2.37", + "mips64-linux-gnu-n64.2.38", + "mips64-linux-gnu-n64-nan2008.2.33", + "mips64-linux-gnu-n64-nan2008.2.34", + "mips64-linux-gnu-n64-nan2008.2.35", + "mips64-linux-gnu-n64-nan2008.2.36", + "mips64-linux-gnu-n64-nan2008.2.37", + "mips64-linux-gnu-n64-nan2008.2.38", + "mips64-linux-gnu-n64-nan2008-soft.2.33", + "mips64-linux-gnu-n64-nan2008-soft.2.34", + "mips64-linux-gnu-n64-nan2008-soft.2.35", + "mips64-linux-gnu-n64-nan2008-soft.2.36", + "mips64-linux-gnu-n64-nan2008-soft.2.37", + "mips64-linux-gnu-n64-nan2008-soft.2.38", + "mips64-linux-gnu-n64-soft.2.33", + "mips64-linux-gnu-n64-soft.2.34", + "mips64-linux-gnu-n64-soft.2.35", + "mips64-linux-gnu-n64-soft.2.36", + "mips64-linux-gnu-n64-soft.2.37", + "mips64-linux-gnu-n64-soft.2.38", + "mipsel-linux-gnu.2.33", + "mipsel-linux-gnu.2.34", + "mipsel-linux-gnu.2.35", + "mipsel-linux-gnu.2.36", + "mipsel-linux-gnu.2.37", + "mipsel-linux-gnu.2.38", + "mipsel-linux-gnu-nan2008.2.33", + "mipsel-linux-gnu-nan2008.2.34", + "mipsel-linux-gnu-nan2008.2.35", + "mipsel-linux-gnu-nan2008.2.36", + "mipsel-linux-gnu-nan2008.2.37", + "mipsel-linux-gnu-nan2008.2.38", + "mipsel-linux-gnu-nan2008-soft.2.33", + "mipsel-linux-gnu-nan2008-soft.2.34", + "mipsel-linux-gnu-nan2008-soft.2.35", + "mipsel-linux-gnu-nan2008-soft.2.36", + "mipsel-linux-gnu-nan2008-soft.2.37", + "mipsel-linux-gnu-nan2008-soft.2.38", + "mipsel-linux-gnu-soft.2.33", + "mipsel-linux-gnu-soft.2.34", + "mipsel-linux-gnu-soft.2.35", + "mipsel-linux-gnu-soft.2.36", + "mipsel-linux-gnu-soft.2.37", + "mipsel-linux-gnu-soft.2.38", + "mipsisa32r6el-linux-gnu.2.33", + "mipsisa32r6el-linux-gnu.2.34", + "mipsisa32r6el-linux-gnu.2.35", + "mipsisa32r6el-linux-gnu.2.36", + "mipsisa32r6el-linux-gnu.2.37", + "mipsisa32r6el-linux-gnu.2.38", + "mipsisa64r6el-linux-gnu-n32.2.33", + "mipsisa64r6el-linux-gnu-n32.2.34", + "mipsisa64r6el-linux-gnu-n32.2.35", + "mipsisa64r6el-linux-gnu-n32.2.36", + "mipsisa64r6el-linux-gnu-n32.2.37", + "mipsisa64r6el-linux-gnu-n32.2.38", + "mipsisa64r6el-linux-gnu-n64.2.33", + "mipsisa64r6el-linux-gnu-n64.2.34", + "mipsisa64r6el-linux-gnu-n64.2.35", + "mipsisa64r6el-linux-gnu-n64.2.36", + "mipsisa64r6el-linux-gnu-n64.2.37", + "mipsisa64r6el-linux-gnu-n64.2.38", + "mips-linux-gnu.2.33", + "mips-linux-gnu.2.34", + "mips-linux-gnu.2.35", + "mips-linux-gnu.2.36", + "mips-linux-gnu.2.37", + "mips-linux-gnu.2.38", + "mips-linux-gnu-nan2008.2.33", + "mips-linux-gnu-nan2008.2.34", + "mips-linux-gnu-nan2008.2.35", + "mips-linux-gnu-nan2008.2.36", + "mips-linux-gnu-nan2008.2.37", + "mips-linux-gnu-nan2008.2.38", + "mips-linux-gnu-nan2008-soft.2.33", + "mips-linux-gnu-nan2008-soft.2.34", + "mips-linux-gnu-nan2008-soft.2.35", + "mips-linux-gnu-nan2008-soft.2.36", + "mips-linux-gnu-nan2008-soft.2.37", + "mips-linux-gnu-nan2008-soft.2.38", + "mips-linux-gnu-soft.2.33", + "mips-linux-gnu-soft.2.34", + "mips-linux-gnu-soft.2.35", + "mips-linux-gnu-soft.2.36", + "mips-linux-gnu-soft.2.37", + "mips-linux-gnu-soft.2.38", + "powerpc64le-linux-gnu.2.33", + "powerpc64le-linux-gnu.2.34", + "powerpc64le-linux-gnu.2.35", + "powerpc64le-linux-gnu.2.36", + "powerpc64le-linux-gnu.2.37", + "powerpc64le-linux-gnu.2.38", + "powerpc64-linux-gnu.2.33", + "powerpc64-linux-gnu.2.34", + "powerpc64-linux-gnu.2.35", + "powerpc64-linux-gnu.2.36", + "powerpc64-linux-gnu.2.37", + "powerpc64-linux-gnu.2.38", + "powerpc-linux-gnu.2.33", + "powerpc-linux-gnu.2.34", + "powerpc-linux-gnu.2.35", + "powerpc-linux-gnu.2.36", + "powerpc-linux-gnu.2.37", + "powerpc-linux-gnu.2.38", + "powerpc-linux-gnu-power4.2.33", + "powerpc-linux-gnu-power4.2.34", + "powerpc-linux-gnu-power4.2.35", + "powerpc-linux-gnu-power4.2.36", + "powerpc-linux-gnu-power4.2.37", + "powerpc-linux-gnu-power4.2.38", + "powerpc-linux-gnu-soft.2.33", + "powerpc-linux-gnu-soft.2.34", + "powerpc-linux-gnu-soft.2.35", + "powerpc-linux-gnu-soft.2.36", + "powerpc-linux-gnu-soft.2.37", + "powerpc-linux-gnu-soft.2.38", + "riscv64-linux-gnu-rv64imac-lp64.2.33", + "riscv64-linux-gnu-rv64imac-lp64.2.34", + "riscv64-linux-gnu-rv64imac-lp64.2.35", + "riscv64-linux-gnu-rv64imac-lp64.2.36", + "riscv64-linux-gnu-rv64imac-lp64.2.37", + "riscv64-linux-gnu-rv64imac-lp64.2.38", + "riscv64-linux-gnu-rv64imafdc-lp64.2.33", + "riscv64-linux-gnu-rv64imafdc-lp64.2.34", + "riscv64-linux-gnu-rv64imafdc-lp64.2.35", + "riscv64-linux-gnu-rv64imafdc-lp64.2.36", + "riscv64-linux-gnu-rv64imafdc-lp64.2.37", + "riscv64-linux-gnu-rv64imafdc-lp64.2.38", + "riscv64-linux-gnu-rv64imafdc-lp64d.2.33", + "riscv64-linux-gnu-rv64imafdc-lp64d.2.34", + "riscv64-linux-gnu-rv64imafdc-lp64d.2.35", + "riscv64-linux-gnu-rv64imafdc-lp64d.2.36", + "riscv64-linux-gnu-rv64imafdc-lp64d.2.37", + "riscv64-linux-gnu-rv64imafdc-lp64d.2.38", + "s390x-linux-gnu.2.33", + "s390x-linux-gnu.2.34", + "s390x-linux-gnu.2.35", + "s390x-linux-gnu.2.36", + "s390x-linux-gnu.2.37", + "s390x-linux-gnu.2.38", + "sparc64-linux-gnu.2.33", + "sparc64-linux-gnu.2.34", + "sparc64-linux-gnu.2.35", + "sparc64-linux-gnu.2.36", + "sparc64-linux-gnu.2.37", + "sparc64-linux-gnu.2.38", + "sparcv8-linux-gnu-leon3.2.33", + "sparcv8-linux-gnu-leon3.2.34", + "sparcv8-linux-gnu-leon3.2.35", + "sparcv8-linux-gnu-leon3.2.36", + "sparcv8-linux-gnu-leon3.2.37", + "sparcv8-linux-gnu-leon3.2.38", + "sparcv9-linux-gnu.2.33", + "sparcv9-linux-gnu.2.34", + "sparcv9-linux-gnu.2.35", + "sparcv9-linux-gnu.2.36", + "sparcv9-linux-gnu.2.37", + "sparcv9-linux-gnu.2.38", + "x86_64-linux-gnu.2.33", + "x86_64-linux-gnu.2.34", + "x86_64-linux-gnu.2.35", + "x86_64-linux-gnu.2.36", + "x86_64-linux-gnu.2.37", + "x86_64-linux-gnu.2.38", + "x86_64-linux-gnu-x32.2.33", + "x86_64-linux-gnu-x32.2.34", + "x86_64-linux-gnu-x32.2.35", + "x86_64-linux-gnu-x32.2.36", + "x86_64-linux-gnu-x32.2.37", + "x86_64-linux-gnu-x32.2.38", + "__GLIBC_MINOR__ > 32", +}, + +// The rest of these are not duplicated enough so far to warrant a reduction, +// but they are listed in the file so that we can show an error when running +// compile.bash to make sure a new version gets added to this file. + +//any-windows-any diff --git a/src/textdiff/test.bash b/src/textdiff/test.bash new file mode 100755 index 00000000..636b2926 --- /dev/null +++ b/src/textdiff/test.bash @@ -0,0 +1,16 @@ + +HEADER_LIST="$@" + +for i in $HEADER_LIST; +do + echo "testHeaders $i" + ./zig-out/bin/testHeaders uh_headers uh_test $i + diff -uBwr uh_norm/$(basename $i) uh_test | grep -v "Only in" > uh_diff + if [ -s uh_diff ] + then + echo "failed: diff -uBwr uh_norm/$(basename $i) uh_test" + exit 1 + fi +done + +exit 0 diff --git a/src/textdiff/testHeaders.zig b/src/textdiff/testHeaders.zig new file mode 100644 index 00000000..f854dafb --- /dev/null +++ b/src/textdiff/testHeaders.zig @@ -0,0 +1,145 @@ +const std = @import("std"); +const reductions = @import("reductions.zig"){}; + +const debug = false; + +// This utility goes through universal headers and only evaluates the #if blocks that we added to make them universal +// - what comes out can be diffed against the original headers for testing +pub fn main() !void { + var arena_allocator = std.heap.ArenaAllocator.init(std.heap.page_allocator); + const arena = arena_allocator.allocator(); + + var args = try std.process.argsWithAllocator(arena); + + { + var i: usize = 0; + while (args.skip()) { + i += 1; + } + + if (i != 4) { + std.debug.print("usage: testHeaders \n", .{}); + std.debug.print("takes universal headers from , partially evaluates, and outputs to \n", .{}); + std.debug.print("output files should match originals from that version (maybe whitespace differences)\n", .{}); + return; + } + } + + args = try std.process.argsWithAllocator(arena); + _ = args.skip(); + const inDir = args.next() orelse return; + const outDir = args.next() orelse return; + const versionStr = std.fs.path.basename(args.next() orelse return); + + var dir = try std.fs.cwd().openIterableDir(inDir, .{}); + defer dir.close(); + + var walker = try dir.walk(arena); + while (try walker.next()) |entry| { + if (entry.kind != .file) { + continue; + } + + //if (!std.mem.eql(u8, entry.basename, "e_os2.h")) continue; + + //std.debug.print("entry: base {s} path {s}\n", .{ entry.basename, entry.path }); + + // read universal header into memory + var inpath = try std.fs.path.join(arena, &.{ inDir, entry.path }); + var inlines = std.ArrayList([]const u8).init(arena); + { + var file = try std.fs.cwd().openFile(inpath, .{}); + defer file.close(); + var contents = try file.reader().readAllAlloc(arena, 20 * 1024 * 1024); + while (contents.len > 0 and contents[contents.len - 1] == '\n') { + contents = contents[0 .. contents.len - 1]; + } + + if (contents.len > 0) { + var it = std.mem.splitScalar(u8, contents, '\n'); + while (it.next()) |line| { + try inlines.append(line); + } + } + } + + var outpath = try std.fs.path.join(arena, &.{ outDir, entry.path }); + if (std.fs.path.dirname(outpath)) |dirname| { + try std.fs.cwd().makePath(dirname); + } + if (debug) std.debug.print("createFile {s}\n", .{outpath}); + var outfile = try std.fs.cwd().createFile(outpath, .{}); + defer outfile.close(); + var outwriter = outfile.writer(); + + // maintain a stack corresponding to #if blocks we are inside of + // - bit 1 is if we should be outputting these lines (because the version matches) + // - bit 2 is if this #if block is one we added to make the universal header (we don't want to output those) + var outputing = std.ArrayList(u2).init(arena); + + var in_comment: bool = false; + for (inlines.items) |line| { + if (debug) std.debug.print("{d} {s}\n", .{ outputing.items.len, line }); + var com = in_comment; + if (!in_comment and std.mem.indexOf(u8, line, "/*") != null and std.mem.indexOf(u8, line, "*/") == null) { + in_comment = true; + } else if (in_comment and std.mem.indexOf(u8, line, "/*") == null and std.mem.indexOf(u8, line, "*/") != null) { + in_comment = false; // next line will be out of comment + } + var trimmed = std.mem.trimLeft(u8, line, " "); + if (!com and std.mem.startsWith(u8, trimmed, "#")) { + trimmed = trimmed[1..]; + trimmed = std.mem.trimLeft(u8, trimmed, " "); + if (debug) std.debug.print("trimmed {s}\n", .{trimmed}); + if (std.mem.startsWith(u8, trimmed, "if")) { + if (debug) std.debug.print("- if\n", .{}); + if (std.mem.indexOf(u8, trimmed, "_ZIG_UH_") != null) { + var found = false; + if (std.mem.indexOf(u8, trimmed, versionStr) != null) { + found = true; + } else { + // look for versionStr in each reduction, and see + // if that reduction matches + inline for (@typeInfo(@TypeOf(reductions)).Struct.fields) |f| blk: { + const field = @field(reductions, f.name); + for (0..field.len - 1) |i| { + if (std.mem.eql(u8, versionStr, field[i])) { + if (std.mem.indexOf(u8, trimmed, field[field.len - 1]) != null) { + found = true; + break :blk; + } + } + } + } + } + + if (found) { + try outputing.append(3); + } else { + try outputing.append(2); + } + continue; + } else { + const currently_outputting = (outputing.items.len == 0 or outputing.items[outputing.items.len - 1] & 1 > 0); + try outputing.append(if (currently_outputting) 1 else 0); + } + } else if (std.mem.startsWith(u8, trimmed, "endif")) { + if (outputing.items.len == 0) { + return error.dangling_endif; + } + + if (outputing.items[outputing.items.len - 1] & 2 > 0) { + _ = outputing.pop(); + continue; + } else { + _ = outputing.pop(); + } + } + } + + if (outputing.items.len == 0 or outputing.items[outputing.items.len - 1] & 1 > 0) { + try outwriter.print("{s}\n", .{line}); + } + } + } +}