aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobby <[email protected]>2026-02-20 16:01:59 +0530
committerBobby <[email protected]>2026-02-20 16:01:59 +0530
commit91e2c4202a6772a3e3de4cae8c671d4d79cb7af0 (patch)
treedd0b75465a3c90b4f8a9acc22652a85431347756
parentc1c827540981247fd943318f503e5d814e91921d (diff)
downloadakiba-91e2c4202a6772a3e3de4cae8c671d4d79cb7af0.tar.xz
akiba-91e2c4202a6772a3e3de4cae8c671d4d79cb7af0.zip
feat: Add datetime and OS information libraries with formatting and retrieval functions
-rw-r--r--system/libraries/datetime/datetime.zig13
-rw-r--r--system/libraries/datetime/datetime.zon9
-rw-r--r--system/libraries/datetime/format.zig111
-rw-r--r--system/libraries/datetime/time.zig (renamed from system/libraries/format/date.zig)81
-rw-r--r--system/libraries/datetime/types.zig10
-rw-r--r--system/libraries/format/bytes.zig47
-rw-r--r--system/libraries/format/format.zig4
-rw-r--r--system/libraries/os/cpu.zig19
-rw-r--r--system/libraries/os/disk.zig25
-rw-r--r--system/libraries/os/memory.zig28
-rw-r--r--system/libraries/os/os.zig15
-rw-r--r--system/libraries/os/os.zon9
-rw-r--r--system/libraries/os/types.zig12
-rw-r--r--system/libraries/os/uptime.zig15
-rw-r--r--system/libraries/sys/sys.zig5
15 files changed, 345 insertions, 58 deletions
diff --git a/system/libraries/datetime/datetime.zig b/system/libraries/datetime/datetime.zig
new file mode 100644
index 0000000..d72d679
--- /dev/null
+++ b/system/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/libraries/datetime/datetime.zon b/system/libraries/datetime/datetime.zon
new file mode 100644
index 0000000..a55aede
--- /dev/null
+++ b/system/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/libraries/datetime/format.zig b/system/libraries/datetime/format.zig
new file mode 100644
index 0000000..daebd10
--- /dev/null
+++ b/system/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/libraries/format/date.zig b/system/libraries/datetime/time.zig
index d90adec..9634ace 100644
--- a/system/libraries/format/date.zig
+++ b/system/libraries/datetime/time.zig
@@ -1,29 +1,34 @@
-//! Date formatting
+//! Time operations
-const int = @import("int.zig");
+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 MONTH_NAMES = [_][]const u8{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
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 format(timestamp: u64, buf: []u8) []u8 {
- if (timestamp == 0) {
- const default = "01 Jan 1970 00:00";
- for (default, 0..) |c, i| {
- buf[i] = c;
- }
- return buf[0..default.len];
+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;
@@ -46,61 +51,25 @@ pub fn format(timestamp: u64, buf: []u8) []u8 {
const is_leap = isLeapYear(year);
const days_in_months = if (is_leap) DAYS_LEAP else DAYS_NORMAL;
- var month: usize = 0;
+ var month: u8 = 1;
var day: u64 = remaining_days + 1;
for (days_in_months, 0..) |days, m| {
if (day <= days) {
- month = m;
+ month = @intCast(m + 1);
break;
}
day -= days;
}
- var pos: usize = 0;
-
- if (day < 10) {
- buf[pos] = '0';
- pos += 1;
- }
- const day_str = int.toStr(day, buf[pos..]);
- pos += day_str.len;
-
- buf[pos] = ' ';
- pos += 1;
-
- for (MONTH_NAMES[month]) |c| {
- buf[pos] = c;
- pos += 1;
- }
-
- buf[pos] = ' ';
- pos += 1;
-
- const year_str = int.toStr(year, buf[pos..]);
- pos += year_str.len;
-
- buf[pos] = ' ';
- pos += 1;
-
- if (hours < 10) {
- buf[pos] = '0';
- pos += 1;
- }
- const hour_str = int.toStr(hours, buf[pos..]);
- pos += hour_str.len;
-
- buf[pos] = ':';
- pos += 1;
-
- if (minutes < 10) {
- buf[pos] = '0';
- pos += 1;
- }
- const min_str = int.toStr(minutes, buf[pos..]);
- pos += min_str.len;
-
- return buf[0..pos];
+ return types.DateTime{
+ .year = year,
+ .month = month,
+ .day = @intCast(day),
+ .hour = @intCast(hours),
+ .minute = @intCast(minutes),
+ .second = @intCast(seconds),
+ };
}
fn isLeapYear(year: u64) bool {
diff --git a/system/libraries/datetime/types.zig b/system/libraries/datetime/types.zig
new file mode 100644
index 0000000..5024e3a
--- /dev/null
+++ b/system/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/libraries/format/bytes.zig b/system/libraries/format/bytes.zig
new file mode 100644
index 0000000..9d4cb86
--- /dev/null
+++ b/system/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/libraries/format/format.zig b/system/libraries/format/format.zig
index e516017..02a5632 100644
--- a/system/libraries/format/format.zig
+++ b/system/libraries/format/format.zig
@@ -2,13 +2,13 @@
pub const int = @import("int.zig");
pub const size = @import("size.zig");
-pub const date = @import("date.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 formatDate = date.format;
+pub const formatBytes = bytes.format;
pub const print = printmod.print;
pub const println = printmod.println;
diff --git a/system/libraries/os/cpu.zig b/system/libraries/os/cpu.zig
new file mode 100644
index 0000000..1f3ea53
--- /dev/null
+++ b/system/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/libraries/os/disk.zig b/system/libraries/os/disk.zig
new file mode 100644
index 0000000..9a43c26
--- /dev/null
+++ b/system/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/libraries/os/memory.zig b/system/libraries/os/memory.zig
new file mode 100644
index 0000000..86c2a08
--- /dev/null
+++ b/system/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/libraries/os/os.zig b/system/libraries/os/os.zig
new file mode 100644
index 0000000..18b8730
--- /dev/null
+++ b/system/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/libraries/os/os.zon b/system/libraries/os/os.zon
new file mode 100644
index 0000000..e1bc062
--- /dev/null
+++ b/system/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/libraries/os/types.zig b/system/libraries/os/types.zig
new file mode 100644
index 0000000..1b06af9
--- /dev/null
+++ b/system/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/libraries/os/uptime.zig b/system/libraries/os/uptime.zig
new file mode 100644
index 0000000..0f499ff
--- /dev/null
+++ b/system/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/libraries/sys/sys.zig b/system/libraries/sys/sys.zig
index d37e4c8..b080a90 100644
--- a/system/libraries/sys/sys.zig
+++ b/system/libraries/sys/sys.zig
@@ -21,6 +21,11 @@ pub const Invocation = enum(u64) {
setlocation = 0x0C,
postman = 0x0D,
wipe = 0x0E,
+ cpuinfo = 0x0F,
+ meminfo = 0x10,
+ uptime = 0x11,
+ gettime = 0x12,
+ diskinfo = 0x13,
};
pub inline fn syscall(invocation: Invocation, args: anytype) u64 {