patched utilities.c / zig build test works with parser

This commit is contained in:
Emil Lerch 2025-09-18 14:42:22 -07:00
parent a30c6d9ea1
commit e313e33487
Signed by: lobo
GPG key ID: A7B62D657EF764F8
4 changed files with 59 additions and 51 deletions

View file

@ -26,6 +26,50 @@ pub fn build(b: *std.Build) void {
const upstream = download_link_step.dependency(b, .{});
// mod tests fail because the library has unconditional output to stdout,
// which messes with the test runner. So...we need to patch utilities.c with search:
// printf(" Opening
//
// replace:
// if ( verbosity > 0 ) printf(" Opening
//
const Substitutions = struct { orig: []const u8, new: []const u8 };
const patterns: [4]Substitutions = .{
.{
.orig = "\tprintf(\" Opening %s\\n\", filename); ",
.new = "\tif ( verbosity > 0 ) printf(\" Opening %s\\n\", filename); ",
},
.{
.orig = "\tprintf(\" Opening %s\\n\", filename);",
.new = "\tif ( verbosity > 0 ) printf(\" Opening %s\\n\", filename);",
},
.{
.orig = "\t printf(\" Opening %s\\n\", completename); ",
.new = "\t if ( verbosity > 0 ) printf(\" Opening %s\\n\", completename); ",
},
.{
.orig = " printf(\" Opening %s\\n\", completename); ",
.new = " if ( verbosity > 0 ) printf(\" Opening %s\\n\", completename); ",
},
};
// pat5 is same as pat3
//const pat5 = \t printf(" Opening %s\n", completename); ";
// Create sed-lite run step to patch utilities.c
const sed_lite = b.dependency("sed_lite", .{});
const sed_lite_exe = sed_lite.artifact("sed-lite");
const patch_cmd = b.addRunArtifact(sed_lite_exe);
patch_cmd.addArg("-sL");
for (patterns) |s| {
patch_cmd.addArg(s.orig);
patch_cmd.addArg(s.new);
}
patch_cmd.addFileArg(upstream.path("src/utilities.c"));
patch_cmd.step.dependOn(&download_link_step.step);
const lib = b.addLibrary(.{
.name = "link",
.linkage = .static,
@ -36,7 +80,7 @@ pub fn build(b: *std.Build) void {
}),
});
lib.step.dependOn(&download_link_step.step);
lib.step.dependOn(&patch_cmd.step);
lib.addIncludePath(upstream.path("include"));
lib.addCSourceFiles(.{
@ -78,6 +122,7 @@ pub fn build(b: *std.Build) void {
"-fwrapv",
},
});
// This creates a module, which represents a collection of source files alongside
// some compilation options, such as optimization mode and linked system libraries.
// Zig modules are the preferred way of making Zig code available to consumers.
@ -211,12 +256,7 @@ pub fn build(b: *std.Build) void {
// make the two of them run in parallel.
const test_step = b.step("test", "Run tests");
// mod tests fail because we need to patch utilities.c with search:
// printf(" Opening
//
// replace:
// if ( verbosity > 0 ) printf(" Opening
//test_step.dependOn(&run_mod_tests.step);
test_step.dependOn(&run_mod_tests.step);
test_step.dependOn(&run_exe_tests.step);
// Just like flags, top level steps are also listed in the `--help` menu.

View file

@ -32,44 +32,10 @@
// Once all dependencies are fetched, `zig build` no longer requires
// internet connectivity.
.dependencies = .{
// See `zig fetch --save <url>` for a command-line interface for adding dependencies.
//.example = .{
// // When updating this field to a new URL, be sure to delete the corresponding
// // `hash`, otherwise you are communicating that you expect to find the old hash at
// // the new URL. If the contents of a URL change this will result in a hash mismatch
// // which will prevent zig from using it.
// .url = "https://example.com/foo.tar.gz",
//
// // This is computed from the file contents of the directory of files that is
// // obtained after fetching `url` and applying the inclusion rules given by
// // `paths`.
// //
// // This field is the source of truth; packages do not come from a `url`; they
// // come from a `hash`. `url` is just one of many possible mirrors for how to
// // obtain a package matching this `hash`.
// //
// // Uses the [multihash](https://multiformats.io/multihash/) format.
// .hash = "...",
//
// // When this is provided, the package is found in a directory relative to the
// // build root. In this case the package's hash is irrelevant and therefore not
// // computed. This field and `url` are mutually exclusive.
// .path = "foo",
//
// // When this is set to `true`, a package is declared to be lazily
// // fetched. This makes the dependency only get fetched if it is
// // actually used.
// .lazy = false,
//},
.sed_lite = .{
.path = "sed-lite",
},
},
// Specifies the set of files and directories that are included in this package.
// Only files and directories listed here are included in the `hash` that
// is computed for this package. Only files listed here will remain on disk
// when using the zig package manager. As a rule of thumb, one should list
// files required for compilation plus any license(s).
// Paths are relative to the build root. Use the empty string (`""`) to refer to
// the build root itself.
// A directory listed here means that all files within, recursively, are included.
.paths = .{
"build.zig",
"build.zig.zon",

View file

@ -37,6 +37,8 @@ pub fn main() !u8 {
.original = args[2 + i * 2],
.replacement = args[3 + i * 2],
};
// const s = substitutions[i];
// try stdout.print("Replacing {s} -> {s}\n", .{ s.original, s.replacement });
}
const file = std.fs.cwd().openFile(file_path, .{ .mode = .read_only }) catch |err| {
@ -61,12 +63,14 @@ pub fn main() !u8 {
var writer_buffer: [4096]u8 = undefined;
var fwriter = temp_file.writer(&writer_buffer);
const writer = &fwriter.interface;
try substituteLines(
const subs = try substituteLines(
reader,
writer,
substitutions,
);
try writer.flush();
_ = subs;
// try stdout.print("Made {d} substitutions in file {s}\n", .{ subs, file_path });
std.fs.cwd().rename(temp_path, file_path) catch |err| {
try stderr.print("Error moving temp file: {}\n", .{err});
return 1;
@ -83,13 +87,15 @@ const Substitution = struct {
replacement: []const u8,
};
fn substituteLines(reader: *std.Io.Reader, writer: *std.Io.Writer, substitutions: []const Substitution) !void {
fn substituteLines(reader: *std.Io.Reader, writer: *std.Io.Writer, substitutions: []const Substitution) !usize {
var subs: usize = 0;
while (reader.takeDelimiterExclusive('\n')) |line| {
var substituted = false;
for (substitutions) |sub| {
if (std.mem.eql(u8, line, sub.original)) {
try writer.writeAll(sub.replacement);
substituted = true;
subs += 1;
break;
}
}
@ -99,8 +105,7 @@ fn substituteLines(reader: *std.Io.Reader, writer: *std.Io.Writer, substitutions
if (reader.peekByte() != error.EndOfStream)
try writer.writeByte('\n');
} else |err| if (err != error.EndOfStream) return err;
// write the final newline
// try writer.writeByte('\n');
return subs;
}
test "substitute lines exact match" {

View file

@ -38,7 +38,6 @@ pub const Parser = struct {
allocator: std.mem.Allocator,
pub fn init(allocator: std.mem.Allocator) !Parser {
std.debug.print("1", .{});
const dict = c.dictionary_create(
@ptrCast(@constCast("data/4.0.dict")),
@ptrCast(@constCast("data/4.0.knowledge")),
@ -47,10 +46,8 @@ pub const Parser = struct {
);
if (dict == null) return error.DictionaryCreationFailed;
std.debug.print("2", .{});
const opts = c.parse_options_create();
if (opts == null) return error.ParseOptionsCreationFailed;
std.debug.print("3", .{});
c.parse_options_set_verbosity(opts, 0);
c.parse_options_set_linkage_limit(opts, 100);