ya-ar/gen_libarchive_sys.zig

272 lines
8 KiB
Zig

const std = @import("std");
const c = @cImport({
@cInclude("archive.h");
@cInclude("archive_entry.h");
});
const W = *std.Io.Writer;
fn writeRustType(w: W, comptime T: type) std.Io.Writer.Error!void {
if (T == c_int) return w.writeAll("c_int");
if (T == c_uint) return w.writeAll("c_uint");
if (T == c_long) return w.writeAll("c_long");
if (T == c_ulong) return w.writeAll("c_ulong");
if (T == usize) return w.writeAll("usize");
if (T == isize) return w.writeAll("isize");
if (T == i64) return w.writeAll("i64");
if (T == u64) return w.writeAll("u64");
if (T == i32) return w.writeAll("i32");
if (T == u32) return w.writeAll("u32");
if (T == c.struct_archive) return w.writeAll("archive");
if (T == c.struct_archive_entry) return w.writeAll("archive_entry");
if (T == anyopaque) return w.writeAll("c_void");
if (T == u8) return w.writeAll("c_char");
switch (@typeInfo(T)) {
.optional => |o| return writeRustType(w, o.child),
.pointer => |p| {
try w.writeAll(if (p.is_const) "*const " else "*mut ");
return writeRustType(w, p.child);
},
else => @compileError("unhandled type: " ++ @typeName(T)),
}
}
fn FnInfo(comptime name: []const u8) type {
const F = @TypeOf(@field(c, name));
const raw = @typeInfo(F);
return switch (raw) {
.@"fn" => F,
.pointer => |p| p.child,
else => @compileError("expected fn for " ++ name),
};
}
fn writeFn(w: W, comptime name: []const u8) std.Io.Writer.Error!void {
const fi = @typeInfo(FnInfo(name)).@"fn";
try w.writeAll(" pub fn " ++ name ++ "(");
inline for (fi.params, 0..) |param, i| {
if (i > 0) try w.writeAll(", ");
try w.print("_{d}: ", .{i});
try writeRustType(w, param.type.?);
}
try w.writeAll(")");
if (fi.return_type) |ret| {
if (ret != void) {
try w.writeAll(" -> ");
try writeRustType(w, ret);
}
}
try w.writeAll(";\n");
}
pub fn main() !void {
var buf: [4096]u8 = undefined;
var fw = std.fs.File.stdout().writerStreaming(&buf);
const w: W = &fw.interface;
try w.writeAll(
\\#![allow(non_camel_case_types, dead_code, unused_imports)]
\\
\\use std::os::raw::{c_char, c_int, c_long, c_uint, c_void};
\\
\\// Opaque types
\\#[repr(C)]
\\pub struct archive {
\\ _opaque: [u8; 0],
\\}
\\
\\#[repr(C)]
\\pub struct archive_entry {
\\ _opaque: [u8; 0],
\\}
\\
\\
);
// Return codes
try w.writeAll("// Return codes\n");
inline for (.{ "ARCHIVE_EOF", "ARCHIVE_OK", "ARCHIVE_WARN" }) |name| {
try w.print("pub const {s}: c_int = {d};\n", .{ name, @as(c_int, @field(c, name)) });
}
// Format codes
try w.writeAll("\n// Format codes\n");
inline for (.{
"ARCHIVE_FORMAT_BASE_MASK",
"ARCHIVE_FORMAT_CPIO",
"ARCHIVE_FORMAT_TAR",
"ARCHIVE_FORMAT_ISO9660",
"ARCHIVE_FORMAT_ZIP",
"ARCHIVE_FORMAT_EMPTY",
"ARCHIVE_FORMAT_AR",
"ARCHIVE_FORMAT_MTREE",
"ARCHIVE_FORMAT_RAW",
"ARCHIVE_FORMAT_XAR",
"ARCHIVE_FORMAT_LHA",
"ARCHIVE_FORMAT_CAB",
"ARCHIVE_FORMAT_RAR",
"ARCHIVE_FORMAT_7ZIP",
"ARCHIVE_FORMAT_WARC",
"ARCHIVE_FORMAT_RAR_V5",
}) |name| {
try w.print("pub const {s}: u32 = 0x{x};\n", .{ name, @as(c_uint, @field(c, name)) });
}
// Filter codes
try w.writeAll("\n// Filter codes\n");
inline for (.{
"ARCHIVE_FILTER_NONE",
"ARCHIVE_FILTER_GZIP",
"ARCHIVE_FILTER_BZIP2",
"ARCHIVE_FILTER_COMPRESS",
"ARCHIVE_FILTER_LZMA",
"ARCHIVE_FILTER_XZ",
"ARCHIVE_FILTER_UU",
"ARCHIVE_FILTER_RPM",
"ARCHIVE_FILTER_LZIP",
"ARCHIVE_FILTER_LRZIP",
"ARCHIVE_FILTER_LZOP",
"ARCHIVE_FILTER_GRZIP",
"ARCHIVE_FILTER_LZ4",
"ARCHIVE_FILTER_ZSTD",
}) |name| {
try w.print("pub const {s}: u32 = {d};\n", .{ name, @as(c_uint, @field(c, name)) });
}
// Extract flags
try w.writeAll("\n// Extract flags\n");
inline for (.{
"ARCHIVE_EXTRACT_TIME",
"ARCHIVE_EXTRACT_PERM",
"ARCHIVE_EXTRACT_ACL",
"ARCHIVE_EXTRACT_FFLAGS",
"ARCHIVE_EXTRACT_SECURE_SYMLINKS",
"ARCHIVE_EXTRACT_SECURE_NODOTDOT",
"ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS",
}) |name| {
try w.print("pub const {s}: u32 = 0x{x:0>4};\n", .{ name, @as(c_uint, @field(c, name)) });
}
// File type constants (from POSIX stat) — hardcoded, zig cImport can't translate octal macros
try w.writeAll("\n// File type constants (from POSIX stat)\n");
try w.writeAll("pub const AE_IFREG: u32 = 0o100000;\n");
try w.writeAll("pub const AE_IFDIR: u32 = 0o040000;\n");
try w.writeAll("pub const AE_IFLNK: u32 = 0o120000;\n");
// Functions
try w.writeAll(
\\
\\unsafe extern "C" {
\\
);
// Reader
try w.writeAll(" // Reader\n");
inline for (.{
"archive_read_new",
"archive_read_free",
"archive_read_support_format_all",
"archive_read_support_format_raw",
"archive_read_support_filter_all",
"archive_read_open_filename",
"archive_read_open_memory",
"archive_read_next_header",
"archive_read_next_header2",
"archive_read_data",
"archive_read_data_block",
}) |name| {
try writeFn(w, name);
}
// Writer
try w.writeAll("\n // Writer\n");
inline for (.{
"archive_write_new",
"archive_write_free",
"archive_write_set_format",
"archive_write_set_format_raw",
"archive_write_set_format_pax_restricted",
"archive_write_set_format_zip",
"archive_write_set_format_7zip",
"archive_write_set_format_ar_svr4",
"archive_write_set_format_cpio_newc",
"archive_write_add_filter",
"archive_write_add_filter_none",
"archive_write_open_filename",
"archive_write_open_fd",
"archive_write_header",
"archive_write_data",
"archive_write_finish_entry",
"archive_write_close",
}) |name| {
try writeFn(w, name);
}
// Disk reader
try w.writeAll("\n // Disk reader\n");
inline for (.{
"archive_read_disk_new",
"archive_read_disk_set_standard_lookup",
"archive_read_disk_open",
"archive_read_disk_descend",
}) |name| {
try writeFn(w, name);
}
// Disk writer
try w.writeAll("\n // Disk writer\n");
inline for (.{
"archive_write_disk_new",
"archive_write_disk_set_options",
"archive_write_disk_set_standard_lookup",
}) |name| {
try writeFn(w, name);
}
// Entry
try w.writeAll("\n // Entry\n");
inline for (.{
"archive_entry_new",
"archive_entry_free",
"archive_entry_clear",
"archive_entry_pathname",
"archive_entry_pathname_utf8",
"archive_entry_set_pathname_utf8",
"archive_entry_size",
"archive_entry_set_size",
"archive_entry_filetype",
"archive_entry_set_filetype",
"archive_entry_perm",
"archive_entry_set_perm",
"archive_entry_set_mtime",
"archive_entry_set_atime",
"archive_entry_set_ctime",
"archive_entry_set_uid",
"archive_entry_set_gid",
"archive_entry_set_uname_utf8",
"archive_entry_set_gname_utf8",
"archive_entry_hardlink_utf8",
"archive_entry_symlink_utf8",
}) |name| {
try writeFn(w, name);
}
// Metadata
try w.writeAll("\n // Metadata\n");
inline for (.{
"archive_format",
"archive_filter_count",
"archive_filter_code",
"archive_filter_name",
"archive_format_name",
"archive_error_string",
}) |name| {
try writeFn(w, name);
}
try w.writeAll("}\n");
try w.flush();
}