summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel A. Giovanini <mail@gabrielgio.me>2024-07-19 00:01:55 +0200
committerGabriel A. Giovanini <mail@gabrielgio.me>2024-07-19 00:01:55 +0200
commit5d391ac3c3bf0ffc02e5f6eae00db949810346b3 (patch)
treea086b976b53c8af23b960f57a64f8e66f00c35ed
downloaduf-5d391ac3c3bf0ffc02e5f6eae00db949810346b3.tar.gz
uf-5d391ac3c3bf0ffc02e5f6eae00db949810346b3.tar.bz2
uf-5d391ac3c3bf0ffc02e5f6eae00db949810346b3.zip
feat: Initial setup
-rw-r--r--.gitignore2
-rw-r--r--build.zig42
-rw-r--r--src/main.zig75
-rw-r--r--src/root.zig10
4 files changed, 129 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ee7098f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+zig-out/
+zig-cache/
diff --git a/build.zig b/build.zig
new file mode 100644
index 0000000..17d4fb7
--- /dev/null
+++ b/build.zig
@@ -0,0 +1,42 @@
+const std = @import("std");
+
+pub fn build(b: *std.Build) void {
+ const target = b.standardTargetOptions(.{});
+
+ const optimize = b.standardOptimizeOption(.{
+ .preferred_optimize_mode = std.builtin.OptimizeMode.ReleaseFast,
+ });
+
+ const exe = b.addExecutable(.{
+ .name = "uf",
+ .root_source_file = b.path("src/main.zig"),
+ .target = target,
+ .optimize = optimize,
+ .single_threaded = true,
+ .strip = true,
+ });
+
+ b.installArtifact(exe);
+
+ const run_cmd = b.addRunArtifact(exe);
+
+ run_cmd.step.dependOn(b.getInstallStep());
+
+ if (b.args) |args| {
+ run_cmd.addArgs(args);
+ }
+
+ const run_step = b.step("run", "Run the app");
+ run_step.dependOn(&run_cmd.step);
+
+ const exe_unit_tests = b.addTest(.{
+ .root_source_file = b.path("src/main.zig"),
+ .target = target,
+ .optimize = optimize,
+ });
+
+ const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
+
+ const test_step = b.step("test", "Run unit tests");
+ test_step.dependOn(&run_exe_unit_tests.step);
+}
diff --git a/src/main.zig b/src/main.zig
new file mode 100644
index 0000000..c65a36b
--- /dev/null
+++ b/src/main.zig
@@ -0,0 +1,75 @@
+const std = @import("std");
+const File = std.fs.File;
+const Writer = std.fs.File.Writer;
+
+pub fn main() !void {
+ const in = std.io.getStdIn();
+ const out = std.io.getStdOut();
+ Uf.init().streamCopy(in, out) catch |err| {
+ try std.io.getStdErr().writer().print("Error {}", .{err});
+ };
+}
+
+const buf_size = 1_000_000;
+
+const Uf = struct {
+ const Self = @This();
+
+ var out_buf: [buf_size]u8 = undefined;
+ var out_index: u32 = 0;
+
+ fn init() *const Self {
+ return &Self{};
+ }
+
+ fn flush(_: *const Self, out: Writer) !void {
+ _ = try out.write(out_buf[0..out_index]);
+ out_index = 0;
+ }
+
+ fn writeChar(self: *const Self, out: Writer, c: u8) !void {
+ if (out_index >= buf_size) {
+ try self.flush(out);
+ }
+ out_buf[out_index] = c;
+ out_index += 1;
+ }
+
+ fn streamCopy(self: *const Self, in: File, out: File) !void {
+ const reader = in.reader();
+ const writer = out.writer();
+
+ var hit = false;
+ var second = false;
+ var in_buf: [buf_size]u8 = undefined;
+ while (true) {
+ const size = try reader.read(&in_buf);
+
+ for (in_buf[0..size]) |c| {
+ if (hit and c == '\n') {
+ if (second == false) {
+ second = true;
+ } else {
+ continue;
+ }
+ } else if (hit and c != '\n') {
+ if (second) {
+ try self.writeChar(writer, '\n');
+ }
+ hit = false;
+ second = false;
+ } else if (c == '\n') {
+ hit = true;
+ continue;
+ }
+
+ try self.writeChar(writer, c);
+ }
+
+ if (size != in_buf.len) {
+ try self.flush(writer);
+ return;
+ }
+ }
+ }
+};
diff --git a/src/root.zig b/src/root.zig
new file mode 100644
index 0000000..ecfeade
--- /dev/null
+++ b/src/root.zig
@@ -0,0 +1,10 @@
+const std = @import("std");
+const testing = std.testing;
+
+export fn add(a: i32, b: i32) i32 {
+ return a + b;
+}
+
+test "basic add functionality" {
+ try testing.expect(add(3, 7) == 10);
+}