aboutsummaryrefslogtreecommitdiff
path: root/system.old/libraries
diff options
context:
space:
mode:
authorBobby <[email protected]>2026-02-24 06:56:58 +0530
committerBobby <[email protected]>2026-02-24 06:56:58 +0530
commit5fe89e6f5b6fd6f5b5589b9e5d4714e0f4fbe5e8 (patch)
tree2ae2a13678844b82b43583ca28eed4d4b6223ec0 /system.old/libraries
parent297c66b480a238dad5ce7f03405fe6f5b9123701 (diff)
downloadakiba-5fe89e6f5b6fd6f5b5589b9e5d4714e0f4fbe5e8.tar.xz
akiba-5fe89e6f5b6fd6f5b5589b9e5d4714e0f4fbe5e8.zip
Bunch of stuff moved as .old for new arch change
Diffstat (limited to 'system.old/libraries')
-rw-r--r--system.old/libraries/build.zig34
-rw-r--r--system.old/libraries/colors/colors.zig12
-rw-r--r--system.old/libraries/colors/colors.zon6
-rw-r--r--system.old/libraries/datetime/datetime.zig13
-rw-r--r--system.old/libraries/datetime/datetime.zon9
-rw-r--r--system.old/libraries/datetime/format.zig111
-rw-r--r--system.old/libraries/datetime/time.zig77
-rw-r--r--system.old/libraries/datetime/types.zig10
-rw-r--r--system.old/libraries/format/bytes.zig47
-rw-r--r--system.old/libraries/format/format.zig29
-rw-r--r--system.old/libraries/format/format.zon10
-rw-r--r--system.old/libraries/format/int.zig25
-rw-r--r--system.old/libraries/format/print.zig94
-rw-r--r--system.old/libraries/format/size.zig33
-rw-r--r--system.old/libraries/format/table.zig101
-rw-r--r--system.old/libraries/io/attachment.zig33
-rw-r--r--system.old/libraries/io/io.zig36
-rw-r--r--system.old/libraries/io/io.zon10
-rw-r--r--system.old/libraries/io/letter.zig36
-rw-r--r--system.old/libraries/io/location.zig30
-rw-r--r--system.old/libraries/io/stream.zig41
-rw-r--r--system.old/libraries/io/types.zig39
-rw-r--r--system.old/libraries/kata/kata.zig50
-rw-r--r--system.old/libraries/kata/kata.zon9
-rw-r--r--system.old/libraries/mem/mem.zig22
-rw-r--r--system.old/libraries/mem/mem.zon6
-rw-r--r--system.old/libraries/os/cpu.zig19
-rw-r--r--system.old/libraries/os/disk.zig25
-rw-r--r--system.old/libraries/os/memory.zig28
-rw-r--r--system.old/libraries/os/os.zig15
-rw-r--r--system.old/libraries/os/os.zon9
-rw-r--r--system.old/libraries/os/types.zig12
-rw-r--r--system.old/libraries/os/uptime.zig15
-rw-r--r--system.old/libraries/params/params.zig233
-rw-r--r--system.old/libraries/params/params.zon6
-rw-r--r--system.old/libraries/string/builder.zig48
-rw-r--r--system.old/libraries/string/cstring.zig17
-rw-r--r--system.old/libraries/string/location.zig59
-rw-r--r--system.old/libraries/string/string.zig16
-rw-r--r--system.old/libraries/string/string.zon6
-rw-r--r--system.old/libraries/sys/start.zig16
-rw-r--r--system.old/libraries/sys/sys.zig63
-rw-r--r--system.old/libraries/sys/sys.zon6
43 files changed, 1516 insertions, 0 deletions
diff --git a/system.old/libraries/build.zig b/system.old/libraries/build.zig
new file mode 100644
index 0000000..50c3071
--- /dev/null
+++ b/system.old/libraries/build.zig
@@ -0,0 +1,34 @@
+const std = @import("std");
+
+pub fn build(b: *std.Build) void {
+ const target = b.resolveTargetQuery(.{
+ .cpu_arch = .x86_64,
+ .os_tag = .freestanding,
+ .abi = .none,
+ });
+
+ var lib_dir = std.fs.cwd().openDir(".", .{ .iterate = true }) catch return;
+ defer lib_dir.close();
+
+ var lib_iter = lib_dir.iterate();
+ while (lib_iter.next() catch null) |entry| {
+ if (entry.kind != .directory) continue;
+
+ const lib_name = b.allocator.dupe(u8, entry.name) catch continue;
+ const lib_file = std.fmt.allocPrint(b.allocator, "{s}/{s}.zig", .{ lib_name, lib_name }) catch continue;
+
+ std.fs.cwd().access(lib_file, .{}) catch continue;
+
+ const lib = b.addLibrary(.{
+ .name = lib_name,
+ .root_module = b.createModule(.{
+ .root_source_file = b.path(lib_file),
+ .target = target,
+ .optimize = .ReleaseSmall,
+ }),
+ });
+
+ lib.linkage = .static;
+ b.installArtifact(lib);
+ }
+}
diff --git a/system.old/libraries/colors/colors.zig b/system.old/libraries/colors/colors.zig
new file mode 100644
index 0000000..1e151da
--- /dev/null
+++ b/system.old/libraries/colors/colors.zig
@@ -0,0 +1,12 @@
+//! Display colors
+
+pub const white: u32 = 0x00FFFFFF;
+pub const black: u32 = 0x00000000;
+pub const red: u32 = 0x00FF4444;
+pub const green: u32 = 0x0088FF88;
+pub const blue: u32 = 0x004488DD;
+pub const yellow: u32 = 0x00DDDD00;
+pub const cyan: u32 = 0x0000FFFF;
+pub const magenta: u32 = 0x00FF00FF;
+pub const gray: u32 = 0x00888888;
+pub const purple: u32 = 0x00BB88FF;
diff --git a/system.old/libraries/colors/colors.zon b/system.old/libraries/colors/colors.zon
new file mode 100644
index 0000000..8a0a157
--- /dev/null
+++ b/system.old/libraries/colors/colors.zon
@@ -0,0 +1,6 @@
+.{
+ .name = "colors",
+ .version = "1.0.0",
+ .type = .library,
+ .entry = "colors.zig",
+}
diff --git a/system.old/libraries/datetime/datetime.zig b/system.old/libraries/datetime/datetime.zig
new file mode 100644
index 0000000..d72d679
--- /dev/null
+++ b/system.old/libraries/datetime/datetime.zig
@@ -0,0 +1,13 @@
+//! Date and time utilities
+
+pub const time = @import("time.zig");
+pub const fmt = @import("format.zig");
+pub const types = @import("types.zig");
+
+pub const now = time.now;
+pub const parts = time.parts;
+
+pub const formatDate = fmt.date;
+pub const formatDuration = fmt.duration;
+
+pub const DateTime = types.DateTime;
diff --git a/system.old/libraries/datetime/datetime.zon b/system.old/libraries/datetime/datetime.zon
new file mode 100644
index 0000000..a55aede
--- /dev/null
+++ b/system.old/libraries/datetime/datetime.zon
@@ -0,0 +1,9 @@
+.{
+ .name = "datetime",
+ .version = "1.0.0",
+ .type = .library,
+ .dependencies = .{
+ .sys,
+ },
+ .entry = "datetime.zig",
+}
diff --git a/system.old/libraries/datetime/format.zig b/system.old/libraries/datetime/format.zig
new file mode 100644
index 0000000..daebd10
--- /dev/null
+++ b/system.old/libraries/datetime/format.zig
@@ -0,0 +1,111 @@
+//! Date/time formatting
+
+const time = @import("time.zig");
+
+const MONTH_NAMES = [_][]const u8{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+pub fn date(timestamp: u64, buf: []u8) []const u8 {
+ if (timestamp == 0) {
+ const default = "01 Jan 1970 00:00";
+ for (default, 0..) |c, i| {
+ buf[i] = c;
+ }
+ return buf[0..default.len];
+ }
+
+ const dt = time.parts(timestamp);
+ var pos: usize = 0;
+
+ // Day
+ if (dt.day < 10) {
+ buf[pos] = '0';
+ pos += 1;
+ }
+ pos += writeInt(dt.day, buf[pos..]);
+
+ buf[pos] = ' ';
+ pos += 1;
+
+ // Month name
+ const month_idx = if (dt.month > 0 and dt.month <= 12) dt.month - 1 else 0;
+ for (MONTH_NAMES[month_idx]) |c| {
+ buf[pos] = c;
+ pos += 1;
+ }
+
+ buf[pos] = ' ';
+ pos += 1;
+
+ // Year
+ pos += writeInt(dt.year, buf[pos..]);
+
+ buf[pos] = ' ';
+ pos += 1;
+
+ // Hour
+ if (dt.hour < 10) {
+ buf[pos] = '0';
+ pos += 1;
+ }
+ pos += writeInt(dt.hour, buf[pos..]);
+
+ buf[pos] = ':';
+ pos += 1;
+
+ // Minute
+ if (dt.minute < 10) {
+ buf[pos] = '0';
+ pos += 1;
+ }
+ pos += writeInt(dt.minute, buf[pos..]);
+
+ return buf[0..pos];
+}
+
+pub fn duration(total_secs: u64, buf: []u8) []const u8 {
+ const hours = total_secs / 3600;
+ const mins = (total_secs % 3600) / 60;
+ const secs = total_secs % 60;
+
+ var pos: usize = 0;
+
+ pos += writeInt(hours, buf[pos..]);
+ buf[pos] = 'h';
+ pos += 1;
+ buf[pos] = ' ';
+ pos += 1;
+
+ pos += writeInt(mins, buf[pos..]);
+ buf[pos] = 'm';
+ pos += 1;
+ buf[pos] = ' ';
+ pos += 1;
+
+ pos += writeInt(secs, buf[pos..]);
+ buf[pos] = 's';
+ pos += 1;
+
+ return buf[0..pos];
+}
+
+fn writeInt(value: u64, buf: []u8) usize {
+ if (value == 0) {
+ buf[0] = '0';
+ return 1;
+ }
+
+ var temp: [20]u8 = undefined;
+ var len: usize = 0;
+ var v = value;
+
+ while (v > 0) : (v /= 10) {
+ temp[len] = @intCast('0' + (v % 10));
+ len += 1;
+ }
+
+ for (0..len) |i| {
+ buf[i] = temp[len - 1 - i];
+ }
+
+ return len;
+}
diff --git a/system.old/libraries/datetime/time.zig b/system.old/libraries/datetime/time.zig
new file mode 100644
index 0000000..9634ace
--- /dev/null
+++ b/system.old/libraries/datetime/time.zig
@@ -0,0 +1,77 @@
+//! Time operations
+
+const sys = @import("sys");
+const types = @import("types.zig");
+
+const ERROR_RESULT: u64 = @bitCast(@as(i64, -1));
+
+const SECONDS_PER_DAY: u64 = 86400;
+const SECONDS_PER_HOUR: u64 = 3600;
+const SECONDS_PER_MINUTE: u64 = 60;
+const DAYS_PER_4_YEARS: u64 = 1461;
+
+const DAYS_NORMAL = [_]u64{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+const DAYS_LEAP = [_]u64{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+pub fn now() ?u64 {
+ const result = sys.syscall(.gettime, .{});
+
+ if (result == ERROR_RESULT) {
+ return null;
+ }
+
+ return result;
+}
+
+pub fn parts(timestamp: u64) types.DateTime {
+ const days_since_epoch = timestamp / SECONDS_PER_DAY;
+ const seconds_today = timestamp % SECONDS_PER_DAY;
+ const hours = seconds_today / SECONDS_PER_HOUR;
+ const minutes = (seconds_today % SECONDS_PER_HOUR) / SECONDS_PER_MINUTE;
+ const seconds = seconds_today % SECONDS_PER_MINUTE;
+
+ var year: u64 = 1970;
+ var remaining_days = days_since_epoch;
+
+ const four_year_cycles = remaining_days / DAYS_PER_4_YEARS;
+ year += four_year_cycles * 4;
+ remaining_days = remaining_days % DAYS_PER_4_YEARS;
+
+ while (remaining_days >= 365) {
+ const is_leap = isLeapYear(year);
+ const days_this_year: u64 = if (is_leap) 366 else 365;
+ if (remaining_days >= days_this_year) {
+ remaining_days -= days_this_year;
+ year += 1;
+ } else {
+ break;
+ }
+ }
+
+ const is_leap = isLeapYear(year);
+ const days_in_months = if (is_leap) DAYS_LEAP else DAYS_NORMAL;
+
+ var month: u8 = 1;
+ var day: u64 = remaining_days + 1;
+
+ for (days_in_months, 0..) |days, m| {
+ if (day <= days) {
+ month = @intCast(m + 1);
+ break;
+ }
+ day -= days;
+ }
+
+ return types.DateTime{
+ .year = year,
+ .month = month,
+ .day = @intCast(day),
+ .hour = @intCast(hours),
+ .minute = @intCast(minutes),
+ .second = @intCast(seconds),
+ };
+}
+
+fn isLeapYear(year: u64) bool {
+ return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0);
+}
diff --git a/system.old/libraries/datetime/types.zig b/system.old/libraries/datetime/types.zig
new file mode 100644
index 0000000..5024e3a
--- /dev/null
+++ b/system.old/libraries/datetime/types.zig
@@ -0,0 +1,10 @@
+//! DateTime types
+
+pub const DateTime = struct {
+ year: u64,
+ month: u8,
+ day: u8,
+ hour: u8,
+ minute: u8,
+ second: u8,
+};
diff --git a/system.old/libraries/format/bytes.zig b/system.old/libraries/format/bytes.zig
new file mode 100644
index 0000000..9d4cb86
--- /dev/null
+++ b/system.old/libraries/format/bytes.zig
@@ -0,0 +1,47 @@
+//! Byte size formatting
+
+const int = @import("int.zig");
+
+pub fn format(bytes: u64, buf: []u8) []const u8 {
+ const kb = bytes / 1024;
+ const mb = kb / 1024;
+
+ if (mb >= 1024) {
+ // Round: add 512 (half of 1024) before dividing
+ const gb_tenths = (mb * 10 + 512) / 1024;
+ const gb_whole = gb_tenths / 10;
+ const gb_frac = gb_tenths % 10;
+
+ var pos: usize = 0;
+ const whole_str = int.toStr(gb_whole, buf[pos..]);
+ pos += whole_str.len;
+ buf[pos] = '.';
+ pos += 1;
+ buf[pos] = '0' + @as(u8, @intCast(gb_frac));
+ pos += 1;
+ buf[pos] = ' ';
+ pos += 1;
+ buf[pos] = 'G';
+ pos += 1;
+ buf[pos] = 'B';
+ pos += 1;
+ return buf[0..pos];
+ } else if (mb > 0) {
+ const num_str = int.toStr(mb, buf);
+ buf[num_str.len] = ' ';
+ buf[num_str.len + 1] = 'M';
+ buf[num_str.len + 2] = 'B';
+ return buf[0 .. num_str.len + 3];
+ } else if (kb > 0) {
+ const num_str = int.toStr(kb, buf);
+ buf[num_str.len] = ' ';
+ buf[num_str.len + 1] = 'K';
+ buf[num_str.len + 2] = 'B';
+ return buf[0 .. num_str.len + 3];
+ } else {
+ const num_str = int.toStr(bytes, buf);
+ buf[num_str.len] = ' ';
+ buf[num_str.len + 1] = 'B';
+ return buf[0 .. num_str.len + 2];
+ }
+}
diff --git a/system.old/libraries/format/format.zig b/system.old/libraries/format/format.zig
new file mode 100644
index 0000000..f9c8068
--- /dev/null
+++ b/system.old/libraries/format/format.zig
@@ -0,0 +1,29 @@
+//! Formatting utilities
+
+pub const int = @import("int.zig");
+pub const size = @import("size.zig");
+pub const bytes = @import("bytes.zig");
+pub const printmod = @import("print.zig");
+pub const tablemod = @import("table.zig");
+
+pub const intToStr = int.toStr;
+pub const formatSize = size.format;
+pub const formatBytes = bytes.format;
+
+pub const print = printmod.print;
+pub const println = printmod.println;
+pub const printf = printmod.printf;
+pub const color = printmod.color;
+pub const colorln = printmod.colorln;
+pub const colorf = printmod.colorf;
+
+pub const Table = tablemod.Table;
+pub const Column = tablemod.Column;
+pub const Alignment = tablemod.Alignment;
+
+/// Print a u64 value as decimal
+pub fn print_u64(num: u64) void {
+ var buf: [20]u8 = undefined;
+ const str = int.toStr(num, &buf);
+ print(str);
+}
diff --git a/system.old/libraries/format/format.zon b/system.old/libraries/format/format.zon
new file mode 100644
index 0000000..1dee015
--- /dev/null
+++ b/system.old/libraries/format/format.zon
@@ -0,0 +1,10 @@
+.{
+ .name = "format",
+ .version = "1.0.0",
+ .type = .library,
+ .dependencies = .{
+ .io,
+ .colors,
+ },
+ .entry = "format.zig",
+}
diff --git a/system.old/libraries/format/int.zig b/system.old/libraries/format/int.zig
new file mode 100644
index 0000000..17cf4c3
--- /dev/null
+++ b/system.old/libraries/format/int.zig
@@ -0,0 +1,25 @@
+//! Integer formatting
+
+pub fn toStr(num: u64, buf: []u8) []u8 {
+ if (num == 0) {
+ buf[0] = '0';
+ return buf[0..1];
+ }
+
+ var n = num;
+ var i: usize = 0;
+
+ while (n > 0) : (i += 1) {
+ buf[i] = @as(u8, @intCast(n % 10)) + '0';
+ n /= 10;
+ }
+
+ var j: usize = 0;
+ while (j < i / 2) : (j += 1) {
+ const tmp = buf[j];
+ buf[j] = buf[i - 1 - j];
+ buf[i - 1 - j] = tmp;
+ }
+
+ return buf[0..i];
+}
diff --git a/system.old/libraries/format/print.zig b/system.old/libraries/format/print.zig
new file mode 100644
index 0000000..473d651
--- /dev/null
+++ b/system.old/libraries/format/print.zig
@@ -0,0 +1,94 @@
+//! Print utilities
+
+const colors = @import("colors");
+const io = @import("io");
+
+pub fn print(text: []const u8) void {
+ _ = io.mark(io.stream, text, colors.white) catch {};
+}
+
+pub fn println(text: []const u8) void {
+ _ = io.mark(io.stream, text, colors.white) catch {};
+ _ = io.mark(io.stream, "\n", colors.white) catch {};
+}
+
+pub fn color(text: []const u8, col: u32) void {
+ _ = io.mark(io.stream, text, col) catch {};
+}
+
+pub fn colorln(text: []const u8, col: u32) void {
+ _ = io.mark(io.stream, text, col) catch {};
+ _ = io.mark(io.stream, "\n", colors.white) catch {};
+}
+
+pub fn printf(comptime fmt: []const u8, args: anytype, buf: []u8) void {
+ const len = formatBuf(fmt, args, buf);
+ _ = io.mark(io.stream, buf[0..len], colors.white) catch {};
+}
+
+pub fn colorf(comptime fmt: []const u8, args: anytype, buf: []u8, col: u32) void {
+ const len = formatBuf(fmt, args, buf);
+ _ = io.mark(io.stream, buf[0..len], col) catch {};
+}
+
+fn formatBuf(comptime fmt: []const u8, args: anytype, buf: []u8) usize {
+ var pos: usize = 0;
+ comptime var arg_idx: usize = 0;
+
+ comptime var i: usize = 0;
+ inline while (i < fmt.len) {
+ if (fmt[i] == '{' and i + 1 < fmt.len and fmt[i + 1] == '}') {
+ const arg = args[arg_idx];
+ const T = @TypeOf(arg);
+
+ if (T == []const u8 or T == []u8) {
+ for (arg) |c| {
+ if (pos >= buf.len) break;
+ buf[pos] = c;
+ pos += 1;
+ }
+ } else if (@typeInfo(T) == .int or @typeInfo(T) == .comptime_int) {
+ pos += writeInt(@intCast(arg), buf[pos..]);
+ }
+
+ arg_idx += 1;
+ i += 2;
+ } else {
+ if (pos < buf.len) {
+ buf[pos] = fmt[i];
+ pos += 1;
+ }
+ i += 1;
+ }
+ }
+
+ return pos;
+}
+
+fn writeInt(num: u64, buf: []u8) usize {
+ if (num == 0) {
+ if (buf.len > 0) {
+ buf[0] = '0';
+ return 1;
+ }
+ return 0;
+ }
+
+ var temp: [20]u8 = undefined;
+ var n = num;
+ var i: usize = 0;
+
+ while (n > 0) : (i += 1) {
+ temp[i] = @as(u8, @intCast(n % 10)) + '0';
+ n /= 10;
+ }
+
+ var written: usize = 0;
+ while (i > 0 and written < buf.len) {
+ i -= 1;
+ buf[written] = temp[i];
+ written += 1;
+ }
+
+ return written;
+}
diff --git a/system.old/libraries/format/size.zig b/system.old/libraries/format/size.zig
new file mode 100644
index 0000000..a38c0c8
--- /dev/null
+++ b/system.old/libraries/format/size.zig
@@ -0,0 +1,33 @@
+//! Size formatting
+
+const int = @import("int.zig");
+
+const KB: u64 = 1024;
+const MB: u64 = 1024 * 1024;
+const GB: u64 = 1024 * 1024 * 1024;
+
+pub fn format(bytes: u64, buf: []u8) []u8 {
+ if (bytes < KB) {
+ const s = int.toStr(bytes, buf);
+ buf[s.len] = 'B';
+ return buf[0 .. s.len + 1];
+ } else if (bytes < MB) {
+ const kb = bytes / KB;
+ const s = int.toStr(kb, buf);
+ buf[s.len] = 'K';
+ buf[s.len + 1] = 'B';
+ return buf[0 .. s.len + 2];
+ } else if (bytes < GB) {
+ const mb = bytes / MB;
+ const s = int.toStr(mb, buf);
+ buf[s.len] = 'M';
+ buf[s.len + 1] = 'B';
+ return buf[0 .. s.len + 2];
+ } else {
+ const gb = bytes / GB;
+ const s = int.toStr(gb, buf);
+ buf[s.len] = 'G';
+ buf[s.len + 1] = 'B';
+ return buf[0 .. s.len + 2];
+ }
+}
diff --git a/system.old/libraries/format/table.zig b/system.old/libraries/format/table.zig
new file mode 100644
index 0000000..e26be32
--- /dev/null
+++ b/system.old/libraries/format/table.zig
@@ -0,0 +1,101 @@
+//! Table formatting
+
+const io = @import("io");
+const colors = @import("colors");
+
+pub const Alignment = enum {
+ left,
+ right,
+};
+
+pub const Column = struct {
+ name: []const u8,
+ color: u32 = colors.white,
+ alignment: Alignment = .left,
+};
+
+const MAX_COLUMNS = 8;
+const MAX_ROWS = 256;
+
+pub const Table = struct {
+ columns: []const Column,
+ col_widths: [MAX_COLUMNS]usize,
+ rows: [MAX_ROWS][MAX_COLUMNS][]const u8,
+ row_colors: [MAX_ROWS][MAX_COLUMNS]u32,
+ row_count: usize,
+
+ pub fn init(cols: []const Column) Table {
+ var t = Table{
+ .columns = cols,
+ .col_widths = [_]usize{0} ** MAX_COLUMNS,
+ .rows = undefined,
+ .row_colors = undefined,
+ .row_count = 0,
+ };
+
+ for (cols, 0..) |col, i| {
+ t.col_widths[i] = col.name.len;
+ }
+
+ return t;
+ }
+
+ pub fn row(self: *Table, cells: []const []const u8) void {
+ self.rowColored(cells, null);
+ }
+
+ pub fn rowColored(self: *Table, cells: []const []const u8, cell_colors: ?[]const u32) void {
+ if (self.row_count >= MAX_ROWS) return;
+
+ for (cells, 0..) |cell, i| {
+ if (i >= self.columns.len) break;
+ self.rows[self.row_count][i] = cell;
+
+ if (cell_colors) |cc| {
+ self.row_colors[self.row_count][i] = cc[i];
+ } else {
+ self.row_colors[self.row_count][i] = self.columns[i].color;
+ }
+
+ if (cell.len > self.col_widths[i]) {
+ self.col_widths[i] = cell.len;
+ }
+ }
+
+ self.row_count += 1;
+ }
+
+ pub fn print(self: *Table) void {
+ for (self.columns, 0..) |col, i| {
+ _ = io.mark(io.stream, col.name, colors.white) catch {};
+ self.printPadding(self.col_widths[i] - col.name.len + 2);
+ }
+ _ = io.mark(io.stream, "\n", colors.white) catch {};
+
+ for (0..self.row_count) |r| {
+ for (0..self.columns.len) |c| {
+ const cell = self.rows[r][c];
+ const col = self.columns[c];
+ const color = self.row_colors[r][c];
+
+ if (col.alignment == .right) {
+ self.printPadding(self.col_widths[c] - cell.len);
+ _ = io.mark(io.stream, cell, color) catch {};
+ self.printPadding(2);
+ } else {
+ _ = io.mark(io.stream, cell, color) catch {};
+ self.printPadding(self.col_widths[c] - cell.len + 2);
+ }
+ }
+ _ = io.mark(io.stream, "\n", colors.white) catch {};
+ }
+ }
+
+ fn printPadding(self: *Table, count: usize) void {
+ _ = self;
+ var i: usize = 0;
+ while (i < count) : (i += 1) {
+ _ = io.mark(io.stream, " ", colors.white) catch {};
+ }
+ }
+};
diff --git a/system.old/libraries/io/attachment.zig b/system.old/libraries/io/attachment.zig
new file mode 100644
index 0000000..4672fec
--- /dev/null
+++ b/system.old/libraries/io/attachment.zig
@@ -0,0 +1,33 @@
+//! Attachment operations
+
+const sys = @import("sys");
+const types = @import("types.zig");
+
+const ERROR_RESULT: u64 = @bitCast(@as(i64, -1));
+
+pub fn attach(location: []const u8, flags: u32) types.Error!types.Descriptor {
+ const result = sys.syscall(.attach, .{ @intFromPtr(location.ptr), flags });
+ if (result == ERROR_RESULT) {
+ return types.Error.NotFound;
+ }
+ return @truncate(result);
+}
+
+pub fn seal(fd: types.Descriptor) void {
+ _ = sys.syscall(.seal, .{fd});
+}
+
+pub fn viewstack(location: []const u8, entries: []types.StackEntry) types.Error!usize {
+ const result = sys.syscall(.viewstack, .{
+ @intFromPtr(location.ptr),
+ location.len,
+ @intFromPtr(entries.ptr),
+ entries.len,
+ });
+
+ if (result == ERROR_RESULT) {
+ return types.Error.InvalidLocation;
+ }
+
+ return @intCast(result);
+}
diff --git a/system.old/libraries/io/io.zig b/system.old/libraries/io/io.zig
new file mode 100644
index 0000000..f7c0da3
--- /dev/null
+++ b/system.old/libraries/io/io.zig
@@ -0,0 +1,36 @@
+//! I/O operations
+
+pub const attachment = @import("attachment.zig");
+pub const stream_ops = @import("stream.zig");
+pub const location = @import("location.zig");
+pub const letter = @import("letter.zig");
+pub const types = @import("types.zig");
+
+pub const attach = attachment.attach;
+pub const seal = attachment.seal;
+pub const viewstack = attachment.viewstack;
+
+pub const view = stream_ops.view;
+pub const mark = stream_ops.mark;
+pub const getchar = stream_ops.getchar;
+pub const wipe = stream_ops.wipe;
+
+pub const getlocation = location.get;
+pub const setlocation = location.set;
+
+pub const sendLetter = letter.send;
+pub const readLetter = letter.read;
+
+pub const StackEntry = types.StackEntry;
+pub const Descriptor = types.Descriptor;
+pub const Letter = types.Letter;
+pub const Error = types.Error;
+
+pub const source = types.source;
+pub const stream = types.stream;
+pub const trace = types.trace;
+
+pub const VIEW_ONLY = types.VIEW_ONLY;
+pub const MARK_ONLY = types.MARK_ONLY;
+pub const BOTH = types.BOTH;
+pub const CREATE = types.CREATE;
diff --git a/system.old/libraries/io/io.zon b/system.old/libraries/io/io.zon
new file mode 100644
index 0000000..c6a1bc4
--- /dev/null
+++ b/system.old/libraries/io/io.zon
@@ -0,0 +1,10 @@
+.{
+ .name = "io",
+ .version = "1.0.0",
+ .type = .library,
+ .dependencies = .{
+ .sys,
+ .kata,
+ },
+ .entry = "io.zig",
+}
diff --git a/system.old/libraries/io/letter.zig b/system.old/libraries/io/letter.zig
new file mode 100644
index 0000000..3cde330
--- /dev/null
+++ b/system.old/libraries/io/letter.zig
@@ -0,0 +1,36 @@
+//! Letter (postman) operations
+
+const sys = @import("sys");
+const types = @import("types.zig");
+
+const ERROR_RESULT: u64 = @bitCast(@as(i64, -1));
+
+const MODE_SEND: u64 = 0;
+const MODE_READ: u64 = 1;
+
+pub fn send(letter_type: u8, data: []const u8) types.Error!void {
+ const result = sys.syscall(.postman, .{
+ MODE_SEND,
+ @as(u64, letter_type),
+ @intFromPtr(data.ptr),
+ data.len,
+ });
+
+ if (result == ERROR_RESULT) {
+ return types.Error.SendFailed;
+ }
+}
+
+pub fn read(buffer: []u8) types.Error!u8 {
+ const result = sys.syscall(.postman, .{
+ MODE_READ,
+ @intFromPtr(buffer.ptr),
+ buffer.len,
+ });
+
+ if (result == ERROR_RESULT) {
+ return types.Error.ReadFailed;
+ }
+
+ return @intCast(result);
+}
diff --git a/system.old/libraries/io/location.zig b/system.old/libraries/io/location.zig
new file mode 100644
index 0000000..0f1e114
--- /dev/null
+++ b/system.old/libraries/io/location.zig
@@ -0,0 +1,30 @@
+//! Location operations
+
+const sys = @import("sys");
+const types = @import("types.zig");
+
+const ERROR_RESULT: u64 = @bitCast(@as(i64, -1));
+
+pub fn get(buffer: []u8) types.Error![]u8 {
+ const result = sys.syscall(.getlocation, .{
+ @intFromPtr(buffer.ptr),
+ buffer.len,
+ });
+
+ if (result == ERROR_RESULT) {
+ return types.Error.GetLocationFailed;
+ }
+
+ return buffer[0..@intCast(result)];
+}
+
+pub fn set(location: []const u8) types.Error!void {
+ const result = sys.syscall(.setlocation, .{
+ @intFromPtr(location.ptr),
+ location.len,
+ });
+
+ if (result == ERROR_RESULT) {
+ return types.Error.InvalidLocation;
+ }
+}
diff --git a/system.old/libraries/io/stream.zig b/system.old/libraries/io/stream.zig
new file mode 100644
index 0000000..8e65473
--- /dev/null
+++ b/system.old/libraries/io/stream.zig
@@ -0,0 +1,41 @@
+//! Stream operations
+
+const kata = @import("kata");
+const sys = @import("sys");
+const types = @import("types.zig");
+
+const ERROR_RESULT: u64 = @bitCast(@as(i64, -1));
+const EAGAIN_RESULT: u64 = @bitCast(@as(i64, -2));
+
+pub fn view(fd: types.Descriptor, buffer: []u8) types.Error!usize {
+ const result = sys.syscall(.view, .{ fd, @intFromPtr(buffer.ptr), buffer.len });
+ if (result == ERROR_RESULT) {
+ return types.Error.ReadFailed;
+ }
+ return result;
+}
+
+pub fn mark(fd: types.Descriptor, data: []const u8, color: u32) types.Error!usize {
+ const result = sys.syscall(.mark, .{ fd, @intFromPtr(data.ptr), data.len, color });
+ if (result == ERROR_RESULT) {
+ return types.Error.WriteFailed;
+ }
+ return result;
+}
+
+pub fn getchar() types.Error!u8 {
+ while (true) {
+ const result = sys.syscall(.getkeychar, .{});
+ if (result != EAGAIN_RESULT) {
+ if (result != ERROR_RESULT) {
+ return @truncate(result);
+ }
+ return types.Error.ReadFailed;
+ }
+ kata.yield();
+ }
+}
+
+pub fn wipe() void {
+ _ = sys.syscall(.wipe, .{});
+}
diff --git a/system.old/libraries/io/types.zig b/system.old/libraries/io/types.zig
new file mode 100644
index 0000000..1b4336b
--- /dev/null
+++ b/system.old/libraries/io/types.zig
@@ -0,0 +1,39 @@
+//! I/O types and constants
+
+pub const Error = error{
+ NotFound,
+ PermissionDenied,
+ InvalidDescriptor,
+ ReadFailed,
+ WriteFailed,
+ InvalidLocation,
+ SendFailed,
+ GetLocationFailed,
+};
+
+pub const Descriptor = u32;
+
+pub const source: Descriptor = 0;
+pub const stream: Descriptor = 1;
+pub const trace: Descriptor = 2;
+
+pub const VIEW_ONLY: u32 = 0x01;
+pub const MARK_ONLY: u32 = 0x02;
+pub const BOTH: u32 = 0x03;
+pub const CREATE: u32 = 0x0100;
+
+pub const StackEntry = extern struct {
+ identity: [64]u8,
+ identity_len: u8,
+ is_stack: bool,
+ owner_name_len: u8,
+ permission_type: u8,
+ size: u32,
+ modified_time: u64,
+ owner_name: [64]u8,
+};
+
+pub const Letter = struct {
+ pub const NONE: u8 = 0;
+ pub const NAVIGATE: u8 = 1;
+};
diff --git a/system.old/libraries/kata/kata.zig b/system.old/libraries/kata/kata.zig
new file mode 100644
index 0000000..1144294
--- /dev/null
+++ b/system.old/libraries/kata/kata.zig
@@ -0,0 +1,50 @@
+//! Kata (process) control
+
+const sys = @import("sys");
+
+const ERROR_RESULT: u64 = @bitCast(@as(i64, -1));
+
+pub const Error = error{
+ SpawnFailed,
+ WaitFailed,
+};
+
+pub fn yield() void {
+ _ = sys.syscall(.yield, .{});
+}
+
+pub fn exit(code: u64) noreturn {
+ _ = sys.syscall(.exit, .{code});
+ unreachable;
+}
+
+pub fn spawn(location: []const u8) Error!u32 {
+ const result = sys.syscall(.spawn, .{ @intFromPtr(location.ptr), location.len, @as(u64, 0), @as(u64, 0) });
+ if (result == ERROR_RESULT) {
+ return Error.SpawnFailed;
+ }
+ return @truncate(result);
+}
+
+pub fn spawnWithParams(location: []const u8, params: [][*:0]const u8) Error!u32 {
+ const result = sys.syscall(.spawn, .{ @intFromPtr(location.ptr), location.len, @intFromPtr(params.ptr), params.len });
+ if (result == ERROR_RESULT) {
+ return Error.SpawnFailed;
+ }
+ return @truncate(result);
+}
+
+pub fn wait(pid: u32) Error!u64 {
+ while (true) {
+ const result = sys.syscall(.wait, .{pid});
+ if (result != ERROR_RESULT) {
+ return result;
+ }
+ yield();
+ }
+}
+
+/// Reap zombie katas - returns number of zombies reaped
+pub fn reap() u64 {
+ return sys.syscall(.reap, .{});
+}
diff --git a/system.old/libraries/kata/kata.zon b/system.old/libraries/kata/kata.zon
new file mode 100644
index 0000000..51cae1d
--- /dev/null
+++ b/system.old/libraries/kata/kata.zon
@@ -0,0 +1,9 @@
+.{
+ .name = "kata",
+ .version = "1.0.0",
+ .type = .library,
+ .dependencies = .{
+ .sys,
+ },
+ .entry = "kata.zig",
+}
diff --git a/system.old/libraries/mem/mem.zig b/system.old/libraries/mem/mem.zig
new file mode 100644
index 0000000..b513567
--- /dev/null
+++ b/system.old/libraries/mem/mem.zig
@@ -0,0 +1,22 @@
+//! Memory utilities
+
+pub fn copy(dest: []u8, src: []const u8) void {
+ const len = @min(dest.len, src.len);
+ for (0..len) |i| {
+ dest[i] = src[i];
+ }
+}
+
+pub fn zero(buf: []u8) void {
+ for (buf) |*b| {
+ b.* = 0;
+ }
+}
+
+pub fn equals(a: []const u8, b: []const u8) bool {
+ if (a.len != b.len) return false;
+ for (a, b) |ac, bc| {
+ if (ac != bc) return false;
+ }
+ return true;
+}
diff --git a/system.old/libraries/mem/mem.zon b/system.old/libraries/mem/mem.zon
new file mode 100644
index 0000000..18e964f
--- /dev/null
+++ b/system.old/libraries/mem/mem.zon
@@ -0,0 +1,6 @@
+.{
+ .name = "mem",
+ .version = "1.0.0",
+ .type = .library,
+ .entry = "mem.zig",
+}
diff --git a/system.old/libraries/os/cpu.zig b/system.old/libraries/os/cpu.zig
new file mode 100644
index 0000000..1f3ea53
--- /dev/null
+++ b/system.old/libraries/os/cpu.zig
@@ -0,0 +1,19 @@
+//! CPU information
+
+const sys = @import("sys");
+const types = @import("types.zig");
+
+const ERROR_RESULT: u64 = @bitCast(@as(i64, -1));
+
+pub fn info(buffer: []u8) ?[]const u8 {
+ const result = sys.syscall(.cpuinfo, .{
+ @intFromPtr(buffer.ptr),
+ buffer.len,
+ });
+
+ if (result == ERROR_RESULT or result == 0) {
+ return null;
+ }
+
+ return buffer[0..@intCast(result)];
+}
diff --git a/system.old/libraries/os/disk.zig b/system.old/libraries/os/disk.zig
new file mode 100644
index 0000000..9a43c26
--- /dev/null
+++ b/system.old/libraries/os/disk.zig
@@ -0,0 +1,25 @@
+//! Disk information
+
+const sys = @import("sys");
+const types = @import("types.zig");
+
+const ERROR_RESULT: u64 = @bitCast(@as(i64, -1));
+
+pub fn info() ?types.DiskInfo {
+ var total: u64 = 0;
+ var used: u64 = 0;
+
+ const result = sys.syscall(.diskinfo, .{
+ @intFromPtr(&total),
+ @intFromPtr(&used),
+ });
+
+ if (result == ERROR_RESULT) {
+ return null;
+ }
+
+ return types.DiskInfo{
+ .total = total,
+ .used = used,
+ };
+}
diff --git a/system.old/libraries/os/memory.zig b/system.old/libraries/os/memory.zig
new file mode 100644
index 0000000..86c2a08
--- /dev/null
+++ b/system.old/libraries/os/memory.zig
@@ -0,0 +1,28 @@
+//! Memory information
+
+const sys = @import("sys");
+const types = @import("types.zig");
+
+const ERROR_RESULT: u64 = @bitCast(@as(i64, -1));
+
+pub fn info() ?types.MemInfo {
+ var total: u64 = 0;
+ var used: u64 = 0;
+ var free: u64 = 0;
+
+ const result = sys.syscall(.meminfo, .{
+ @intFromPtr(&total),
+ @intFromPtr(&used),
+ @intFromPtr(&free),
+ });
+
+ if (result == ERROR_RESULT) {
+ return null;
+ }
+
+ return types.MemInfo{
+ .total = total,
+ .used = used,
+ .free = free,
+ };
+}
diff --git a/system.old/libraries/os/os.zig b/system.old/libraries/os/os.zig
new file mode 100644
index 0000000..18b8730
--- /dev/null
+++ b/system.old/libraries/os/os.zig
@@ -0,0 +1,15 @@
+//! OS information utilities
+
+pub const cpu = @import("cpu.zig");
+pub const disk = @import("disk.zig");
+pub const mem = @import("memory.zig");
+pub const up = @import("uptime.zig");
+pub const types = @import("types.zig");
+
+pub const cpuinfo = cpu.info;
+pub const meminfo = mem.info;
+pub const diskinfo = disk.info;
+pub const uptime = up.get;
+
+pub const MemInfo = types.MemInfo;
+pub const DiskInfo = types.DiskInfo;
diff --git a/system.old/libraries/os/os.zon b/system.old/libraries/os/os.zon
new file mode 100644
index 0000000..e1bc062
--- /dev/null
+++ b/system.old/libraries/os/os.zon
@@ -0,0 +1,9 @@
+.{
+ .name = "os",
+ .version = "1.0.0",
+ .type = .library,
+ .dependencies = .{
+ .sys,
+ },
+ .entry = "os.zig",
+}
diff --git a/system.old/libraries/os/types.zig b/system.old/libraries/os/types.zig
new file mode 100644
index 0000000..1b06af9
--- /dev/null
+++ b/system.old/libraries/os/types.zig
@@ -0,0 +1,12 @@
+//! OS types
+
+pub const MemInfo = struct {
+ total: u64,
+ used: u64,
+ free: u64,
+};
+
+pub const DiskInfo = struct {
+ total: u64,
+ used: u64,
+};
diff --git a/system.old/libraries/os/uptime.zig b/system.old/libraries/os/uptime.zig
new file mode 100644
index 0000000..0f499ff
--- /dev/null
+++ b/system.old/libraries/os/uptime.zig
@@ -0,0 +1,15 @@
+//! Uptime information
+
+const sys = @import("sys");
+
+const ERROR_RESULT: u64 = @bitCast(@as(i64, -1));
+
+pub fn get() ?u64 {
+ const result = sys.syscall(.uptime, .{});
+
+ if (result == ERROR_RESULT) {
+ return null;
+ }
+
+ return result;
+}
diff --git a/system.old/libraries/params/params.zig b/system.old/libraries/params/params.zig
new file mode 100644
index 0000000..d7e5ba1
--- /dev/null
+++ b/system.old/libraries/params/params.zig
@@ -0,0 +1,233 @@
+//! Akiba parameter parsing
+
+pub const Value = union(enum) {
+ scalar: []const u8,
+ list: []const []const u8,
+};
+
+pub const Named = struct {
+ key: []const u8,
+ value: Value,
+};
+
+pub const Params = struct {
+ positionals: []const Value,
+ named: []const Named,
+
+ pub fn positional(self: Params, index: usize) ?Value {
+ if (index >= self.positionals.len) return null;
+ return self.positionals[index];
+ }
+
+ pub fn get(self: Params, key: []const u8) ?Value {
+ for (self.named) |n| {
+ if (eql(n.key, key)) return n.value;
+ }
+ return null;
+ }
+
+ pub fn getString(self: Params, key: []const u8) ?[]const u8 {
+ const val = self.get(key) orelse return null;
+ return switch (val) {
+ .scalar => |s| s,
+ .list => null,
+ };
+ }
+
+ pub fn getList(self: Params, key: []const u8) ?[]const []const u8 {
+ const val = self.get(key) orelse return null;
+ return switch (val) {
+ .scalar => null,
+ .list => |l| l,
+ };
+ }
+
+ pub fn getBool(self: Params, key: []const u8) ?bool {
+ const val = self.getString(key) orelse return null;
+ if (eql(val, "true")) return true;
+ if (eql(val, "false")) return false;
+ return null;
+ }
+
+ pub fn getInt(self: Params, key: []const u8) ?i64 {
+ const val = self.getString(key) orelse return null;
+ return parseInt(val);
+ }
+};
+
+pub const Error = error{
+ EmptyToken,
+ EmptyKey,
+ EmptyValue,
+ InvalidKey,
+ DuplicateKey,
+ PositionalAfterNamed,
+ LeadingComma,
+ TrailingComma,
+};
+
+const MAX_POSITIONALS = 16;
+const MAX_NAMED = 32;
+const MAX_LIST_ITEMS = 16;
+
+var positional_storage: [MAX_POSITIONALS]Value = undefined;
+var named_storage: [MAX_NAMED]Named = undefined;
+var list_storage: [MAX_POSITIONALS + MAX_NAMED][MAX_LIST_ITEMS][]const u8 = undefined;
+var list_index: usize = 0;
+
+pub fn parse(pc: u32, pv: [*]const [*:0]const u8) Error!Params {
+ var positional_count: usize = 0;
+ var named_count: usize = 0;
+ var in_named = false;
+ list_index = 0;
+
+ // Skip program name (pv[0])
+ var i: u32 = 1;
+ while (i < pc) : (i += 1) {
+ const arg = sliceFromCstr(pv[i]);
+
+ if (arg.len == 0) return Error.EmptyToken;
+
+ const eq_pos = indexOf(arg, '=');
+
+ if (eq_pos) |pos| {
+ // Named parameter
+ in_named = true;
+
+ if (pos == 0) return Error.EmptyKey;
+ if (pos == arg.len - 1) return Error.EmptyValue;
+
+ const key = arg[0..pos];
+ const value_str = arg[pos + 1 ..];
+
+ if (!isValidKey(key)) return Error.InvalidKey;
+ if (hasDuplicateKey(named_storage[0..named_count], key)) return Error.DuplicateKey;
+
+ const value = try parseValue(value_str);
+ named_storage[named_count] = .{ .key = key, .value = value };
+ named_count += 1;
+ } else {
+ // Positional
+ if (in_named) return Error.PositionalAfterNamed;
+
+ const value = try parseValue(arg);
+ positional_storage[positional_count] = value;
+ positional_count += 1;
+ }
+ }
+
+ return Params{
+ .positionals = positional_storage[0..positional_count],
+ .named = named_storage[0..named_count],
+ };
+}
+
+fn parseValue(str: []const u8) Error!Value {
+ if (str.len == 0) return Error.EmptyValue;
+ if (str[0] == ',') return Error.LeadingComma;
+ if (str[str.len - 1] == ',') return Error.TrailingComma;
+
+ // Check for commas
+ var comma_count: usize = 0;
+ for (str) |c| {
+ if (c == ',') comma_count += 1;
+ }
+
+ if (comma_count == 0) {
+ return Value{ .scalar = str };
+ }
+
+ // Parse list
+ var items: [][]const u8 = list_storage[list_index][0..];
+ var item_count: usize = 0;
+ var start: usize = 0;
+
+ for (str, 0..) |c, j| {
+ if (c == ',') {
+ if (j == start) return Error.LeadingComma; // Empty segment
+ items[item_count] = str[start..j];
+ item_count += 1;
+ start = j + 1;
+ }
+ }
+
+ // Last item
+ if (start == str.len) return Error.TrailingComma;
+ items[item_count] = str[start..];
+ item_count += 1;
+
+ list_index += 1;
+
+ return Value{ .list = items[0..item_count] };
+}
+
+fn isValidKey(key: []const u8) bool {
+ if (key.len == 0) return false;
+
+ const first = key[0];
+ if (!isLetter(first)) return false;
+
+ for (key[1..]) |c| {
+ if (!isLetter(c) and !isDigit(c) and c != '_') return false;
+ }
+
+ return true;
+}
+
+fn isLetter(c: u8) bool {
+ return (c >= 'a' and c <= 'z') or (c >= 'A' and c <= 'Z');
+}
+
+fn isDigit(c: u8) bool {
+ return c >= '0' and c <= '9';
+}
+
+fn hasDuplicateKey(named: []const Named, key: []const u8) bool {
+ for (named) |n| {
+ if (eql(n.key, key)) return true;
+ }
+ return false;
+}
+
+fn indexOf(str: []const u8, char: u8) ?usize {
+ for (str, 0..) |c, i| {
+ if (c == char) return i;
+ }
+ return null;
+}
+
+fn eql(a: []const u8, b: []const u8) bool {
+ if (a.len != b.len) return false;
+ for (a, b) |ac, bc| {
+ if (ac != bc) return false;
+ }
+ return true;
+}
+
+fn sliceFromCstr(cstr: [*:0]const u8) []const u8 {
+ var len: usize = 0;
+ while (cstr[len] != 0) : (len += 1) {}
+ return cstr[0..len];
+}
+
+fn parseInt(str: []const u8) ?i64 {
+ if (str.len == 0) return null;
+
+ var negative = false;
+ var start: usize = 0;
+
+ if (str[0] == '-') {
+ negative = true;
+ start = 1;
+ }
+
+ if (start >= str.len) return null;
+
+ var result: i64 = 0;
+ for (str[start..]) |c| {
+ if (!isDigit(c)) return null;
+ result = result * 10 + @as(i64, c - '0');
+ }
+
+ return if (negative) -result else result;
+}
diff --git a/system.old/libraries/params/params.zon b/system.old/libraries/params/params.zon
new file mode 100644
index 0000000..b629ab3
--- /dev/null
+++ b/system.old/libraries/params/params.zon
@@ -0,0 +1,6 @@
+.{
+ .name = "params",
+ .version = "1.0.0",
+ .type = .library,
+ .entry = "params.zig",
+}
diff --git a/system.old/libraries/string/builder.zig b/system.old/libraries/string/builder.zig
new file mode 100644
index 0000000..16bd35c
--- /dev/null
+++ b/system.old/libraries/string/builder.zig
@@ -0,0 +1,48 @@
+//! String building
+
+pub fn build(buf: []u8, parts: anytype) []const u8 {
+ var pos: usize = 0;
+ inline for (parts) |part| {
+ for (part) |c| {
+ if (pos >= buf.len) break;
+ buf[pos] = c;
+ pos += 1;
+ }
+ }
+ return buf[0..pos];
+}
+
+pub fn concat(buf: []u8, a: []const u8, b: []const u8) []const u8 {
+ var pos: usize = 0;
+ for (a) |c| {
+ if (pos >= buf.len) break;
+ buf[pos] = c;
+ pos += 1;
+ }
+ for (b) |c| {
+ if (pos >= buf.len) break;
+ buf[pos] = c;
+ pos += 1;
+ }
+ return buf[0..pos];
+}
+
+pub fn concat3(buf: []u8, a: []const u8, b: []const u8, c: []const u8) []const u8 {
+ var pos: usize = 0;
+ for (a) |ch| {
+ if (pos >= buf.len) break;
+ buf[pos] = ch;
+ pos += 1;
+ }
+ for (b) |ch| {
+ if (pos >= buf.len) break;
+ buf[pos] = ch;
+ pos += 1;
+ }
+ for (c) |ch| {
+ if (pos >= buf.len) break;
+ buf[pos] = ch;
+ pos += 1;
+ }
+ return buf[0..pos];
+}
diff --git a/system.old/libraries/string/cstring.zig b/system.old/libraries/string/cstring.zig
new file mode 100644
index 0000000..32ad60f
--- /dev/null
+++ b/system.old/libraries/string/cstring.zig
@@ -0,0 +1,17 @@
+//! C-string utilities
+
+pub fn len(str: [*:0]const u8) usize {
+ var i: usize = 0;
+ while (str[i] != 0) : (i += 1) {}
+ return i;
+}
+
+pub fn toSlice(str: [*:0]const u8) []const u8 {
+ return str[0..len(str)];
+}
+
+pub fn findNull(buf: []const u8) usize {
+ var i: usize = 0;
+ while (i < buf.len and buf[i] != 0) : (i += 1) {}
+ return i;
+}
diff --git a/system.old/libraries/string/location.zig b/system.old/libraries/string/location.zig
new file mode 100644
index 0000000..ff1c915
--- /dev/null
+++ b/system.old/libraries/string/location.zig
@@ -0,0 +1,59 @@
+//! Location utilities
+
+pub fn getStackName(location: []const u8) []const u8 {
+ if (location.len == 0 or (location.len == 1 and location[0] == '/')) {
+ return "/";
+ }
+
+ var last_slash: usize = 0;
+ for (location, 0..) |c, i| {
+ if (c == '/') {
+ last_slash = i;
+ }
+ }
+
+ if (last_slash == location.len - 1 and location.len > 1) {
+ var i: usize = location.len - 2;
+ while (i > 0) : (i -= 1) {
+ if (location[i] == '/') {
+ return location[i + 1 .. location.len - 1];
+ }
+ }
+ return location[1 .. location.len - 1];
+ }
+
+ if (last_slash + 1 < location.len) {
+ return location[last_slash + 1 ..];
+ }
+
+ return location;
+}
+
+pub fn parent(location: []const u8, buf: []u8) []const u8 {
+ if (location.len <= 1) {
+ buf[0] = '/';
+ return buf[0..1];
+ }
+
+ var end = location.len;
+ if (location[end - 1] == '/') {
+ end -= 1;
+ }
+
+ var i: usize = end;
+ while (i > 0) : (i -= 1) {
+ if (location[i - 1] == '/') {
+ if (i == 1) {
+ buf[0] = '/';
+ return buf[0..1];
+ }
+ for (location[0 .. i - 1], 0..) |c, j| {
+ buf[j] = c;
+ }
+ return buf[0 .. i - 1];
+ }
+ }
+
+ buf[0] = '/';
+ return buf[0..1];
+}
diff --git a/system.old/libraries/string/string.zig b/system.old/libraries/string/string.zig
new file mode 100644
index 0000000..1d7c798
--- /dev/null
+++ b/system.old/libraries/string/string.zig
@@ -0,0 +1,16 @@
+//! String utilities
+
+pub const cstring = @import("cstring.zig");
+pub const location = @import("location.zig");
+pub const builder = @import("builder.zig");
+
+pub const len = cstring.len;
+pub const toSlice = cstring.toSlice;
+pub const findNull = cstring.findNull;
+
+pub const getStackName = location.getStackName;
+pub const parent = location.parent;
+
+pub const build = builder.build;
+pub const concat = builder.concat;
+pub const concat3 = builder.concat3;
diff --git a/system.old/libraries/string/string.zon b/system.old/libraries/string/string.zon
new file mode 100644
index 0000000..e722bf8
--- /dev/null
+++ b/system.old/libraries/string/string.zon
@@ -0,0 +1,6 @@
+.{
+ .name = "string",
+ .version = "1.0.0",
+ .type = .library,
+ .entry = "string.zig",
+}
diff --git a/system.old/libraries/sys/start.zig b/system.old/libraries/sys/start.zig
new file mode 100644
index 0000000..a65eec8
--- /dev/null
+++ b/system.old/libraries/sys/start.zig
@@ -0,0 +1,16 @@
+//! Entry point
+
+extern fn main(pc: u32, pv: [*]const [*:0]const u8) u8;
+
+export fn _start() callconv(.naked) noreturn {
+ asm volatile (
+ \\mov (%%rsp), %%edi
+ \\mov 8(%%rsp), %%rsi
+ \\and $-16, %%rsp
+ \\call main
+ \\movzbl %%al, %%edi
+ \\mov $0x01, %%eax
+ \\syscall
+ \\ud2
+ );
+}
diff --git a/system.old/libraries/sys/sys.zig b/system.old/libraries/sys/sys.zig
new file mode 100644
index 0000000..56186f1
--- /dev/null
+++ b/system.old/libraries/sys/sys.zig
@@ -0,0 +1,63 @@
+//! System runtime
+
+pub const start = @import("start.zig");
+
+comptime {
+ _ = start;
+}
+
+pub const Invocation = enum(u64) {
+ exit = 0x01,
+ attach = 0x02,
+ seal = 0x03,
+ view = 0x04,
+ mark = 0x05,
+ spawn = 0x06,
+ wait = 0x07,
+ yield = 0x08,
+ getkeychar = 0x09,
+ viewstack = 0x0A,
+ getlocation = 0x0B,
+ setlocation = 0x0C,
+ postman = 0x0D,
+ wipe = 0x0E,
+ cpuinfo = 0x0F,
+ meminfo = 0x10,
+ uptime = 0x11,
+ gettime = 0x12,
+ diskinfo = 0x13,
+ reap = 0x14,
+};
+
+pub inline fn syscall(invocation: Invocation, args: anytype) u64 {
+ const Args = @TypeOf(args);
+ const fields = @typeInfo(Args).@"struct".fields;
+
+ const arg0: u64 = if (fields.len > 0) toU64(args[0]) else 0;
+ const arg1: u64 = if (fields.len > 1) toU64(args[1]) else 0;
+ const arg2: u64 = if (fields.len > 2) toU64(args[2]) else 0;
+ const arg3: u64 = if (fields.len > 3) toU64(args[3]) else 0;
+ const arg4: u64 = if (fields.len > 4) toU64(args[4]) else 0;
+ const arg5: u64 = if (fields.len > 5) toU64(args[5]) else 0;
+
+ return asm volatile ("syscall"
+ : [ret] "={rax}" (-> u64),
+ : [number] "{rax}" (@intFromEnum(invocation)),
+ [arg0] "{rdi}" (arg0),
+ [arg1] "{rsi}" (arg1),
+ [arg2] "{rdx}" (arg2),
+ [arg3] "{r10}" (arg3),
+ [arg4] "{r8}" (arg4),
+ [arg5] "{r9}" (arg5),
+ : .{ .rcx = true, .r11 = true, .memory = true });
+}
+
+inline fn toU64(value: anytype) u64 {
+ const T = @TypeOf(value);
+ return switch (@typeInfo(T)) {
+ .int, .comptime_int => @intCast(value),
+ .pointer => @intFromPtr(value),
+ .@"enum" => @intFromEnum(value),
+ else => @bitCast(value),
+ };
+}
diff --git a/system.old/libraries/sys/sys.zon b/system.old/libraries/sys/sys.zon
new file mode 100644
index 0000000..35d065e
--- /dev/null
+++ b/system.old/libraries/sys/sys.zon
@@ -0,0 +1,6 @@
+.{
+ .name = "sys",
+ .version = "1.0.0",
+ .type = .library,
+ .entry = "sys.zig",
+}