summaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/cls.zig22
-rw-r--r--src/cmd/date.zig68
-rw-r--r--src/cmd/echo.zig68
-rw-r--r--src/cmd/move.zig24
-rw-r--r--src/cmd/sort.zig63
-rw-r--r--src/cmd/time.zig31
-rw-r--r--src/cmd/ver.zig24
7 files changed, 300 insertions, 0 deletions
diff --git a/src/cmd/cls.zig b/src/cmd/cls.zig
new file mode 100644
index 0000000..b476563
--- /dev/null
+++ b/src/cmd/cls.zig
@@ -0,0 +1,22 @@
+const std = @import("std");
+const Allocator = std.mem.Allocator;
+const print = std.debug.print;
+
+const types = @import("./types.zig");
+const CommandStatus = types.CommandStatus;
+const OutputCapture = types.OutputCapture;
+const InputSource = types.InputSource;
+
+pub const Cls = struct {
+ pub fn eval(cls: Cls, allocator: Allocator, output_capture: ?*OutputCapture, input_source: ?*InputSource) !CommandStatus {
+ _ = cls;
+ _ = allocator;
+ _ = input_source;
+
+ if (output_capture == null) {
+ // Clear screen - only works when not redirected
+ print("\x1B[2J\x1B[H", .{});
+ }
+ return CommandStatus{ .Code = 0 };
+ }
+};
diff --git a/src/cmd/date.zig b/src/cmd/date.zig
new file mode 100644
index 0000000..c6db0a2
--- /dev/null
+++ b/src/cmd/date.zig
@@ -0,0 +1,68 @@
+const std = @import("std");
+const Allocator = std.mem.Allocator;
+const print = std.debug.print;
+
+const types = @import("./types.zig");
+const CommandStatus = types.CommandStatus;
+const OutputCapture = types.OutputCapture;
+const InputSource = types.InputSource;
+
+fn isLeapYear(year: u32) bool {
+ return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0);
+}
+
+pub const Date = struct {
+ pub fn eval(date: Date, allocator: Allocator, output_capture: ?*OutputCapture, input_source: ?*InputSource) !CommandStatus {
+ _ = date;
+ _ = input_source;
+
+ const timestamp = std.time.timestamp();
+ const epoch_seconds = @as(u64, @intCast(timestamp));
+ const epoch_day = @divFloor(epoch_seconds, std.time.s_per_day);
+
+ // Calculate days since Unix epoch (1970-01-01)
+ // Unix epoch is 719163 days since year 1 AD
+ const days_since_year_1 = epoch_day + 719163;
+
+ // Simple algorithm to convert days to year/month/day
+ var year: u32 = 1;
+ var remaining_days = days_since_year_1;
+
+ // Find the year
+ while (true) {
+ const days_in_year: u64 = if (isLeapYear(year)) 366 else 365;
+ if (remaining_days < days_in_year) break;
+ remaining_days -= days_in_year;
+ year += 1;
+ }
+
+ // Days in each month (non-leap year)
+ const days_in_month = [_]u32{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+ var month: u32 = 1;
+ for (days_in_month, 1..) |days, m| {
+ var month_days = days;
+ // Adjust February for leap years
+ if (m == 2 and isLeapYear(year)) {
+ month_days = 29;
+ }
+
+ if (remaining_days < month_days) {
+ month = @intCast(m);
+ break;
+ }
+ remaining_days -= month_days;
+ }
+
+ const day = remaining_days + 1; // Days are 1-indexed
+
+ const output = try std.fmt.allocPrint(allocator, "Current date is {d:0>2}/{d:0>2}/{d}\n", .{ month, day, year });
+ defer allocator.free(output);
+ if (output_capture) |capture| {
+ try capture.write(output);
+ } else {
+ print("{s}", .{output});
+ }
+ return CommandStatus{ .Code = 0 };
+ }
+};
diff --git a/src/cmd/echo.zig b/src/cmd/echo.zig
new file mode 100644
index 0000000..a11d748
--- /dev/null
+++ b/src/cmd/echo.zig
@@ -0,0 +1,68 @@
+const std = @import("std");
+const Allocator = std.mem.Allocator;
+const print = std.debug.print;
+
+const types = @import("./types.zig");
+const CommandStatus = types.CommandStatus;
+const OutputCapture = types.OutputCapture;
+const InputSource = types.InputSource;
+
+pub const EchoOff = struct {
+ pub fn eval(echo_off: EchoOff, allocator: Allocator, output_capture: ?*OutputCapture, input_source: ?*InputSource) !CommandStatus {
+ _ = echo_off;
+ _ = allocator;
+ _ = output_capture;
+ _ = input_source;
+
+ return CommandStatus{ .Code = 0 };
+ }
+};
+
+pub const EchoOn = struct {
+ pub fn eval(echo_on: EchoOn, allocator: Allocator, output_capture: ?*OutputCapture, input_source: ?*InputSource) !CommandStatus {
+ _ = echo_on;
+ _ = allocator;
+ _ = input_source;
+
+ const output = "ECHO is on\n";
+ if (output_capture) |capture| {
+ try capture.write(output);
+ } else {
+ print("{s}", .{output});
+ }
+ return CommandStatus{ .Code = 0 };
+ }
+};
+
+pub const EchoPlain = struct {
+ pub fn eval(echo_plain: EchoPlain, allocator: Allocator, output_capture: ?*OutputCapture, input_source: ?*InputSource) !CommandStatus {
+ _ = echo_plain;
+ _ = allocator;
+ _ = input_source;
+
+ const output = "ECHO is on\n";
+ if (output_capture) |capture| {
+ try capture.write(output);
+ } else {
+ print("{s}", .{output});
+ }
+ return CommandStatus{ .Code = 0 };
+ }
+};
+
+pub const EchoText = struct {
+ message: []const u8,
+
+ pub fn eval(echo_text: EchoText, allocator: Allocator, output_capture: ?*OutputCapture, input_source: ?*InputSource) !CommandStatus {
+ _ = input_source;
+
+ const output = try std.fmt.allocPrint(allocator, "{s}\n", .{echo_text.message});
+ defer allocator.free(output);
+ if (output_capture) |capture| {
+ try capture.write(output);
+ } else {
+ print("{s}", .{output});
+ }
+ return CommandStatus{ .Code = 0 };
+ }
+};
diff --git a/src/cmd/move.zig b/src/cmd/move.zig
new file mode 100644
index 0000000..ceaa6db
--- /dev/null
+++ b/src/cmd/move.zig
@@ -0,0 +1,24 @@
+const std = @import("std");
+const Allocator = std.mem.Allocator;
+const print = std.debug.print;
+
+const types = @import("./types.zig");
+const CommandStatus = types.CommandStatus;
+const OutputCapture = types.OutputCapture;
+const InputSource = types.InputSource;
+
+pub const Move = struct {
+ pub fn eval(move: Move, allocator: Allocator, output_capture: ?*OutputCapture, input_source: ?*InputSource) !CommandStatus {
+ _ = move;
+ _ = allocator;
+ _ = input_source;
+
+ const error_msg = "MOVE command not yet implemented\n";
+ if (output_capture) |capture| {
+ try capture.write(error_msg);
+ } else {
+ print("{s}", .{error_msg});
+ }
+ return CommandStatus{ .Code = 1 };
+ }
+};
diff --git a/src/cmd/sort.zig b/src/cmd/sort.zig
new file mode 100644
index 0000000..fb08f0b
--- /dev/null
+++ b/src/cmd/sort.zig
@@ -0,0 +1,63 @@
+const std = @import("std");
+const Allocator = std.mem.Allocator;
+const ArrayList = std.ArrayList;
+const print = std.debug.print;
+
+const types = @import("./types.zig");
+const CommandStatus = types.CommandStatus;
+const OutputCapture = types.OutputCapture;
+const InputSource = types.InputSource;
+
+pub const Sort = struct {
+ pub fn eval(sort: Sort, allocator: Allocator, output_capture: ?*OutputCapture, input_source: ?*InputSource) !CommandStatus {
+ _ = sort;
+
+ var lines = ArrayList([]const u8).init(allocator);
+ defer {
+ for (lines.items) |line| {
+ allocator.free(line);
+ }
+ lines.deinit();
+ }
+
+ // Read input lines
+ if (input_source) |source| {
+ // Read from input redirection
+ while (try source.readLine(allocator)) |line| {
+ try lines.append(line);
+ }
+ } else {
+ // Read from stdin (simplified - just show message)
+ const msg = "SORT: Use input redirection (< file.txt) to sort file contents\n";
+ if (output_capture) |capture| {
+ try capture.write(msg);
+ } else {
+ print("{s}", .{msg});
+ }
+ return CommandStatus{ .Code = 0 };
+ }
+
+ // Sort the lines
+ std.mem.sort([]const u8, lines.items, {}, struct {
+ fn lessThan(_: void, lhs: []const u8, rhs: []const u8) bool {
+ return std.mem.order(u8, lhs, rhs) == .lt;
+ }
+ }.lessThan);
+
+ // Output sorted lines
+ var output_buffer = ArrayList(u8).init(allocator);
+ defer output_buffer.deinit();
+
+ for (lines.items) |line| {
+ try output_buffer.writer().print("{s}\n", .{line});
+ }
+
+ if (output_capture) |capture| {
+ try capture.write(output_buffer.items);
+ } else {
+ print("{s}", .{output_buffer.items});
+ }
+
+ return CommandStatus{ .Code = 0 };
+ }
+};
diff --git a/src/cmd/time.zig b/src/cmd/time.zig
new file mode 100644
index 0000000..57d58bd
--- /dev/null
+++ b/src/cmd/time.zig
@@ -0,0 +1,31 @@
+const std = @import("std");
+const Allocator = std.mem.Allocator;
+const print = std.debug.print;
+
+const types = @import("./types.zig");
+const CommandStatus = types.CommandStatus;
+const OutputCapture = types.OutputCapture;
+const InputSource = types.InputSource;
+
+pub const Time = struct {
+ pub fn eval(time: Time, allocator: Allocator, output_capture: ?*OutputCapture, input_source: ?*InputSource) !CommandStatus {
+ _ = time;
+ _ = input_source;
+
+ const timestamp = std.time.timestamp();
+ const epoch_seconds = @as(u64, @intCast(timestamp));
+ const day_seconds = epoch_seconds % std.time.s_per_day;
+ const hours = day_seconds / std.time.s_per_hour;
+ const minutes = (day_seconds % std.time.s_per_hour) / std.time.s_per_min;
+ const seconds = day_seconds % std.time.s_per_min;
+
+ const output = try std.fmt.allocPrint(allocator, "Current time is {d:0>2}:{d:0>2}:{d:0>2}\n", .{ hours, minutes, seconds });
+ defer allocator.free(output);
+ if (output_capture) |capture| {
+ try capture.write(output);
+ } else {
+ print("{s}", .{output});
+ }
+ return CommandStatus{ .Code = 0 };
+ }
+};
diff --git a/src/cmd/ver.zig b/src/cmd/ver.zig
new file mode 100644
index 0000000..286f6f9
--- /dev/null
+++ b/src/cmd/ver.zig
@@ -0,0 +1,24 @@
+const std = @import("std");
+const Allocator = std.mem.Allocator;
+const print = std.debug.print;
+
+const types = @import("./types.zig");
+const CommandStatus = types.CommandStatus;
+const OutputCapture = types.OutputCapture;
+const InputSource = types.InputSource;
+
+pub const Ver = struct {
+ pub fn eval(ver: Ver, allocator: Allocator, output_capture: ?*OutputCapture, input_source: ?*InputSource) !CommandStatus {
+ _ = ver;
+ _ = allocator;
+ _ = input_source;
+
+ const output = "MB-DOSE Version 6.22\n";
+ if (output_capture) |capture| {
+ try capture.write(output);
+ } else {
+ print("{s}", .{output});
+ }
+ return CommandStatus{ .Code = 0 };
+ }
+};