aboutsummaryrefslogtreecommitdiff
path: root/binaries
diff options
context:
space:
mode:
Diffstat (limited to 'binaries')
-rw-r--r--binaries/mi/mi.zig230
-rw-r--r--binaries/mi/mi.zon9
-rw-r--r--binaries/nav/nav.zig35
-rw-r--r--binaries/nav/nav.zon9
-rw-r--r--binaries/rd/rd.zig48
-rw-r--r--binaries/rd/rd.zon9
-rw-r--r--binaries/wipe/wipe.zig5
-rw-r--r--binaries/wipe/wipe.zon7
8 files changed, 91 insertions, 261 deletions
diff --git a/binaries/mi/mi.zig b/binaries/mi/mi.zig
index 1e158a9..ca9e46f 100644
--- a/binaries/mi/mi.zig
+++ b/binaries/mi/mi.zig
@@ -1,28 +1,18 @@
-//! mi - Professional stack viewer for Akiba OS
+//! mi - Stack viewer for Akiba OS
-const akiba = @import("akiba");
-
-const Color = struct {
- const white: u32 = 0x00FFFFFF;
- const cyan: u32 = 0x0000FFFF;
- const blue: u32 = 0x004488DD;
- const green: u32 = 0x0000DD88;
- const yellow: u32 = 0x00DDDD00;
- const gray: u32 = 0x00777777;
- const purple: u32 = 0x00BB88FF;
- const red: u32 = 0x00FF4444;
-};
+const colors = @import("colors");
+const format = @import("format");
+const io = @import("io");
+const sys = @import("sys");
const PERM_OWNER: u8 = 1;
const PERM_WORLD: u8 = 2;
const PERM_READ_ONLY: u8 = 3;
export fn main(pc: u32, pv: [*]const [*:0]const u8) u8 {
- // Use first argument as path, or default to ""
var target_path: []const u8 = "";
if (pc > 1) {
- // Get pv[1] as the target path
const arg = pv[1];
var len: usize = 0;
while (arg[len] != 0) : (len += 1) {}
@@ -30,7 +20,9 @@ export fn main(pc: u32, pv: [*]const [*:0]const u8) u8 {
}
display_stack(target_path) catch |err| {
- mark_error(@errorName(err));
+ format.color("mi: ", colors.white);
+ format.color(@errorName(err), colors.red);
+ format.print("\n");
return 1;
};
@@ -38,29 +30,24 @@ export fn main(pc: u32, pv: [*]const [*:0]const u8) u8 {
}
fn display_stack(path: []const u8) !void {
- var entries: [128]akiba.io.StackEntry = undefined;
- const count = akiba.io.viewstack(path, &entries) catch {
- // Path doesn't exist or isn't a directory
- _ = akiba.io.mark(akiba.io.stream, "mi: cannot access '", Color.red) catch 0;
- _ = akiba.io.mark(akiba.io.stream, path, Color.white) catch 0;
- _ = akiba.io.mark(akiba.io.stream, "': No such stack.\n", Color.red) catch 0;
+ var entries: [128]io.StackEntry = undefined;
+ const count = io.viewstack(path, &entries) catch {
+ format.color("mi: cannot access '", colors.red);
+ format.print(path);
+ format.colorln("': No such stack.", colors.red);
return;
};
- // Check for empty directory (valid directory with 0 entries)
if (count == 0) {
- _ = akiba.io.mark(akiba.io.stream, path, Color.cyan) catch 0;
- _ = akiba.io.mark(akiba.io.stream, " is empty.\n", Color.gray) catch 0;
+ format.color(path, colors.cyan);
+ format.colorln(" is empty.", colors.gray);
return;
}
- // Calculate max widths for each column
var max_access_len: usize = 6;
var max_size_len: usize = 4;
var max_owner_len: usize = 7;
- var max_date_len: usize = 8;
- const formatted_date_len: usize = 19;
- if (formatted_date_len > max_date_len) max_date_len = formatted_date_len;
+ const max_date_len: usize = 19;
for (0..count) |i| {
const entry = &entries[i];
@@ -68,7 +55,7 @@ fn display_stack(path: []const u8) !void {
if (perms.len > max_access_len) max_access_len = perms.len;
var size_buf: [32]u8 = undefined;
- const size_str = format_size(entry.size, &size_buf);
+ const size_str = format.formatSize(entry.size, &size_buf);
if (size_str.len > max_size_len) max_size_len = size_str.len;
if (entry.owner_name_len > max_owner_len) {
@@ -76,16 +63,15 @@ fn display_stack(path: []const u8) !void {
}
}
- // Print header
- _ = akiba.io.mark(akiba.io.stream, "Access", Color.white) catch 0;
+ format.print("Access");
print_padding(max_access_len - 6 + 2);
- _ = akiba.io.mark(akiba.io.stream, "Size", Color.white) catch 0;
+ format.print("Size");
print_padding(max_size_len - 4 + 2);
- _ = akiba.io.mark(akiba.io.stream, "Persona", Color.white) catch 0;
+ format.print("Persona");
print_padding(max_owner_len - 7 + 3);
- _ = akiba.io.mark(akiba.io.stream, "Modified", Color.white) catch 0;
+ format.print("Modified");
print_padding(max_date_len - 8 + 1);
- _ = akiba.io.mark(akiba.io.stream, "Name\n", Color.white) catch 0;
+ format.println("Name");
var stack_count: usize = 0;
var unit_count: usize = 0;
@@ -97,43 +83,44 @@ fn display_stack(path: []const u8) !void {
const owner = entry.owner_name[0..entry.owner_name_len];
const perms = get_permissions(entry.permission_type);
- _ = akiba.io.mark(akiba.io.stream, perms, Color.cyan) catch 0;
+ format.color(perms, colors.cyan);
print_padding(max_access_len - perms.len + 2);
var size_buf: [32]u8 = undefined;
- const size_str = format_size(entry.size, &size_buf);
- _ = akiba.io.mark(akiba.io.stream, size_str, Color.green) catch 0;
+ const size_str = format.formatSize(entry.size, &size_buf);
+ format.color(size_str, colors.green);
print_padding(max_size_len - size_str.len + 2);
- _ = akiba.io.mark(akiba.io.stream, owner, Color.yellow) catch 0;
+ format.color(owner, colors.yellow);
print_padding(max_owner_len - owner.len + 3);
- format_date(entry.modified_time);
- print_padding(1);
+ var date_buf: [32]u8 = undefined;
+ const date_str = format.formatDate(entry.modified_time, &date_buf);
+ format.color(date_str, colors.blue);
+ print_padding(max_date_len - date_str.len + 2);
if (entry.is_stack) {
stack_count += 1;
total_size += entry.size;
- _ = akiba.io.mark(akiba.io.stream, identity, Color.cyan) catch 0;
- _ = akiba.io.mark(akiba.io.stream, "/", Color.blue) catch 0;
+ format.color(identity, colors.cyan);
+ format.color("/", colors.blue);
} else {
unit_count += 1;
total_size += entry.size;
- _ = akiba.io.mark(akiba.io.stream, identity, Color.white) catch 0;
+ format.print(identity);
}
- _ = akiba.io.mark(akiba.io.stream, "\n", Color.white) catch 0;
+ format.print("\n");
}
- _ = akiba.io.mark(akiba.io.stream, "\n", Color.white) catch 0;
- // Summary
+ format.print("\n");
+
var buf: [16]u8 = undefined;
- _ = akiba.io.mark(akiba.io.stream, int_to_str(stack_count, &buf), Color.gray) catch 0;
- _ = akiba.io.mark(akiba.io.stream, " stacks ", Color.gray) catch 0;
- _ = akiba.io.mark(akiba.io.stream, int_to_str(unit_count, &buf), Color.gray) catch 0;
- _ = akiba.io.mark(akiba.io.stream, " units ", Color.gray) catch 0;
+ format.color(format.intToStr(stack_count, &buf), colors.gray);
+ format.color(" stacks ", colors.gray);
+ format.color(format.intToStr(unit_count, &buf), colors.gray);
+ format.color(" units ", colors.gray);
var size_buf: [32]u8 = undefined;
- _ = akiba.io.mark(akiba.io.stream, format_size(total_size, &size_buf), Color.gray) catch 0;
- _ = akiba.io.mark(akiba.io.stream, "\n", Color.white) catch 0;
+ format.colorln(format.formatSize(total_size, &size_buf), colors.gray);
}
fn get_permissions(perm_type: u8) []const u8 {
@@ -148,139 +135,6 @@ fn get_permissions(perm_type: u8) []const u8 {
fn print_padding(count: usize) void {
var i: usize = 0;
while (i < count) : (i += 1) {
- _ = akiba.io.mark(akiba.io.stream, " ", Color.white) catch {};
- }
-}
-
-fn format_date(timestamp: u64) void {
- if (timestamp == 0) {
- _ = akiba.io.mark(akiba.io.stream, " 1 Jan 1970 00:00 ", Color.blue) catch 0;
- return;
- }
- const SECONDS_PER_DAY: u64 = 86400;
- const SECONDS_PER_HOUR: u64 = 3600;
- const SECONDS_PER_MINUTE: u64 = 60;
- 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 DAYS_PER_4_YEARS: u64 = 1461;
- 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 = (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0);
- 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 = (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0);
- const days_in_months = if (is_leap) [_]u64{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } else [_]u64{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
- const month_names = [_][]const u8{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
- var month: usize = 0;
- var day: u64 = remaining_days + 1;
- for (days_in_months, 0..) |days, m| {
- if (day <= days) {
- month = m;
- break;
- }
- day -= days;
- }
- var buf: [20]u8 = undefined;
- var pos: usize = 0;
- if (day < 10) {
- buf[pos] = '0';
- pos += 1;
- }
- const day_str = int_to_str(day, buf[pos..]);
- pos += day_str.len;
- buf[pos] = ' ';
- pos += 1;
- for (month_names[month]) |c| {
- buf[pos] = c;
- pos += 1;
+ format.print(" ");
}
- buf[pos] = ' ';
- pos += 1;
- const year_str = int_to_str(year, buf[pos..]);
- pos += year_str.len;
- buf[pos] = ' ';
- pos += 1;
- if (hours < 10) {
- buf[pos] = '0';
- pos += 1;
- }
- const hour_str = int_to_str(hours, buf[pos..]);
- pos += hour_str.len;
- buf[pos] = ':';
- pos += 1;
- if (minutes < 10) {
- buf[pos] = '0';
- pos += 1;
- }
- const min_str = int_to_str(minutes, buf[pos..]);
- pos += min_str.len;
- buf[pos] = ' ';
- pos += 1;
- buf[pos] = ' ';
- pos += 1;
- _ = akiba.io.mark(akiba.io.stream, buf[0..pos], Color.blue) catch 0;
-}
-
-fn format_size(size: u64, buf: []u8) []u8 {
- if (size < 1024) {
- const s = int_to_str(size, buf);
- buf[s.len] = 'B';
- return buf[0 .. s.len + 1];
- } else if (size < 1024 * 1024) {
- const kb = size / 1024;
- const s = int_to_str(kb, buf);
- buf[s.len] = 'K';
- buf[s.len + 1] = 'B';
- return buf[0 .. s.len + 2];
- } else if (size < 1024 * 1024 * 1024) {
- const mb = size / (1024 * 1024);
- const s = int_to_str(mb, buf);
- buf[s.len] = 'M';
- buf[s.len + 1] = 'B';
- return buf[0 .. s.len + 2];
- } else {
- const gb = size / (1024 * 1024 * 1024);
- const s = int_to_str(gb, buf);
- buf[s.len] = 'G';
- buf[s.len + 1] = 'B';
- return buf[0 .. s.len + 2];
- }
-}
-
-fn int_to_str(num: usize, 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];
-}
-
-fn mark_error(msg: []const u8) void {
- _ = akiba.io.mark(akiba.io.trace, "mi: ", Color.white) catch 0;
- _ = akiba.io.mark(akiba.io.trace, msg, Color.white) catch 0;
- _ = akiba.io.mark(akiba.io.trace, "\n", Color.white) catch 0;
}
diff --git a/binaries/mi/mi.zon b/binaries/mi/mi.zon
index b7faaf0..352d31e 100644
--- a/binaries/mi/mi.zon
+++ b/binaries/mi/mi.zon
@@ -2,9 +2,10 @@
.name = "mi",
.version = "0.1.0",
.dependencies = .{
- .akiba = .{ .path = "../../system/libraries/akiba" },
- },
- .paths = .{
- "mi.zig",
+ .sys,
+ .io,
+ .colors,
+ .format,
},
+ .entry = "mi.zig",
}
diff --git a/binaries/nav/nav.zig b/binaries/nav/nav.zig
index 98883d0..acdeeb6 100644
--- a/binaries/nav/nav.zig
+++ b/binaries/nav/nav.zig
@@ -1,44 +1,31 @@
//! nav - Navigate the filesystem
-//!
-//! nav - Print current location
-//! nav <path> - Navigate to path
-//! nav ^ - Navigate to parent
-//! nav / - Navigate to root
-const akiba = @import("akiba");
+const colors = @import("colors");
+const format = @import("format");
+const io = @import("io");
+const sys = @import("sys");
-const Color = struct {
- const white: u32 = 0x00FFFFFF;
- const green: u32 = 0x0088FF88;
- const red: u32 = 0x00FF4444;
-};
-
-// Global buffer
var location_buf: [256]u8 = undefined;
export fn main(pc: u32, pv: [*]const [*:0]const u8) u8 {
- // No arguments - print current location
if (pc <= 1) {
- const location = akiba.io.getlocation(&location_buf) catch {
- _ = akiba.io.mark(akiba.io.stream, "nav: cannot get current location.\n", Color.red) catch 0;
+ const location = io.getlocation(&location_buf) catch {
+ format.colorln("nav: cannot get current location.", colors.red);
return 1;
};
- _ = akiba.io.mark(akiba.io.stream, location, Color.green) catch 0;
- _ = akiba.io.mark(akiba.io.stream, "\n", Color.white) catch 0;
+ format.colorln(location, colors.green);
return 0;
}
- // Get target path from argument
const arg = pv[1];
var target_len: usize = 0;
while (arg[target_len] != 0) : (target_len += 1) {}
const target = arg[0..target_len];
- // Navigate - setlocation auto-sends letter to parent
- akiba.io.setlocation(target) catch {
- _ = akiba.io.mark(akiba.io.stream, "nav: cannot navigate to '", Color.red) catch 0;
- _ = akiba.io.mark(akiba.io.stream, target, Color.white) catch 0;
- _ = akiba.io.mark(akiba.io.stream, "': No such stack.\n", Color.red) catch 0;
+ io.setlocation(target) catch {
+ format.color("nav: cannot navigate to '", colors.red);
+ format.print(target);
+ format.colorln("': No such stack.", colors.red);
return 1;
};
diff --git a/binaries/nav/nav.zon b/binaries/nav/nav.zon
index 8597b44..21d50a4 100644
--- a/binaries/nav/nav.zon
+++ b/binaries/nav/nav.zon
@@ -2,9 +2,10 @@
.name = "nav",
.version = "0.1.0",
.dependencies = .{
- .akiba = .{ .path = "../../system/libraries/akiba" },
- },
- .paths = .{
- "nav.zig",
+ .sys,
+ .io,
+ .colors,
+ .format,
},
+ .entry = "nav.zig",
}
diff --git a/binaries/rd/rd.zig b/binaries/rd/rd.zig
index e16f7cc..008cb54 100644
--- a/binaries/rd/rd.zig
+++ b/binaries/rd/rd.zig
@@ -1,61 +1,47 @@
//! rd - Read unit contents
-//!
-//! rd <location> - Display contents of a unit (file)
-//! rd - Error: no location specified
-const akiba = @import("akiba");
+const colors = @import("colors");
+const format = @import("format");
+const io = @import("io");
+const sys = @import("sys");
-const Color = struct {
- const white: u32 = 0x00FFFFFF;
- const red: u32 = 0x00FF4444;
- const gray: u32 = 0x00888888;
-};
-
-// Buffer for file contents (64KB max)
var file_buffer: [64 * 1024]u8 = undefined;
export fn main(pc: u32, pv: [*]const [*:0]const u8) u8 {
- // No arguments - show error
if (pc <= 1) {
- _ = akiba.io.mark(akiba.io.stream, "rd: missing unit location.\n", Color.red) catch 0;
+ format.colorln("rd: missing unit location.", colors.red);
return 1;
}
- // Get location from argument
const arg = pv[1];
var location_len: usize = 0;
while (arg[location_len] != 0) : (location_len += 1) {}
const location = arg[0..location_len];
- // Open the file
- const fd = akiba.io.attach(location, akiba.io.VIEW_ONLY) catch {
- _ = akiba.io.mark(akiba.io.stream, "rd: cannot access '", Color.red) catch 0;
- _ = akiba.io.mark(akiba.io.stream, location, Color.white) catch 0;
- _ = akiba.io.mark(akiba.io.stream, "': No such unit.\n", Color.red) catch 0;
+ const fd = io.attach(location, io.VIEW_ONLY) catch {
+ format.color("rd: cannot access '", colors.red);
+ format.print(location);
+ format.colorln("': No such unit.", colors.red);
return 1;
};
- // Read contents
- const bytes_read = akiba.io.view(fd, &file_buffer) catch {
- _ = akiba.io.mark(akiba.io.stream, "rd: cannot read '", Color.red) catch 0;
- _ = akiba.io.mark(akiba.io.stream, location, Color.white) catch 0;
- _ = akiba.io.mark(akiba.io.stream, "'.\n", Color.red) catch 0;
- akiba.io.seal(fd);
+ const bytes_read = io.view(fd, &file_buffer) catch {
+ format.color("rd: cannot read '", colors.red);
+ format.print(location);
+ format.colorln("'.", colors.red);
+ io.seal(fd);
return 1;
};
- // Display contents
if (bytes_read > 0) {
- _ = akiba.io.mark(akiba.io.stream, file_buffer[0..bytes_read], Color.white) catch 0;
+ format.print(file_buffer[0..bytes_read]);
- // Add newline if file doesn't end with one
if (file_buffer[bytes_read - 1] != '\n') {
- _ = akiba.io.mark(akiba.io.stream, "\n", Color.white) catch 0;
+ format.print("\n");
}
}
- // Close file
- akiba.io.seal(fd);
+ io.seal(fd);
return 0;
}
diff --git a/binaries/rd/rd.zon b/binaries/rd/rd.zon
index 0480840..47cddc8 100644
--- a/binaries/rd/rd.zon
+++ b/binaries/rd/rd.zon
@@ -2,9 +2,10 @@
.name = "rd",
.version = "0.1.0",
.dependencies = .{
- .akiba = .{ .path = "../../system/libraries/akiba" },
- },
- .paths = .{
- "rd.zig",
+ .sys,
+ .io,
+ .colors,
+ .format,
},
+ .entry = "rd.zig",
}
diff --git a/binaries/wipe/wipe.zig b/binaries/wipe/wipe.zig
index 34c6f95..8bdc336 100644
--- a/binaries/wipe/wipe.zig
+++ b/binaries/wipe/wipe.zig
@@ -1,10 +1,11 @@
//! wipe - Clear the terminal screen
-const akiba = @import("akiba");
+const io = @import("io");
+const sys = @import("sys");
export fn main(pc: u32, pv: [*]const [*:0]const u8) u8 {
_ = pc;
_ = pv;
- akiba.io.wipe();
+ io.wipe();
return 0;
}
diff --git a/binaries/wipe/wipe.zon b/binaries/wipe/wipe.zon
index 0c6f141..4c90d6c 100644
--- a/binaries/wipe/wipe.zon
+++ b/binaries/wipe/wipe.zon
@@ -2,9 +2,8 @@
.name = "wipe",
.version = "0.1.0",
.dependencies = .{
- .akiba = .{ .path = "../../system/libraries/akiba" },
- },
- .paths = .{
- "wipe.zig",
+ .sys,
+ .io,
},
+ .entry = "wipe.zig",
}