Compare commits
10 commits
283bfa5407
...
a6358d5156
Author | SHA1 | Date | |
---|---|---|---|
a6358d5156 | |||
ef0088a923 | |||
50d5b969a9 | |||
a3fc96418f | |||
a84f213848 | |||
641528ac84 | |||
ec79f693a5 | |||
e3cef17b63 | |||
9e96cbb4c3 | |||
fc512c0689 |
5 changed files with 214 additions and 22 deletions
100
build.zig
100
build.zig
|
@ -1,9 +1,92 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
pub fn build(b: *std.Build) void {
|
pub fn build(b: *std.Build) void {
|
||||||
|
const release = b.option(bool, "package_release", "Build all release targets") orelse false;
|
||||||
|
const strip = b.option(bool, "strip", "Disable debug information (default: no)");
|
||||||
|
const pie = b.option(bool, "pie", "Produce an executable with position independent code (default: none)");
|
||||||
|
|
||||||
|
const run_step = b.step("run", "Run the app");
|
||||||
|
|
||||||
|
return (if (release) &build_release else &build_development)(
|
||||||
|
b,
|
||||||
|
run_step,
|
||||||
|
strip,
|
||||||
|
pie,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_development(
|
||||||
|
b: *std.Build,
|
||||||
|
run_step: *std.Build.Step,
|
||||||
|
strip: ?bool,
|
||||||
|
pie: ?bool,
|
||||||
|
) void {
|
||||||
const target = b.standardTargetOptions(.{});
|
const target = b.standardTargetOptions(.{});
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
|
return build_exe(
|
||||||
|
b,
|
||||||
|
run_step,
|
||||||
|
target,
|
||||||
|
optimize,
|
||||||
|
.{},
|
||||||
|
strip orelse false,
|
||||||
|
pie,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_release(
|
||||||
|
b: *std.Build,
|
||||||
|
run_step: *std.Build.Step,
|
||||||
|
strip: ?bool,
|
||||||
|
pie: ?bool,
|
||||||
|
) void {
|
||||||
|
const targets: []const std.Target.Query = &.{
|
||||||
|
.{ .cpu_arch = .x86_64, .os_tag = .linux, .abi = .musl },
|
||||||
|
.{ .cpu_arch = .aarch64, .os_tag = .linux, .abi = .musl },
|
||||||
|
.{ .cpu_arch = .x86_64, .os_tag = .macos },
|
||||||
|
.{ .cpu_arch = .aarch64, .os_tag = .macos },
|
||||||
|
.{ .cpu_arch = .x86_64, .os_tag = .windows },
|
||||||
|
.{ .cpu_arch = .aarch64, .os_tag = .windows },
|
||||||
|
};
|
||||||
|
const optimize = .ReleaseFast;
|
||||||
|
|
||||||
|
var version = std.ArrayList(u8).init(b.allocator);
|
||||||
|
defer version.deinit();
|
||||||
|
gen_version(b, version.writer()) catch unreachable;
|
||||||
|
const write_file_step = b.addWriteFiles();
|
||||||
|
const version_file = write_file_step.add("version", version.items);
|
||||||
|
b.getInstallStep().dependOn(&b.addInstallFile(version_file, "version").step);
|
||||||
|
|
||||||
|
for (targets) |t| {
|
||||||
|
const target = b.resolveTargetQuery(t);
|
||||||
|
var triple = std.mem.splitScalar(u8, t.zigTriple(b.allocator) catch unreachable, '-');
|
||||||
|
const arch = triple.next() orelse unreachable;
|
||||||
|
const os = triple.next() orelse unreachable;
|
||||||
|
const target_path = std.mem.join(b.allocator, "-", &[_][]const u8{ os, arch }) catch unreachable;
|
||||||
|
|
||||||
|
build_exe(
|
||||||
|
b,
|
||||||
|
run_step,
|
||||||
|
target,
|
||||||
|
optimize,
|
||||||
|
.{ .dest_dir = .{ .override = .{ .custom = target_path } } },
|
||||||
|
strip orelse true,
|
||||||
|
pie,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build_exe(
|
||||||
|
b: *std.Build,
|
||||||
|
run_step: *std.Build.Step,
|
||||||
|
target: std.Build.ResolvedTarget,
|
||||||
|
optimize: std.builtin.OptimizeMode,
|
||||||
|
exe_install_options: std.Build.Step.InstallArtifact.Options,
|
||||||
|
strip: bool,
|
||||||
|
pie: ?bool,
|
||||||
|
) void {
|
||||||
|
|
||||||
const clap_dep = b.dependency("clap", .{ .target = target, .optimize = optimize });
|
const clap_dep = b.dependency("clap", .{ .target = target, .optimize = optimize });
|
||||||
const ansi_term_dep = b.dependency("ansi-term", .{ .target = target, .optimize = optimize });
|
const ansi_term_dep = b.dependency("ansi-term", .{ .target = target, .optimize = optimize });
|
||||||
const themes_dep = b.dependency("themes", .{});
|
const themes_dep = b.dependency("themes", .{});
|
||||||
|
@ -15,18 +98,31 @@ pub fn build(b: *std.Build) void {
|
||||||
.root_source_file = b.path("src/main.zig"),
|
.root_source_file = b.path("src/main.zig"),
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
|
.strip = strip,
|
||||||
});
|
});
|
||||||
|
if (pie) |value| exe.pie = value;
|
||||||
exe.root_module.addImport("syntax", syntax_dep.module("syntax"));
|
exe.root_module.addImport("syntax", syntax_dep.module("syntax"));
|
||||||
exe.root_module.addImport("theme", themes_dep.module("theme"));
|
exe.root_module.addImport("theme", themes_dep.module("theme"));
|
||||||
exe.root_module.addImport("themes", themes_dep.module("themes"));
|
exe.root_module.addImport("themes", themes_dep.module("themes"));
|
||||||
exe.root_module.addImport("clap", clap_dep.module("clap"));
|
exe.root_module.addImport("clap", clap_dep.module("clap"));
|
||||||
exe.root_module.addImport("ansi-term", ansi_term_dep.module("ansi-term"));
|
exe.root_module.addImport("ansi-term", ansi_term_dep.module("ansi-term"));
|
||||||
exe.root_module.addImport("cbor", b.createModule(.{ .root_source_file = thespian_dep.path("src/cbor.zig") }));
|
exe.root_module.addImport("cbor", b.createModule(.{ .root_source_file = thespian_dep.path("src/cbor.zig") }));
|
||||||
b.installArtifact(exe);
|
const exe_install = b.addInstallArtifact(exe, exe_install_options);
|
||||||
|
b.getInstallStep().dependOn(&exe_install.step);
|
||||||
|
|
||||||
const run_cmd = b.addRunArtifact(exe);
|
const run_cmd = b.addRunArtifact(exe);
|
||||||
run_cmd.step.dependOn(b.getInstallStep());
|
run_cmd.step.dependOn(b.getInstallStep());
|
||||||
if (b.args) |args| run_cmd.addArgs(args);
|
if (b.args) |args| run_cmd.addArgs(args);
|
||||||
const run_step = b.step("run", "Run the app");
|
|
||||||
run_step.dependOn(&run_cmd.step);
|
run_step.dependOn(&run_cmd.step);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn gen_version(b: *std.Build, writer: anytype) !void {
|
||||||
|
var code: u8 = 0;
|
||||||
|
|
||||||
|
const describe = try b.runAllowFail(&[_][]const u8{ "git", "describe", "--always", "--tags" }, &code, .Ignore);
|
||||||
|
const diff_ = try b.runAllowFail(&[_][]const u8{ "git", "diff", "--stat", "--patch", "HEAD" }, &code, .Ignore);
|
||||||
|
const diff = std.mem.trimRight(u8, diff_, "\r\n ");
|
||||||
|
const version = std.mem.trimRight(u8, describe, "\r\n ");
|
||||||
|
|
||||||
|
try writer.print("{s}{s}", .{ version, if (diff.len > 0) "-dirty" else "" });
|
||||||
|
}
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
.{
|
.{
|
||||||
.name = "zat",
|
.name = "zat",
|
||||||
.version = "0.0.1",
|
.version = "1.0.0",
|
||||||
.dependencies = .{
|
.dependencies = .{
|
||||||
.clap = .{
|
.clap = .{
|
||||||
.url = "https://github.com/Hejsil/zig-clap/archive/c0193e9247335a6c1688b946325060289405de2a.tar.gz",
|
.url = "https://github.com/Hejsil/zig-clap/archive/c0193e9247335a6c1688b946325060289405de2a.tar.gz",
|
||||||
.hash = "12207ee987ce045596cb992cfb15b0d6d9456e50d4721c3061c69dabc2962053644d",
|
.hash = "12207ee987ce045596cb992cfb15b0d6d9456e50d4721c3061c69dabc2962053644d",
|
||||||
},
|
},
|
||||||
.themes = .{
|
.themes = .{
|
||||||
.url = "https://github.com/neurocyte/flow-themes/releases/download/master-08c07e21c47abe41ebd16ee260438da5b4c2039e/flow-themes.tar.gz",
|
.url = "https://github.com/neurocyte/flow-themes/releases/download/master-618a7801d3383049adfe18cc09f5f5086c66995f/flow-themes.tar.gz",
|
||||||
.hash = "12202be270e675e3b61d96845baad143494539b167bcb8b1ef32659bf146dd85d3e1",
|
.hash = "1220019ed92f48fb94d4ae82bba17b11d0ba06f17ed31cd66613b3c048b1d2382095",
|
||||||
},
|
},
|
||||||
.syntax = .{
|
.syntax = .{
|
||||||
.url = "https://github.com/neurocyte/flow-syntax/archive/dcfa5cdf3f1f48411dc3c7ab8be26b7561673850.tar.gz",
|
.url = "https://github.com/neurocyte/flow-syntax/archive/28bc77f4615488aaa269c25fc862864f4b3a7460.tar.gz",
|
||||||
.hash = "1220ea88bb77cba3cf85caeb8002823218503c601f9907ccffbd41329c632596ebc3",
|
.hash = "1220abddc10ca8f8b6b5477f8c007948c168504b9dd3516899fe37251890eeabf4ab",
|
||||||
},
|
},
|
||||||
.thespian = .{
|
.thespian = .{
|
||||||
.url = "https://github.com/neurocyte/thespian/archive/d7dd27116398b17c8ab68327c384885f161d0cc1.tar.gz",
|
.url = "https://github.com/neurocyte/thespian/archive/d7dd27116398b17c8ab68327c384885f161d0cc1.tar.gz",
|
||||||
|
|
45
scripts/make_release
Executable file
45
scripts/make_release
Executable file
|
@ -0,0 +1,45 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
BASEDIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||||
|
APPNAME="$(basename "$BASEDIR")"
|
||||||
|
|
||||||
|
cd "$BASEDIR"
|
||||||
|
|
||||||
|
if [ -e "release" ]; then
|
||||||
|
echo directory \"release\" already exists
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo building...
|
||||||
|
|
||||||
|
./zig build -Dpackage_release --prefix release/build
|
||||||
|
|
||||||
|
cd release/build
|
||||||
|
|
||||||
|
VERSION=$(/bin/cat version)
|
||||||
|
TARGETS=$(/bin/ls)
|
||||||
|
|
||||||
|
for target in $TARGETS; do
|
||||||
|
if [ -d "$target" ]; then
|
||||||
|
cd "$target"
|
||||||
|
echo packing "$target"...
|
||||||
|
tar -czf "../../${APPNAME}-${VERSION}-${target}.tar.gz" -- *
|
||||||
|
cd ..
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
rm -r build
|
||||||
|
|
||||||
|
TARFILES=$(/bin/ls)
|
||||||
|
|
||||||
|
for tarfile in $TARFILES; do
|
||||||
|
echo signing "$tarfile"...
|
||||||
|
gpg --local-user 4E6CF7234FFC4E14531074F98EB1E1BB660E3FB9 --detach-sig "$tarfile"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "done making release $VERSION"
|
||||||
|
echo
|
||||||
|
|
||||||
|
/bin/ls -lah
|
|
@ -1,5 +1,6 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const cbor = @import("cbor");
|
const cbor = @import("cbor");
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
const application_name = "flow";
|
const application_name = "flow";
|
||||||
|
|
||||||
|
@ -48,18 +49,36 @@ pub fn get_config_dir() ![]const u8 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_app_config_dir(appname: []const u8) ![]const u8 {
|
fn get_app_config_dir(appname: []const u8) ![]const u8 {
|
||||||
|
const a = std.heap.c_allocator;
|
||||||
const local = struct {
|
const local = struct {
|
||||||
var config_dir_buffer: [std.posix.PATH_MAX]u8 = undefined;
|
var config_dir_buffer: [std.posix.PATH_MAX]u8 = undefined;
|
||||||
var config_dir: ?[]const u8 = null;
|
var config_dir: ?[]const u8 = null;
|
||||||
};
|
};
|
||||||
const config_dir = if (local.config_dir) |dir|
|
const config_dir = if (local.config_dir) |dir|
|
||||||
dir
|
dir
|
||||||
else if (std.posix.getenv("XDG_CONFIG_HOME")) |xdg|
|
else if (std.process.getEnvVarOwned(a, "XDG_CONFIG_HOME") catch null) |xdg| ret: {
|
||||||
try std.fmt.bufPrint(&local.config_dir_buffer, "{s}/{s}", .{ xdg, appname })
|
defer a.free(xdg);
|
||||||
else if (std.posix.getenv("HOME")) |home|
|
break :ret try std.fmt.bufPrint(&local.config_dir_buffer, "{s}/{s}", .{ xdg, appname });
|
||||||
try std.fmt.bufPrint(&local.config_dir_buffer, "{s}/.config/{s}", .{ home, appname })
|
} else if (std.process.getEnvVarOwned(a, "HOME") catch null) |home| ret: {
|
||||||
else
|
defer a.free(home);
|
||||||
return error.AppConfigDirUnavailable;
|
const dir = try std.fmt.bufPrint(&local.config_dir_buffer, "{s}/.config", .{home});
|
||||||
|
std.fs.makeDirAbsolute(dir) catch |e| switch (e) {
|
||||||
|
error.PathAlreadyExists => {},
|
||||||
|
else => return e,
|
||||||
|
};
|
||||||
|
break :ret try std.fmt.bufPrint(&local.config_dir_buffer, "{s}/.config/{s}", .{ home, appname });
|
||||||
|
} else if (builtin.os.tag == .windows) ret: {
|
||||||
|
if (std.process.getEnvVarOwned(a, "APPDATA") catch null) |appdata| {
|
||||||
|
defer a.free(appdata);
|
||||||
|
const dir = try std.fmt.bufPrint(&local.config_dir_buffer, "{s}/{s}", .{ appdata, appname });
|
||||||
|
std.fs.makeDirAbsolute(dir) catch |e| switch (e) {
|
||||||
|
error.PathAlreadyExists => {},
|
||||||
|
else => return e,
|
||||||
|
};
|
||||||
|
break :ret dir;
|
||||||
|
} else return error.AppConfigDirUnavailable;
|
||||||
|
} else return error.AppConfigDirUnavailable;
|
||||||
|
|
||||||
local.config_dir = config_dir;
|
local.config_dir = config_dir;
|
||||||
std.fs.makeDirAbsolute(config_dir) catch |e| switch (e) {
|
std.fs.makeDirAbsolute(config_dir) catch |e| switch (e) {
|
||||||
error.PathAlreadyExists => {},
|
error.PathAlreadyExists => {},
|
||||||
|
|
50
src/main.zig
50
src/main.zig
|
@ -20,6 +20,7 @@ pub fn main() !void {
|
||||||
\\-t, --theme <name> Select theme to use.
|
\\-t, --theme <name> Select theme to use.
|
||||||
\\-d, --default <name> Set the language to use if guessing failed (default: conf).
|
\\-d, --default <name> Set the language to use if guessing failed (default: conf).
|
||||||
\\-s, --show-language Show detected language in output.
|
\\-s, --show-language Show detected language in output.
|
||||||
|
\\-C, --color Always produce color output, even if stdout is not a tty.
|
||||||
\\--html Output HTML instead of ansi escape codes.
|
\\--html Output HTML instead of ansi escape codes.
|
||||||
\\--list-themes Show available themes.
|
\\--list-themes Show available themes.
|
||||||
\\--list-languages Show available language parsers.
|
\\--list-languages Show available language parsers.
|
||||||
|
@ -53,8 +54,9 @@ pub fn main() !void {
|
||||||
};
|
};
|
||||||
defer res.deinit();
|
defer res.deinit();
|
||||||
|
|
||||||
const stdout_file = std.io.getStdOut().writer();
|
const stdout_file = std.io.getStdOut();
|
||||||
var bw = std.io.bufferedWriter(stdout_file);
|
const stdout_writer = stdout_file.writer();
|
||||||
|
var bw = std.io.bufferedWriter(stdout_writer);
|
||||||
const writer = bw.writer();
|
const writer = bw.writer();
|
||||||
defer bw.flush() catch {};
|
defer bw.flush() catch {};
|
||||||
|
|
||||||
|
@ -67,6 +69,9 @@ pub fn main() !void {
|
||||||
if (res.args.@"list-languages" != 0)
|
if (res.args.@"list-languages" != 0)
|
||||||
return list_langs(writer);
|
return list_langs(writer);
|
||||||
|
|
||||||
|
if (res.args.color == 0 and !stdout_file.supportsAnsiEscapeCodes())
|
||||||
|
return plain_cat(res.positionals);
|
||||||
|
|
||||||
var conf_buf: ?[]const u8 = null;
|
var conf_buf: ?[]const u8 = null;
|
||||||
const conf = config_loader.read_config(a, &conf_buf);
|
const conf = config_loader.read_config(a, &conf_buf);
|
||||||
const theme_name = if (res.args.theme) |theme| theme else conf.theme;
|
const theme_name = if (res.args.theme) |theme| theme else conf.theme;
|
||||||
|
@ -103,7 +108,10 @@ pub fn main() !void {
|
||||||
|
|
||||||
if (res.positionals.len > 0) {
|
if (res.positionals.len > 0) {
|
||||||
for (res.positionals) |arg| {
|
for (res.positionals) |arg| {
|
||||||
const file = try std.fs.cwd().openFile(arg, .{ .mode = .read_only });
|
const file = if (std.mem.eql(u8, arg, "-"))
|
||||||
|
std.io.getStdIn()
|
||||||
|
else
|
||||||
|
try std.fs.cwd().openFile(arg, .{ .mode = .read_only });
|
||||||
defer file.close();
|
defer file.close();
|
||||||
const content = try file.readToEndAlloc(a, std.math.maxInt(u32));
|
const content = try file.readToEndAlloc(a, std.math.maxInt(u32));
|
||||||
defer a.free(content);
|
defer a.free(content);
|
||||||
|
@ -392,8 +400,8 @@ fn list_themes(writer: Writer) !void {
|
||||||
|
|
||||||
fn set_ansi_style(writer: Writer, style: Theme.Style) Writer.Error!void {
|
fn set_ansi_style(writer: Writer, style: Theme.Style) Writer.Error!void {
|
||||||
const ansi_style = .{
|
const ansi_style = .{
|
||||||
.foreground = if (style.fg) |color| to_rgb_color(color) else .Default,
|
.foreground = if (style.fg) |color| to_rgb_color(color.color) else .Default,
|
||||||
.background = if (style.bg) |color| to_rgb_color(color) else .Default,
|
.background = if (style.bg) |color| to_rgb_color(color.color) else .Default,
|
||||||
.font_style = switch (style.fs orelse .normal) {
|
.font_style = switch (style.fs orelse .normal) {
|
||||||
.normal => term.style.FontStyle{},
|
.normal => term.style.FontStyle{},
|
||||||
.bold => term.style.FontStyle.bold,
|
.bold => term.style.FontStyle.bold,
|
||||||
|
@ -409,8 +417,8 @@ fn set_ansi_style(writer: Writer, style: Theme.Style) Writer.Error!void {
|
||||||
const unset_ansi_style = set_ansi_style;
|
const unset_ansi_style = set_ansi_style;
|
||||||
|
|
||||||
fn write_html_preamble(writer: Writer, style: Theme.Style) !void {
|
fn write_html_preamble(writer: Writer, style: Theme.Style) !void {
|
||||||
const color = if (style.fg) |color| color else 0;
|
const color = if (style.fg) |color| color.color else 0;
|
||||||
const background = if (style.bg) |background| background else 0xFFFFFF;
|
const background = if (style.bg) |background| background.color else 0xFFFFFF;
|
||||||
try writer.writeAll("<div style=\"color:");
|
try writer.writeAll("<div style=\"color:");
|
||||||
try write_hex_color(writer, color);
|
try write_hex_color(writer, color);
|
||||||
try writer.writeAll(";background-color:");
|
try writer.writeAll(";background-color:");
|
||||||
|
@ -423,7 +431,7 @@ fn write_html_postamble(writer: Writer) !void {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_html_style(writer: Writer, style: Theme.Style) !void {
|
fn set_html_style(writer: Writer, style: Theme.Style) !void {
|
||||||
const color = if (style.fg) |color| color else 0;
|
const color = if (style.fg) |color| color.color else 0;
|
||||||
try writer.writeAll("<span style=\"color:");
|
try writer.writeAll("<span style=\"color:");
|
||||||
try write_hex_color(writer, color);
|
try write_hex_color(writer, color);
|
||||||
switch (style.fs orelse .normal) {
|
switch (style.fs orelse .normal) {
|
||||||
|
@ -466,7 +474,7 @@ fn render_file_type(writer: Writer, file_type: *const syntax.FileType, theme: *c
|
||||||
try set_ansi_style(writer, reversed);
|
try set_ansi_style(writer, reversed);
|
||||||
try writer.writeAll("");
|
try writer.writeAll("");
|
||||||
try set_ansi_style(writer, .{
|
try set_ansi_style(writer, .{
|
||||||
.fg = if (file_type.color == 0xFFFFFF or file_type.color == 0x000000) style.fg else file_type.color,
|
.fg = if (file_type.color == 0xFFFFFF or file_type.color == 0x000000) style.fg else .{ .color = file_type.color },
|
||||||
.bg = style.bg,
|
.bg = style.bg,
|
||||||
});
|
});
|
||||||
try writer.writeAll(file_type.icon);
|
try writer.writeAll(file_type.icon);
|
||||||
|
@ -478,3 +486,27 @@ fn render_file_type(writer: Writer, file_type: *const syntax.FileType, theme: *c
|
||||||
try set_ansi_style(writer, plain);
|
try set_ansi_style(writer, plain);
|
||||||
try writer.writeAll("\n");
|
try writer.writeAll("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn plain_cat(files: []const []const u8) !void {
|
||||||
|
const stdout = std.io.getStdOut();
|
||||||
|
if (files.len == 0) {
|
||||||
|
try plain_cat_file(stdout, "-");
|
||||||
|
} else {
|
||||||
|
for (files) |file| try plain_cat_file(stdout, file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn plain_cat_file(out_file: std.fs.File, in_file_name: []const u8) !void {
|
||||||
|
var in_file = if (std.mem.eql(u8, in_file_name, "-"))
|
||||||
|
std.io.getStdIn()
|
||||||
|
else
|
||||||
|
try std.fs.cwd().openFile(in_file_name, .{});
|
||||||
|
defer in_file.close();
|
||||||
|
|
||||||
|
var buf: [std.mem.page_size]u8 = undefined;
|
||||||
|
while (true) {
|
||||||
|
const bytes_read = try in_file.read(&buf);
|
||||||
|
if (bytes_read == 0) return;
|
||||||
|
try out_file.writeAll(buf[0..bytes_read]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue