diff --git a/pkg/oniguruma/build.zig b/pkg/oniguruma/build.zig new file mode 100644 index 000000000..920a17460 --- /dev/null +++ b/pkg/oniguruma/build.zig @@ -0,0 +1,130 @@ +const std = @import("std"); +const NativeTargetInfo = std.zig.system.NativeTargetInfo; + +pub fn build(b: *std.Build) !void { + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + + _ = b.addModule("oniguruma", .{ .source_file = .{ .path = "main.zig" } }); + + const upstream = b.dependency("oniguruma", .{}); + const lib = try buildOniguruma(b, upstream, target, optimize); + b.installArtifact(lib); + + { + const test_exe = b.addTest(.{ + .name = "test", + .root_source_file = .{ .path = "main.zig" }, + .target = target, + .optimize = optimize, + }); + test_exe.linkLibrary(lib); + const tests_run = b.addRunArtifact(test_exe); + const test_step = b.step("test", "Run tests"); + test_step.dependOn(&tests_run.step); + + // Uncomment this if we're debugging tests + // b.installArtifact(test_exe); + } +} + +fn buildOniguruma( + b: *std.Build, + upstream: *std.Build.Dependency, + target: std.zig.CrossTarget, + optimize: std.builtin.OptimizeMode, +) !*std.Build.Step.Compile { + const lib = b.addStaticLibrary(.{ + .name = "oniguruma", + .target = target, + .optimize = optimize, + }); + const t = lib.target_info.target; + lib.linkLibC(); + lib.addIncludePath(upstream.path("src")); + + lib.addConfigHeader(b.addConfigHeader(.{ + .style = .{ .cmake = upstream.path("src/config.h.cmake.in") }, + }, .{ + .PACKAGE = "oniguruma", + .PACKAGE_VERSION = "6.9.9", + .VERSION = "6.9.9", + .HAVE_STDINT_H = true, + .HAVE_SYS_TIMES_H = true, + .HAVE_SYS_TIME_H = true, + .HAVE_SYS_TYPES_H = true, + .HAVE_UNISTD_H = true, + .HAVE_INTTYPES_H = true, + .SIZEOF_INT = t.c_type_byte_size(.int), + .SIZEOF_LONG = t.c_type_byte_size(.long), + .SIZEOF_LONG_LONG = t.c_type_byte_size(.longlong), + .SIZEOF_VOIDP = t.ptrBitWidth() / t.c_type_bit_size(.char), + })); + + var flags = std.ArrayList([]const u8).init(b.allocator); + defer flags.deinit(); + try flags.appendSlice(&.{}); + lib.addCSourceFiles(.{ + .dependency = upstream, + .flags = flags.items, + .files = &.{ + "src/regerror.c", + "src/regparse.c", + "src/regext.c", + "src/regcomp.c", + "src/regexec.c", + "src/reggnu.c", + "src/regenc.c", + "src/regsyntax.c", + "src/regtrav.c", + "src/regversion.c", + "src/st.c", + "src/onig_init.c", + "src/unicode.c", + "src/ascii.c", + "src/utf8.c", + "src/utf16_be.c", + "src/utf16_le.c", + "src/utf32_be.c", + "src/utf32_le.c", + "src/euc_jp.c", + "src/sjis.c", + "src/iso8859_1.c", + "src/iso8859_2.c", + "src/iso8859_3.c", + "src/iso8859_4.c", + "src/iso8859_5.c", + "src/iso8859_6.c", + "src/iso8859_7.c", + "src/iso8859_8.c", + "src/iso8859_9.c", + "src/iso8859_10.c", + "src/iso8859_11.c", + "src/iso8859_13.c", + "src/iso8859_14.c", + "src/iso8859_15.c", + "src/iso8859_16.c", + "src/euc_tw.c", + "src/euc_kr.c", + "src/big5.c", + "src/gb18030.c", + "src/koi8_r.c", + "src/cp1251.c", + "src/euc_jp_prop.c", + "src/sjis_prop.c", + "src/unicode_unfold_key.c", + "src/unicode_fold1_key.c", + "src/unicode_fold2_key.c", + "src/unicode_fold3_key.c", + }, + }); + + lib.installHeadersDirectoryOptions(.{ + .source_dir = upstream.path("src"), + .install_dir = .header, + .install_subdir = "", + .include_extensions = &.{".h"}, + }); + + return lib; +} diff --git a/pkg/oniguruma/build.zig.zon b/pkg/oniguruma/build.zig.zon new file mode 100644 index 000000000..8e08a0ad2 --- /dev/null +++ b/pkg/oniguruma/build.zig.zon @@ -0,0 +1,11 @@ +.{ + .name = "oniguruma", + .version = "6.9.9", + .paths = .{""}, + .dependencies = .{ + .oniguruma = .{ + .url = "https://github.com/kkos/oniguruma/archive/refs/tags/v6.9.9.tar.gz", + .hash = "1220c15e72eadd0d9085a8af134904d9a0f5dfcbed5f606ad60edc60ebeccd9706bb", + }, + }, +} diff --git a/pkg/oniguruma/c.zig b/pkg/oniguruma/c.zig new file mode 100644 index 000000000..1788a6289 --- /dev/null +++ b/pkg/oniguruma/c.zig @@ -0,0 +1,3 @@ +pub usingnamespace @cImport({ + @cInclude("oniguruma.h"); +}); diff --git a/pkg/oniguruma/encoding.zig b/pkg/oniguruma/encoding.zig new file mode 100644 index 000000000..3407b8286 --- /dev/null +++ b/pkg/oniguruma/encoding.zig @@ -0,0 +1,5 @@ +const c = @import("c.zig"); + +pub const Encoding = opaque { + pub const utf8: *Encoding = @ptrCast(c.ONIG_ENCODING_UTF8); +}; diff --git a/pkg/oniguruma/errors.zig b/pkg/oniguruma/errors.zig new file mode 100644 index 000000000..25bf1d859 --- /dev/null +++ b/pkg/oniguruma/errors.zig @@ -0,0 +1,19 @@ +const c = @import("c.zig"); + +/// Maximum error message length. +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 { + switch (code) { + c.ONIG_NORMAL => {}, + else => return error.OnigurumaError, + } +} + +/// Convert an error code to a string. buf must be at least +/// MAX_ERROR_LEN bytes long. +pub fn errorString(buf: []u8, code: c_int) ![]u8 { + const len = c.onig_error_code_to_str(buf.ptr, code); + return buf[0..@intCast(len)]; +} diff --git a/pkg/oniguruma/init.zig b/pkg/oniguruma/init.zig new file mode 100644 index 000000000..edd19f80d --- /dev/null +++ b/pkg/oniguruma/init.zig @@ -0,0 +1,12 @@ +const c = @import("c.zig"); +const Encoding = @import("encoding.zig").Encoding; +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( + @constCast(@ptrCast(@alignCast(encs.ptr))), + @intCast(encs.len), + )); +} diff --git a/pkg/oniguruma/main.zig b/pkg/oniguruma/main.zig new file mode 100644 index 000000000..19ced50bc --- /dev/null +++ b/pkg/oniguruma/main.zig @@ -0,0 +1,8 @@ +pub usingnamespace @import("init.zig"); +pub usingnamespace @import("errors.zig"); +pub const c = @import("c.zig"); +pub const Encoding = @import("encoding.zig").Encoding; + +test { + @import("std").testing.refAllDecls(@This()); +} diff --git a/pkg/oniguruma/testing.zig b/pkg/oniguruma/testing.zig new file mode 100644 index 000000000..126ef49fa --- /dev/null +++ b/pkg/oniguruma/testing.zig @@ -0,0 +1,14 @@ +const init = @import("init.zig"); + +var initialized: bool = false; + +/// Call this function before any other tests in this package to ensure that +/// the oni library is initialized. This should only be used for tests +/// and only when you're sure this is the ONLY way that oni is being +/// initialized. +/// +/// This always only initializes the encodings the tests use. +pub fn ensureInit() !void { + if (initialized) return; + try init.init(); +}