diff --git a/pkg/oniguruma/build.zig b/pkg/oniguruma/build.zig index 920a17460..70a1e9312 100644 --- a/pkg/oniguruma/build.zig +++ b/pkg/oniguruma/build.zig @@ -24,7 +24,7 @@ pub fn build(b: *std.Build) !void { test_step.dependOn(&tests_run.step); // Uncomment this if we're debugging tests - // b.installArtifact(test_exe); + b.installArtifact(test_exe); } } diff --git a/pkg/oniguruma/errors.zig b/pkg/oniguruma/errors.zig index f5ec71279..b9edf2d36 100644 --- a/pkg/oniguruma/errors.zig +++ b/pkg/oniguruma/errors.zig @@ -5,9 +5,9 @@ const Encoding = @import("types.zig").Encoding; pub const MAX_ERROR_LEN = c.ONIG_MAX_ERROR_MESSAGE_LEN; /// Convert an Oniguruma error to an error. -pub fn convertError(code: c_int) !void { +pub fn convertError(code: c_int) !c_int { + if (code >= 0) return code; switch (code) { - c.ONIG_NORMAL => {}, else => return error.OnigurumaError, } } diff --git a/pkg/oniguruma/init.zig b/pkg/oniguruma/init.zig index 531f9e0c7..3e40887c0 100644 --- a/pkg/oniguruma/init.zig +++ b/pkg/oniguruma/init.zig @@ -5,7 +5,7 @@ const errors = @import("errors.zig"); /// Call once per process to initialize Oniguruma. This should be given /// the encodings that the program will use. pub fn init(encs: []const *Encoding) !void { - try errors.convertError(c.onig_initialize( + _ = try errors.convertError(c.onig_initialize( @constCast(@ptrCast(@alignCast(encs.ptr))), @intCast(encs.len), )); diff --git a/pkg/oniguruma/main.zig b/pkg/oniguruma/main.zig index 113f23e5c..5e56c70be 100644 --- a/pkg/oniguruma/main.zig +++ b/pkg/oniguruma/main.zig @@ -1,6 +1,7 @@ pub usingnamespace @import("init.zig"); pub usingnamespace @import("errors.zig"); pub usingnamespace @import("regex.zig"); +pub usingnamespace @import("region.zig"); pub usingnamespace @import("types.zig"); pub const c = @import("c.zig"); diff --git a/pkg/oniguruma/regex.zig b/pkg/oniguruma/regex.zig index 490129220..3e4e563d5 100644 --- a/pkg/oniguruma/regex.zig +++ b/pkg/oniguruma/regex.zig @@ -3,6 +3,7 @@ const c = @import("c.zig"); const types = @import("types.zig"); const errors = @import("errors.zig"); const testEnsureInit = @import("testing.zig").ensureInit; +const Region = @import("region.zig").Region; const ErrorInfo = errors.ErrorInfo; const Encoding = types.Encoding; const Option = types.Option; @@ -19,7 +20,7 @@ pub const Regex = struct { err: ?*ErrorInfo, ) !Regex { var self: Regex = undefined; - try errors.convertError(c.onig_new( + _ = try errors.convertError(c.onig_new( &self.value, pattern.ptr, pattern.ptr + pattern.len, @@ -34,10 +35,49 @@ pub const Regex = struct { pub fn deinit(self: *Regex) void { c.onig_free(self.value); } + + /// onig_search shorthand to search an entire string. + pub fn search( + self: *Regex, + str: []const u8, + region: *Region, + options: Option, + ) !usize { + return try self.searchAdvanced(str, 0, str.len, region, options); + } + + /// onig_search + pub fn searchAdvanced( + self: *Regex, + str: []const u8, + start: usize, + end: usize, + region: *Region, + options: Option, + ) !usize { + const pos = try errors.convertError(c.onig_search( + self.value, + str.ptr, + str.ptr + str.len, + str.ptr + start, + str.ptr + end, + @ptrCast(region), + options.int(), + )); + + return @intCast(pos); + } }; test { + const testing = std.testing; + try testEnsureInit(); var re = try Regex.init("foo", .{}, Encoding.utf8, Syntax.default, null); defer re.deinit(); + + var region: Region = .{}; + defer region.deinit(); + const pos = try re.search("hello foo bar", ®ion, .{}); + try testing.expectEqual(@as(usize, 6), pos); } diff --git a/pkg/oniguruma/region.zig b/pkg/oniguruma/region.zig new file mode 100644 index 000000000..b8c61fc4f --- /dev/null +++ b/pkg/oniguruma/region.zig @@ -0,0 +1,16 @@ +const std = @import("std"); +const c = @import("c.zig"); + +pub const Region = extern struct { + allocated: c_int = 0, + num_regs: c_int = 0, + beg: ?[*]c_int = null, + end: ?[*]c_int = null, + history_root: ?*c.OnigCaptureTreeNode = null, // TODO: convert to Zig + + pub fn deinit(self: *Region) void { + // We never free ourself because allocation of Region in the Zig + // bindings is handled by the Zig program. + c.onig_region_free(@ptrCast(self), 0); + } +};