Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ jobs:
uses: actions/checkout@v2

- name: Setup Zig
uses: mlugg/setup-zig@v1
uses: mlugg/setup-zig@v2
with:
version: 0.14.0
version: 0.15.2

- name: Basic Build
run: |
Expand Down
9 changes: 7 additions & 2 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ pub fn build(b: *std.Build) void {
.mkfs = true,
.exfat = true,
.label = true,
.target = target,
.optimize = optimize,
});

const zfat_mod = zfat_dep.module("zfat");
Expand All @@ -30,9 +32,11 @@ pub fn build(b: *std.Build) void {
.target = target,
.optimize = optimize,
.link_libc = true,
.imports = &.{
.{ .name = "args", .module = args_mod },
.{ .name = "zfat", .module = zfat_mod },
},
});
dim_mod.addImport("args", args_mod);
dim_mod.addImport("zfat", zfat_mod);

const dim_exe = b.addExecutable(.{
.name = "dimmer",
Expand All @@ -53,6 +57,7 @@ pub fn build(b: *std.Build) void {
const script_test = b.step(step_name, b.fmt("Run {s} behaviour test", .{script}));

const run_behaviour = b.addRunArtifact(dim_exe);
run_behaviour.setCwd(b.path(script).dirname());
run_behaviour.addArg("--output");
_ = run_behaviour.addOutputFileArg("disk.img");
run_behaviour.addArg("--script");
Expand Down
8 changes: 4 additions & 4 deletions build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
.fingerprint = 0x9947018c924eecb2,
.dependencies = .{
.zfat = .{
.url = "https://github.com/ZigEmbeddedGroup/zfat/archive/3ce06d43a4e04d387034dcae2f486b050701f321.tar.gz",
.hash = "zfat-0.0.0-AAAAAMYlcABdh06Mn9CNk8Ccy_3bBFgJr8wo4jKza1q-",
.url = "git+https://github.com/ZigEmbeddedGroup/zfat.git#0571b0d8c8cc4fcb037a1d5e7ea5666cb2f83ddf",
.hash = "zfat-0.15.0-SNNK9RRqcgCLQ5mjXghbB6mokzcHORsGnY7GtbfOt2k3",
},
.args = .{
.url = "git+https://github.com/ikskuh/zig-args.git#9425b94c103a031777fdd272c555ce93a7dea581",
.hash = "args-0.0.0-CiLiqv_NAAC97fGpk9hS2K681jkiqPsWP6w3ucb_ctGH",
.url = "git+https://github.com/ikskuh/zig-args.git#8ae26b44a884ff20dca98ee84c098e8f8e94902f",
.hash = "args-0.0.0-CiLiqojRAACGzDRO7A9dw7kWSchNk29caJZkXuMCb0Cn",
},
},
.paths = .{
Expand Down
158 changes: 89 additions & 69 deletions src/BuildInterface.zig
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub fn createDisk(dimmer: Interface, size: u64, content: Content) std.Build.Lazy
compile_script.addArg(b.fmt("--size={d}", .{size}));

compile_script.addPrefixedFileArg("--script=", script_file);
compile_script.addPrefixedDirectoryArg("--script-root=", .{ .cwd_relative = "." });

const result_file = compile_script.addPrefixedOutputFileArg("--output=", "disk.img");

Expand All @@ -62,14 +63,18 @@ pub fn createDisk(dimmer: Interface, size: u64, content: Content) std.Build.Lazy
return result_file;
}

fn renderContent(wfs: *std.Build.Step.WriteFile, allocator: std.mem.Allocator, content: Content) struct { []const u8, ContentWriter.VariableMap } {
var code: std.ArrayList(u8) = .init(allocator);
fn renderContent(
wfs: *std.Build.Step.WriteFile,
allocator: std.mem.Allocator,
content: Content,
) struct { []const u8, ContentWriter.VariableMap } {
var code: std.Io.Writer.Allocating = .init(allocator);
defer code.deinit();

var variables: ContentWriter.VariableMap = .init(allocator);

var cw: ContentWriter = .{
.code = code.writer(),
.code = &code.writer,
.wfs = wfs,
.vars = &variables,
};
Expand Down Expand Up @@ -99,7 +104,7 @@ const ContentWriter = struct {
pub const VariableMap = std.StringArrayHashMap(struct { std.Build.LazyPath, ContentWriter.UsageHint });

wfs: *std.Build.Step.WriteFile,
code: std.ArrayList(u8).Writer,
code: *std.Io.Writer,
vars: *VariableMap,

fn render(cw: ContentWriter, content: Content) !void {
Expand All @@ -117,7 +122,7 @@ const ContentWriter = struct {
},

.paste_file => |data| {
try cw.code.print("paste-file {}", .{cw.fmtLazyPath(data, .file)});
try cw.code.print("paste-file {f}", .{cw.fmtLazyPath(data, .file)});
},

.mbr_part_table => |data| {
Expand Down Expand Up @@ -158,7 +163,7 @@ const ContentWriter = struct {
.gpt_part_table => |data| {
try cw.code.writeAll("gpt-part\n");

if(data.legacy_bootable) {
if (data.legacy_bootable) {
try cw.code.writeAll(" legacy-bootable\n");
}

Expand All @@ -176,7 +181,7 @@ const ContentWriter = struct {
try cw.code.writeByte('\n');

if (part.name) |name| {
try cw.code.print(" name \"{}\"\n", .{std.zig.fmtEscapes(name)});
try cw.code.print(" name \"{f}\"\n", .{std.zig.fmtString(name)});
}
if (part.offset) |offset| {
try cw.code.print(" offset {d}\n", .{offset});
Expand All @@ -198,7 +203,7 @@ const ContentWriter = struct {
@tagName(data.format),
});
if (data.label) |label| {
try cw.code.print(" label {}\n", .{
try cw.code.print(" label {f}\n", .{
fmtPath(label),
});
}
Expand All @@ -213,61 +218,117 @@ const ContentWriter = struct {
fn renderFileSystemTree(cw: ContentWriter, fs: FileSystem) !void {
for (fs.items) |item| {
switch (item) {
.empty_dir => |dir| try cw.code.print("mkdir {}\n", .{
.empty_dir => |dir| try cw.code.print("mkdir {f}\n", .{
fmtPath(dir),
}),

.copy_dir => |copy| try cw.code.print("copy-dir {} {}\n", .{
.copy_dir => |copy| try cw.code.print("copy-dir {f} {f}\n", .{
fmtPath(copy.destination),
cw.fmtLazyPath(copy.source, .directory),
}),

.copy_file => |copy| try cw.code.print("copy-file {} {}\n", .{
.copy_file => |copy| try cw.code.print("copy-file {f} {f}\n", .{
fmtPath(copy.destination),
cw.fmtLazyPath(copy.source, .file),
}),

.include_script => |script| try cw.code.print("!include {}\n", .{
.include_script => |script| try cw.code.print("!include {f}\n", .{
cw.fmtLazyPath(script, .file),
}),
}
}
}

const PathFormatter = std.fmt.Formatter(formatPath);
const LazyPathFormatter = std.fmt.Formatter(formatLazyPath);
const PathFormatter = struct {
path: []const u8,

pub fn format(
p: PathFormatter,
writer: *std.Io.Writer,
) std.Io.Writer.Error!void {
const path = p.path;
const is_safe_word = for (path) |char| {
switch (char) {
'A'...'Z',
'a'...'z',
'0'...'9',
'_',
'-',
'/',
'.',
':',
=> {},
else => break false,
}
} else true;

if (is_safe_word) {
try writer.writeAll(path);
} else {
try writer.writeAll("\"");

for (path) |c| {
if (c == '\\') {
try writer.writeAll("/");
} else {
try writer.print("{f}", .{std.zig.fmtString(&[_]u8{c})});
}
}

try writer.writeAll("\"");
}
}
};
const LazyPathFormatter = std.fmt.Alt(
struct { ContentWriter, std.Build.LazyPath, UsageHint },
formatLazyPath,
);
const UsageHint = enum { file, directory };

fn fmtLazyPath(cw: ContentWriter, path: std.Build.LazyPath, hint: UsageHint) LazyPathFormatter {
fn fmtLazyPath(
cw: ContentWriter,
path: std.Build.LazyPath,
hint: UsageHint,
) LazyPathFormatter {
return .{ .data = .{ cw, path, hint } };
}

fn fmtPath(path: []const u8) PathFormatter {
return .{ .data = path };
return .{ .path = path };
}

fn formatLazyPath(
data: struct { ContentWriter, std.Build.LazyPath, UsageHint },
comptime fmt: []const u8,
options: std.fmt.FormatOptions,
writer: anytype,
) !void {
writer: *std.Io.Writer,
) std.Io.Writer.Error!void {
const cw, const path, const hint = data;
_ = fmt;
_ = options;

switch (path) {
.cwd_relative,
.dependency,
.src_path,
=> {

// We can safely call getPath2 as we can fully resolve the path
// already
const full_path = path.getPath2(cw.wfs.step.owner, &cw.wfs.step);

std.debug.assert(std.fs.path.isAbsolute(full_path));
const rel_path = path.getPath2(cw.wfs.step.owner, &cw.wfs.step);

const full_path = if (!std.fs.path.isAbsolute(rel_path))
std.fs.cwd().realpathAlloc(cw.wfs.step.owner.allocator, rel_path) catch @panic("oom")
else
rel_path;

if (!std.fs.path.isAbsolute(full_path)) {
const cwd = std.fs.cwd().realpathAlloc(cw.wfs.step.owner.allocator, ".") catch @panic("oom");
std.debug.print("non-absolute path detected for {t}: cwd=\"{f}\" path=\"{f}\"\n", .{
path,
std.zig.fmtString(cwd),
std.zig.fmtString(full_path),
});
@panic("non-absolute path detected!");
}

try writer.print("{}", .{
try writer.print("{f}", .{
fmtPath(full_path),
});
},
Expand All @@ -278,53 +339,12 @@ const ContentWriter = struct {
const var_id = cw.vars.count() + 1;
const var_name = cw.wfs.step.owner.fmt("PATH{}", .{var_id});

try cw.vars.put(var_name, .{ path, hint });
cw.vars.put(var_name, .{ path, hint }) catch return error.WriteFailed;

try writer.print("${s}", .{var_name});
},
}
}

fn formatPath(
path: []const u8,
comptime fmt: []const u8,
options: std.fmt.FormatOptions,
writer: anytype,
) !void {
_ = fmt;
_ = options;

const is_safe_word = for (path) |char| {
switch (char) {
'A'...'Z',
'a'...'z',
'0'...'9',
'_',
'-',
'/',
'.',
':',
=> {},
else => break false,
}
} else true;

if (is_safe_word) {
try writer.writeAll(path);
} else {
try writer.writeAll("\"");

for (path) |c| {
if (c == '\\') {
try writer.writeAll("/");
} else {
try writer.print("{}", .{std.zig.fmtEscapes(&[_]u8{c})});
}
}

try writer.writeAll("\"");
}
}
};

pub const Content = union(enum) {
Expand Down Expand Up @@ -385,7 +405,7 @@ pub const GptPartTable = struct {
@"microsoft-basic-data",
@"microsoft-reserved",
@"windows-recovery",
@"plan9",
plan9,
@"linux-swap",
@"linux-fs",
@"linux-reserved",
Expand Down
2 changes: 1 addition & 1 deletion src/Parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ fn resolve_value(parser: *Parser, token_type: TokenType, text: []const u8) ![]co
if (!has_includes)
return content_slice;

var unescaped: std.ArrayList(u8) = .init(parser.arena.allocator());
var unescaped: std.array_list.Managed(u8) = .init(parser.arena.allocator());
defer unescaped.deinit();

try unescaped.ensureTotalCapacityPrecise(content_slice.len);
Expand Down
4 changes: 2 additions & 2 deletions src/Tokenizer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,9 @@ test Tokenizer {
var offset: u32 = 0;
for (seq) |expected| {
const actual = (try tokenizer.next()) orelse return error.Unexpected;
errdefer std.debug.print("unexpected token: .{} \"{}\"\n", .{
errdefer std.debug.print("unexpected token: .{f} \"{f}\"\n", .{
std.zig.fmtId(@tagName(actual.type)),
std.zig.fmtEscapes(tokenizer.source[actual.offset..][0..actual.len]),
std.zig.fmtString(tokenizer.source[actual.offset..][0..actual.len]),
});
try std.testing.expectEqualStrings(expected.@"1", tokenizer.get_text(actual));
try std.testing.expectEqual(offset, actual.offset);
Expand Down
Loading
Loading