diff --git a/.gitignore b/.gitignore index 09b93e9..cd2e6cc 100644 --- a/.gitignore +++ b/.gitignore @@ -5,8 +5,7 @@ # Zig programming language zig-cache/ -.zig-cache/ -zig-out/ +*zig-*/ build/ build-*/ docgen_tmp/ @@ -18,4 +17,4 @@ Vagrantfile zig-linux* libroot* .DS_Store -*.o \ No newline at end of file +*.o diff --git a/.tool-versions b/.tool-versions index 50a1011..d2df185 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1 +1,2 @@ -zig 0.15.2 +zig 0.16.0 +# zig 0.15.2 diff --git a/README.org b/README.org index b5b386c..476e226 100644 --- a/README.org +++ b/README.org @@ -31,12 +31,12 @@ const curl = @import("curl"); const URL = "https://edgebin.liujiacai.net/anything"; -pub fn main() !void { +pub fn main(init: std.process.Init) !void { var gpa: std.heap.DebugAllocator(.{}) = .init; defer if (gpa.deinit() != .ok) @panic("leak"); const allocator = gpa.allocator(); - const ca_bundle = try curl.allocCABundle(allocator); + const ca_bundle = try curl.allocCABundle(allocator, init.io); defer ca_bundle.deinit(); var easy = try curl.Easy.init(.{ .ca_bundle = ca_bundle, @@ -92,14 +92,14 @@ After fetch, import =curl= like this in your =build.zig=: #+begin_src zig const dep_curl = b.dependency("curl", .{}); exe.root_module.addImport("curl", dep_curl.module("curl")); -exe.linkLibC(); +exe.root_module.link_libc = true; #+end_src This library will link to a vendored libcurl by default, you can disable it and link to system-wide with this #+begin_src zig const dep_curl = b.dependency("curl", .{ .link_vendor = false }); -exe.linkSystemLibrary("curl"); -exe.linkLibC(); +exe.root_module.linkSystemLibrary("curl", .{}); +exe.root_module.link_libc = true; #+end_src * License diff --git a/build.zig b/build.zig index cbdf3eb..df13a71 100644 --- a/build.zig +++ b/build.zig @@ -51,9 +51,9 @@ pub fn build(b: *Build) !void { }); if (libcurl) |lib| { - main_tests.linkLibrary(lib); + main_tests.root_module.linkLibrary(lib); } else { - main_tests.linkSystemLibrary("curl"); + main_tests.root_module.linkSystemLibrary("curl", .{}); } const run_main_tests = b.addRunArtifact(main_tests); @@ -104,8 +104,8 @@ fn buildLibcurl( } const libcurl = curl.?; - libcurl.linkLibrary(tls.?); - libcurl.linkLibrary(zlib.?); + libcurl.root_module.linkLibrary(tls.?); + libcurl.root_module.linkLibrary(zlib.?); return libcurl; } @@ -130,9 +130,9 @@ fn addExample( exe.root_module.addImport(MODULE_NAME, curl_module); if (libcurl) |lib| { - exe.linkLibrary(lib); + exe.root_module.linkLibrary(lib); } else { - exe.linkSystemLibrary("curl"); + exe.root_module.linkSystemLibrary("curl", .{}); } const run_step = b.step( @@ -154,7 +154,7 @@ fn parseManifest(b: *Build) !Manifest { const input = @embedFile("build.zig.zon"); var diagnostics: std.zon.parse.Diagnostics = .{}; defer diagnostics.deinit(b.allocator); - const parsed = std.zon.parse.fromSlice( + const parsed = std.zon.parse.fromSliceAlloc( Manifest, b.allocator, input, diff --git a/build.zig.zon b/build.zig.zon index 31b85ea..ae0a22e 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -2,7 +2,7 @@ .name = .curl, .fingerprint = 0x3e01b4de1538b3f, .version = "0.4.0", - .minimum_zig_version = "0.15.2", + .minimum_zig_version = "0.16.0", .paths = .{ "src", "libs", diff --git a/examples/advanced.zig b/examples/advanced.zig index 9d72169..4db630b 100644 --- a/examples/advanced.zig +++ b/examples/advanced.zig @@ -111,12 +111,12 @@ fn postMultiPart(allocator: Allocator, easy: *Easy) !void { std.debug.print("code: {d}, resp:{s}\n", .{ resp.status_code, writer.writer.buffered() }); } -pub fn main() !void { +pub fn main(init: std.process.Init) !void { var gpa = std.heap.DebugAllocator(.{}){}; defer if (gpa.deinit() != .ok) @panic("leak"); const allocator = gpa.allocator(); - const ca_bundle = try curl.allocCABundle(allocator); + const ca_bundle = try curl.allocCABundle(allocator, init.io); defer ca_bundle.deinit(); var easy = try Easy.init(.{ diff --git a/examples/basic.zig b/examples/basic.zig index 44451a6..f034907 100644 --- a/examples/basic.zig +++ b/examples/basic.zig @@ -3,12 +3,12 @@ const curl = @import("curl"); const URL = "https://edgebin.liujiacai.net/anything"; -pub fn main() !void { +pub fn main(init: std.process.Init) !void { var gpa: std.heap.DebugAllocator(.{}) = .init; defer if (gpa.deinit() != .ok) @panic("leak"); const allocator = gpa.allocator(); - const ca_bundle = try curl.allocCABundle(allocator); + const ca_bundle = try curl.allocCABundle(allocator, init.io); defer ca_bundle.deinit(); var easy = try curl.Easy.init(.{ .ca_bundle = ca_bundle, diff --git a/examples/header.zig b/examples/header.zig index ffb47d1..1278e2f 100644 --- a/examples/header.zig +++ b/examples/header.zig @@ -58,12 +58,12 @@ fn iterateRedirectedHeaders(easy: *Easy) !void { try std.testing.expectEqual(count, 2); } -pub fn main() !void { +pub fn main(init: std.process.Init) !void { var gpa = std.heap.DebugAllocator(.{}){}; defer if (gpa.deinit() != .ok) @panic("leak"); const allocator = gpa.allocator(); - const ca_bundle = try curl.allocCABundle(allocator); + const ca_bundle = try curl.allocCABundle(allocator, init.io); defer ca_bundle.deinit(); var easy = try Easy.init(.{ .ca_bundle = ca_bundle }); defer easy.deinit(); diff --git a/examples/multi.zig b/examples/multi.zig index 5c0b97d..0653cdc 100644 --- a/examples/multi.zig +++ b/examples/multi.zig @@ -7,7 +7,7 @@ const Easy = curl.Easy; const Multi = curl.Multi; const c = curl.libcurl; const checkCode = curl.checkCode; -const Writer = std.io.Writer; +const Writer = std.Io.Writer; fn newEasy(writer: *Writer, url: [:0]const u8) !Easy { var easy = try Easy.init(.{}); diff --git a/examples/post.zig b/examples/post.zig index 658c652..93c73e0 100644 --- a/examples/post.zig +++ b/examples/post.zig @@ -1,12 +1,12 @@ const std = @import("std"); const curl = @import("curl"); -pub fn main() !void { +pub fn main(init: std.process.Init) !void { var gpa = std.heap.DebugAllocator(.{}){}; defer if (gpa.deinit() != .ok) @panic("leak"); const allocator = gpa.allocator(); - const ca_bundle = try curl.allocCABundle(allocator); + const ca_bundle = try curl.allocCABundle(allocator, init.io); defer ca_bundle.deinit(); var easy = try curl.Easy.init(.{ .ca_bundle = ca_bundle, diff --git a/examples/upload.zig b/examples/upload.zig index 8006f3a..a053b34 100644 --- a/examples/upload.zig +++ b/examples/upload.zig @@ -5,13 +5,13 @@ const Allocator = std.mem.Allocator; const URL = "https://edgebin.liujiacai.net/anything"; -pub fn main() !void { +pub fn main(init: std.process.Init) !void { println("Upload demo"); var gpa = std.heap.DebugAllocator(.{}){}; defer if (gpa.deinit() != .ok) @panic("leak"); const allocator = gpa.allocator(); - const ca_bundle = try curl.allocCABundle(allocator); + const ca_bundle = try curl.allocCABundle(allocator, init.io); defer ca_bundle.deinit(); var easy = try curl.Easy.init(.{ .ca_bundle = ca_bundle, @@ -22,11 +22,11 @@ pub fn main() !void { var writer = std.Io.Writer.Allocating.init(allocator); defer writer.deinit(); - const file = try std.fs.cwd().openFile(path, .{}); - defer file.close(); + const file = try std.Io.Dir.cwd().openFile(init.io, path, .{}); + defer file.close(init.io); var buf: [4096]u8 = undefined; - var reader = file.reader(&buf); + var reader = file.reader(init.io, &buf); const resp = try easy.upload(URL, &reader.interface, &writer.writer); std.debug.print("Status code: {d}\nBody: {s}\n", .{ diff --git a/libs/curl.zig b/libs/curl.zig index 66ddae6..e583a4a 100644 --- a/libs/curl.zig +++ b/libs/curl.zig @@ -1,15 +1,17 @@ const std = @import("std"); pub fn create(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, sanitize_c: ?std.zig.SanitizeC, mbedtls_pthreads: bool) ?*std.Build.Step.Compile { + const module = b.createModule(.{ + .target = target, + .optimize = optimize, + .link_libc = true, + .sanitize_c = sanitize_c, + }); + const lib = b.addLibrary(.{ .linkage = .static, .name = "curl", - .root_module = b.createModule(.{ - .target = target, - .optimize = optimize, - .link_libc = true, - .sanitize_c = sanitize_c, - }), + .root_module = module, }); const curl_dep = b.lazyDependency("curl", .{ .target = target, @@ -17,13 +19,13 @@ pub fn create(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.bui }) orelse return null; inline for (srcs) |s| { - lib.addCSourceFile(.{ + module.addCSourceFile(.{ .file = curl_dep.path(s), .flags = &.{"-std=gnu89"}, }); } - lib.addIncludePath(curl_dep.path("lib")); - lib.addIncludePath(curl_dep.path("include")); + module.addIncludePath(curl_dep.path("lib")); + module.addIncludePath(curl_dep.path("include")); lib.installHeadersDirectory(curl_dep.path("include/curl"), "curl", .{}); lib.root_module.addCMacro("BUILDING_LIBCURL", "1"); lib.root_module.addCMacro("CURL_STATICLIB", "1"); @@ -49,7 +51,7 @@ pub fn create(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.bui lib.root_module.addCMacro("HAVE_LIBZ", "1"); lib.root_module.addCMacro("HAVE_ZLIB_H", "1"); if (target.result.os.tag == .windows) { - lib.linkSystemLibrary("bcrypt"); + module.linkSystemLibrary("bcrypt", .{}); return lib; } lib.root_module.addCMacro("CURL_EXTERN_SYMBOL", "__attribute__ ((__visibility__ (\"default\"))"); diff --git a/libs/mbedtls.zig b/libs/mbedtls.zig index ead1b0b..f57f0ff 100644 --- a/libs/mbedtls.zig +++ b/libs/mbedtls.zig @@ -18,11 +18,11 @@ pub fn create(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.bui .optimize = optimize, }) orelse return null; inline for (srcs) |s| { - lib.addCSourceFile(.{ .file = mbedtls_dep.path(s), .flags = &.{"-std=c99"} }); + lib.root_module.addCSourceFile(.{ .file = mbedtls_dep.path(s), .flags = &.{"-std=c99"} }); } - lib.addIncludePath(mbedtls_dep.path("include")); - lib.addIncludePath(mbedtls_dep.path("library")); + lib.root_module.addIncludePath(mbedtls_dep.path("include")); + lib.root_module.addIncludePath(mbedtls_dep.path("library")); lib.installHeadersDirectory(mbedtls_dep.path("include/mbedtls"), "mbedtls", .{}); lib.installHeadersDirectory(mbedtls_dep.path("include/psa"), "psa", .{}); if (enable_pthreads) { @@ -31,7 +31,7 @@ pub fn create(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.bui } if (target.result.os.tag == .windows) { - lib.linkSystemLibrary("ws2_32"); + lib.root_module.linkSystemLibrary("ws2_32", .{}); } return lib; } diff --git a/libs/zlib.zig b/libs/zlib.zig index 54cd42e..1b68a48 100644 --- a/libs/zlib.zig +++ b/libs/zlib.zig @@ -1,15 +1,17 @@ const std = @import("std"); pub fn create(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, sanitize_c: ?std.zig.SanitizeC) ?*std.Build.Step.Compile { + const module = b.createModule(.{ + .target = target, + .optimize = optimize, + .link_libc = true, + .sanitize_c = sanitize_c, + }); + const lib = b.addLibrary(.{ .linkage = .static, .name = "z", - .root_module = b.createModule(.{ - .target = target, - .optimize = optimize, - .link_libc = true, - .sanitize_c = sanitize_c, - }), + .root_module = module, }); const zlib_dep = b.lazyDependency("zlib", .{ .target = target, @@ -17,7 +19,7 @@ pub fn create(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.bui }) orelse return null; inline for (srcs) |s| { - lib.addCSourceFile(.{ + module.addCSourceFile(.{ .file = zlib_dep.path(s), .flags = &.{"-std=c89"}, }); diff --git a/src/Easy.zig b/src/Easy.zig index 01af6d3..c2e0067 100644 --- a/src/Easy.zig +++ b/src/Easy.zig @@ -341,7 +341,8 @@ pub fn setWritedata(self: *Self, data: *anyopaque) !void { /// The function should return the number of bytes written, or 0 to indicate an error. /// There are two write functions provided by this library: /// 1. `discardWriteCallback` - does nothing, used when you don't care about the response body. -/// 2. `stdoutWriteCallback` - writes the response body to stdout. +/// 2. `stdoutWriteCallback` - writes the response body to stdout; requires +/// `setWritedata` to be called with a `*const std.Io`. /// /// https://curl.se/libcurl/c/CURLOPT_WRITEFUNCTION.html pub fn setWritefunction( @@ -482,15 +483,12 @@ pub fn discardWriteCallback(ptr: [*c]c_char, size: c_uint, nmemb: c_uint, user_d } /// A write callback that writes the response body to stdout. +/// `user_data` must be a `*const std.Io` (pass via `setWritedata`). pub fn stdoutWriteCallback(ptr: [*c]c_char, size: c_uint, nmemb: c_uint, user_data: *anyopaque) callconv(.c) c_uint { - _ = user_data; - const stdout = std.fs.File.stdout(); - var writer = stdout.writer(&.{}); // empty buffer means unbuffered + const io: *const std.Io = @ptrCast(@alignCast(user_data)); const real_size = size * nmemb; const data = (@as([*]const u8, @ptrCast(ptr)))[0..real_size]; - writer.writeAll(data) catch { - return 0; - }; + std.Io.File.stdout().writeStreamingAll(io.*, data) catch return 0; return real_size; } diff --git a/src/util.zig b/src/util.zig index 22df3bf..c436d45 100644 --- a/src/util.zig +++ b/src/util.zig @@ -93,12 +93,12 @@ test "url encode" { const CERT_MARKER_BEGIN = "-----BEGIN CERTIFICATE-----"; const CERT_MARKER_END = "\n-----END CERTIFICATE-----\n"; -pub fn allocCABundle(allocator: std.mem.Allocator) !ResizableBuffer { - var bundle: std.crypto.Certificate.Bundle = .{}; +pub fn allocCABundle(allocator: std.mem.Allocator, io: std.Io) !ResizableBuffer { + var bundle: std.crypto.Certificate.Bundle = .empty; defer bundle.deinit(allocator); var blob = ResizableBuffer.init(allocator); - try bundle.rescan(allocator); + try bundle.rescan(allocator, io, .now(io, .real)); var iter = bundle.map.iterator(); while (iter.next()) |entry| { const der = try std.crypto.Certificate.der.Element.parse(bundle.bytes.items, entry.value_ptr.*);