Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions build.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const builtin = @import("builtin");
const std = @import("std");

const zig_atleast_16 = @import("builtin").zig_version.order(.{ .major = 0, .minor = 16, .patch = 0 }) != .lt;

/// Create the xtt (x11 true type) module with a custom TrueType module.
pub fn createXtt(b: *std.Build, zigx_dep: *std.Build.Dependency, TrueType: *std.Build.Module) *std.Build.Module {
return b.createModule(.{
Expand Down Expand Up @@ -38,10 +40,17 @@ pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});

const zigversion_mod = b.createModule(.{
.root_source_file = if (zig_atleast_16) b.path("zigversion/atleast16.zig") else b.path("zigversion/before16.zig"),
});

// In almost all cases, Zig programs should only use this module, not the
// library defined below, that's for C programs.
const x_mod = b.addModule("x11", .{
.root_source_file = b.path("src/x.zig"),
.imports = &.{
.{ .name = "zigversion", .module = zigversion_mod },
},
});

const true_type_mod = b.dependency("TrueType", .{}).module("TrueType");
Expand Down Expand Up @@ -178,6 +187,9 @@ pub fn build(b: *std.Build) void {
const x_mod_with_target = b.createModule(.{
.root_source_file = b.path("src/x.zig"),
.target = target,
.imports = &.{
.{ .name = "zigversion", .module = zigversion_mod },
},
});
const unit_tests = b.addTest(.{
.root_module = x_mod_with_target,
Expand Down
60 changes: 5 additions & 55 deletions src/x.zig
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
// ...todo...
//

const zigversion = @import("zigversion");
const std = @import("std");
const stdext = @import("stdext.zig");
const testing = std.testing;
Expand Down Expand Up @@ -62,8 +63,8 @@ pub const record = @compileError("todo");
pub const BoundedArray = @import("bounded_array.zig").BoundedArray;
pub const charset = @import("charset.zig");
pub const Charset = charset.Charset;
pub const Slice = @import("x/slice.zig").Slice;
pub const SliceWithMaxLen = @import("x/slice.zig").SliceWithMaxLen;
pub const Slice = zigversion.Slice;
pub const SliceWithMaxLen = zigversion.SliceWithMaxLen;
pub const keymap = @import("keymap.zig");

pub const log = std.log.scoped(.x11);
Expand Down Expand Up @@ -1086,46 +1087,7 @@ const FmtRead = struct {
}
};

pub fn ArrayPointer(comptime T: type) type {
const err = "ArrayPointer not implemented for " ++ @typeName(T);
switch (@typeInfo(T)) {
.pointer => |info| {
switch (info.size) {
.one => {
switch (@typeInfo(info.child)) {
.Array => |array_info| {
return @Type(std.builtin.Type{ .pointer = .{
.size = .Many,
.is_const = true,
.is_volatile = false,
.alignment = @alignOf(array_info.child),
.address_space = info.address_space,
.child = array_info.child,
.is_allowzero = false,
.sentinel = array_info.sentinel,
} });
},
else => @compileError("here"),
}
},
.slice => {
return @Type(std.builtin.Type{ .pointer = .{
.size = .many,
.is_const = info.is_const,
.is_volatile = info.is_volatile,
.alignment = info.alignment,
.address_space = info.address_space,
.child = info.child,
.is_allowzero = info.is_allowzero,
.sentinel_ptr = info.sentinel_ptr,
} });
},
else => @compileError(err),
}
},
else => @compileError(err),
}
}
pub const ArrayPointer = zigversion.ArrayPointer;

pub fn slice(comptime LenType: type, s: anytype) Slice(LenType, ArrayPointer(@TypeOf(s))) {
switch (@typeInfo(@TypeOf(s))) {
Expand Down Expand Up @@ -3929,19 +3891,7 @@ pub const VisualType = extern struct {
unused: u32,
};

pub fn NonExhaustive(comptime T: type) type {
const info = switch (@typeInfo(T)) {
.@"enum" => |info| info,
else => |info| @compileError("expected an Enum type but got a(n) " ++ @tagName(info)),
};
std.debug.assert(info.is_exhaustive);
return @Type(std.builtin.Type{ .@"enum" = .{
.tag_type = info.tag_type,
.fields = info.fields,
.decls = &.{},
.is_exhaustive = false,
} });
}
pub const NonExhaustive = zigversion.NonExhaustive;
pub const ImageByteOrder = enum(u8) {
lsb_first = 0,
msb_first = 1,
Expand Down
54 changes: 54 additions & 0 deletions zigversion/atleast16.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
pub const Slice = @import("sliceatleast16.zig").Slice;
pub const SliceWithMaxLen = @import("sliceatleast16.zig").SliceWithMaxLen;

pub fn NonExhaustive(comptime T: type) type {
const info = switch (@typeInfo(T)) {
.@"enum" => |info| info,
else => |info| @compileError("expected an Enum type but got a(n) " ++ @tagName(info)),
};
std.debug.assert(info.is_exhaustive);
var names: [info.fields.len][]const u8 = undefined;
var values: [info.fields.len]info.tag_type = undefined;
for (&names, &values, info.fields) |*name, *value, field| {
name.* = field.name;
value.* = field.value;
}
return @Enum(info.tag_type, .nonexhaustive, &names, &values);
}

pub fn ArrayPointer(comptime T: type) type {
const err = "ArrayPointer not implemented for " ++ @typeName(T);
return switch (@typeInfo(T)) {
.pointer => |info| {
switch (info.size) {
.one => switch (@typeInfo(info.child)) {
.Array => |array_info| @Pointer(
.many,
.{
.@"const" = true,
},
array_info.child,
array_info.sentinel,
),
else => @compileError(err),
},
.slice => @Pointer(
.many,
.{
.@"const" = info.is_const,
.@"volatile" = info.is_volatile,
.@"align" = info.alignment,
.@"addrspace" = info.address_space,
.@"allowzero" = info.is_allowzero,
},
info.child,
info.sentinel_ptr,
),
else => @compileError(err),
}
},
else => @compileError(err),
};
}

const std = @import("std");
53 changes: 53 additions & 0 deletions zigversion/before16.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
pub const Slice = @import("slicebefore16.zig").Slice;
pub const SliceWithMaxLen = @import("slicebefore16.zig").SliceWithMaxLen;

pub fn NonExhaustive(comptime T: type) type {
const info = switch (@typeInfo(T)) {
.@"enum" => |info| info,
else => |info| @compileError("expected an Enum type but got a(n) " ++ @tagName(info)),
};
std.debug.assert(info.is_exhaustive);
return @Type(std.builtin.Type{ .@"enum" = .{
.tag_type = info.tag_type,
.fields = info.fields,
.decls = &.{},
.is_exhaustive = false,
} });
}

pub fn ArrayPointer(comptime T: type) type {
const err = "ArrayPointer not implemented for " ++ @typeName(T);
return switch (@typeInfo(T)) {
.pointer => |info| {
switch (info.size) {
.one => switch (@typeInfo(info.child)) {
.Array => |array_info| @Type(std.builtin.Type{ .pointer = .{
.size = .Many,
.is_const = true,
.is_volatile = false,
.alignment = @alignOf(array_info.child),
.address_space = info.address_space,
.child = array_info.child,
.is_allowzero = false,
.sentinel = array_info.sentinel,
} }),
else => @compileError(err),
},
.slice => @Type(std.builtin.Type{ .pointer = .{
.size = .many,
.is_const = info.is_const,
.is_volatile = info.is_volatile,
.alignment = info.alignment,
.address_space = info.address_space,
.child = info.child,
.is_allowzero = info.is_allowzero,
.sentinel_ptr = info.sentinel_ptr,
} }),
else => @compileError(err),
}
},
else => @compileError(err),
};
}

const std = @import("std");
107 changes: 107 additions & 0 deletions zigversion/sliceatleast16.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
const std = @import("std");

pub fn Slice(comptime LenType: type, comptime Ptr: type) type {
return struct {
const Self = @This();
const ptr_info = @typeInfo(Ptr).pointer;
pub const NativeSlice = @Pointer(
.slice,
.{
.@"const" = ptr_info.is_const,
.@"volatile" = ptr_info.is_volatile,
.@"align" = ptr_info.alignment,
.@"addrspace" = ptr_info.address_space,
.@"allowzero" = ptr_info.is_allowzero,
},
ptr_info.child,
ptr_info.sentinel(),
);

ptr: Ptr,
len: LenType,

pub const empty: @This() = .{ .ptr = undefined, .len = 0 };

pub fn init(ptr: Ptr, len: LenType) @This() {
return .{ .ptr = ptr, .len = len };
}

pub fn initAssume(slice: NativeSlice) @This() {
return .{ .ptr = slice.ptr, .len = @intCast(slice.len) };
}

pub fn initComptime(comptime ct_slice: NativeSlice) @This() {
return .{ .ptr = ct_slice.ptr, .len = @intCast(ct_slice.len) };
}

pub fn nativeSlice(self: @This()) NativeSlice {
return self.ptr[0..self.len];
}

pub fn lenCast(self: @This(), comptime NewLenType: type) Slice(NewLenType, Ptr) {
return .{ .ptr = self.ptr, .len = @intCast(self.len) };
}

pub const format = switch (@typeInfo(Ptr).pointer.child) {
u8 => (struct {
pub fn format(self: Self, writer: *std.Io.Writer) error{WriteFailed}!void {
try writer.writeAll(self.ptr[0..self.len]);
}
}).format,
else => @compileError("can't format non-u8 slice"),
};
};
}

pub fn SliceWithMaxLen(comptime LenType: type, comptime Ptr: type, comptime max_len_arg: LenType) type {
return struct {
pub const max_len = max_len_arg;
pub const undefined_max_len: @This() = .{ .ptr = undefined, .len = max_len };

const Self = @This();
const ptr_info = @typeInfo(Ptr).pointer;
pub const NativeSlice = @Pointer(
.slice,
.{
.@"const" = ptr_info.is_const,
.@"volatile" = ptr_info.is_volatile,
.@"align" = ptr_info.alignment,
.@"addrspace" = ptr_info.address_space,
.@"allowzero" = ptr_info.is_allowzero,
},
ptr_info.child,
ptr_info.sentinel(),
);

ptr: Ptr,
len: LenType,

pub const empty: @This() = .{ .ptr = undefined, .len = 0 };

pub fn validateMaxLen(self: @This()) void {
std.debug.assert(self.len <= max_len);
}

pub fn nativeSlice(self: @This()) NativeSlice {
return self.ptr[0..self.len];
}

pub fn initComptime(comptime ct_slice: NativeSlice) @This() {
std.debug.assert(ct_slice.len <= max_len);
return .{ .ptr = ct_slice.ptr, .len = @intCast(ct_slice.len) };
}

pub fn lenCast(self: @This(), comptime NewLenType: type) Slice(NewLenType, Ptr) {
return .{ .ptr = self.ptr, .len = @intCast(self.len) };
}

pub const format = switch (@typeInfo(Ptr).pointer.child) {
u8 => (struct {
pub fn format(self: Self, writer: *std.Io.Writer) error{WriteFailed}!void {
try writer.writeAll(self.ptr[0..self.len]);
}
}).format,
else => @compileError("can't format non-u8 slice"),
};
};
}
File renamed without changes.
Loading