Skip to content
Draft
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
10 changes: 6 additions & 4 deletions build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
.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/CascadeOS/zfat#2806bfd983dd810c9c74b0ea6a63f783208518b5",
// .hash = "zfat-0.16.0-SNNK9fKtTgASssfmCblZwRMLU4pndVtwxTNhYCegBOyA",
.path = "../zfat",
},
.args = .{
.url = "git+https://github.com/ikskuh/zig-args.git#9425b94c103a031777fdd272c555ce93a7dea581",
.hash = "args-0.0.0-CiLiqv_NAAC97fGpk9hS2K681jkiqPsWP6w3ucb_ctGH",
.path = "../zig-args",
// .url = "git+https://github.com/ikskuh/zig-args.git#8ae26b44a884ff20dca98ee84c098e8f8e94902f",
// .hash = "args-0.0.0-CiLiqojRAACGzDRO7A9dw7kWSchNk29caJZkXuMCb0Cn",
},
},
.paths = .{
Expand Down
57 changes: 27 additions & 30 deletions src/BuildInterface.zig
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ pub fn createDisk(dimmer: Interface, size: u64, content: Content) std.Build.Lazy

const compile_script = b.addRunArtifact(dimmer.dimmer_exe);

compile_script.setCwd(script_file.dirname());

_ = compile_script.addPrefixedDepFileOutputArg("--deps-file=", "image.d");

compile_script.addArg(b.fmt("--size={d}", .{size}));
Expand Down Expand Up @@ -63,13 +65,13 @@ pub fn createDisk(dimmer: Interface, size: u64, content: Content) std.Build.Lazy
}

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);
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 +101,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 +119,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 +160,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 +178,10 @@ 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.part_guid) |pg| {
try cw.code.print(" guid \"{s}\"", .{&pg});
}
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,29 +218,29 @@ 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 = std.fmt.Alt([]const u8, formatPath);
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 {
Expand All @@ -248,13 +253,9 @@ const ContentWriter = struct {

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

switch (path) {
.cwd_relative,
Expand All @@ -267,7 +268,7 @@ const ContentWriter = struct {

std.debug.assert(std.fs.path.isAbsolute(full_path));

try writer.print("{}", .{
try writer.print("{f}", .{
fmtPath(full_path),
});
},
Expand All @@ -278,7 +279,7 @@ 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});
},
Expand All @@ -287,13 +288,8 @@ const ContentWriter = struct {

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

const is_safe_word = for (path) |char| {
switch (char) {
'A'...'Z',
Expand All @@ -318,7 +314,7 @@ const ContentWriter = struct {
if (c == '\\') {
try writer.writeAll("/");
} else {
try writer.print("{}", .{std.zig.fmtEscapes(&[_]u8{c})});
try writer.print("{f}", .{std.zig.fmtString(&[_]u8{c})});
}
}

Expand Down Expand Up @@ -385,7 +381,7 @@ pub const GptPartTable = struct {
@"microsoft-basic-data",
@"microsoft-reserved",
@"windows-recovery",
@"plan9",
plan9,
@"linux-swap",
@"linux-fs",
@"linux-reserved",
Expand All @@ -394,6 +390,7 @@ pub const GptPartTable = struct {
guid: [36]u8,
},
name: ?[]const u8 = null,
part_guid: ?[36]u8 = null,
size: ?u64 = null,
offset: ?u64 = null,
data: Content,
Expand All @@ -419,7 +416,7 @@ pub const FatFs = struct {

pub const FileSystemBuilder = struct {
b: *std.Build,
list: std.ArrayListUnmanaged(FileSystem.Item),
list: std.ArrayList(FileSystem.Item),

pub fn init(b: *std.Build) FileSystemBuilder {
return FileSystemBuilder{
Expand Down
59 changes: 31 additions & 28 deletions src/Parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,19 @@ pub const Error = Tokenizer.Error || error{
UnknownDirective,
OutOfMemory,
InvalidEscapeSequence,
Canceled,
};

pub const IO = struct {
fetch_file_fn: *const fn (io: *const IO, std.mem.Allocator, path: []const u8) error{ FileNotFound, IoError, OutOfMemory, InvalidPath }![]const u8,
resolve_variable_fn: *const fn (io: *const IO, name: []const u8) error{UnknownVariable}![]const u8,
fetch_file_fn: *const fn (stdio: std.Io, io: *const IO, std.mem.Allocator, path: []const u8) error{ FileNotFound, IoError, OutOfMemory, InvalidPath, Canceled }![]const u8,
resolve_variable_fn: *const fn (stdio: std.Io, io: *const IO, name: []const u8) error{UnknownVariable}![]const u8,

pub fn fetch_file(io: *const IO, allocator: std.mem.Allocator, path: []const u8) error{ FileNotFound, IoError, OutOfMemory, InvalidPath }![]const u8 {
return io.fetch_file_fn(io, allocator, path);
pub fn fetch_file(io: *const IO, stdio: std.Io, allocator: std.mem.Allocator, path: []const u8) error{ FileNotFound, IoError, OutOfMemory, InvalidPath, Canceled }![]const u8 {
return io.fetch_file_fn(stdio,io, allocator, path);
}

pub fn resolve_variable(io: *const IO, name: []const u8) error{UnknownVariable}![]const u8 {
return io.resolve_variable_fn(io, name);
pub fn resolve_variable(io: *const IO, stdio: std.Io, name: []const u8) error{UnknownVariable}![]const u8 {
return io.resolve_variable_fn(stdio,io, name);
}
};

Expand Down Expand Up @@ -84,10 +85,10 @@ pub fn push_source(parser: *Parser, options: struct {
};
}

pub fn push_file(parser: *Parser, include_path: []const u8) !void {
pub fn push_file(parser: *Parser, stdio: std.Io, include_path: []const u8) !void {
const abs_include_path = try parser.get_include_path(parser.arena.allocator(), include_path);

const file_contents = try parser.io.fetch_file(parser.arena.allocator(), abs_include_path);
const file_contents = try parser.io.fetch_file(stdio , parser.arena.allocator(), abs_include_path);

const index = parser.file_stack.len;
parser.file_stack.len += 1;
Expand Down Expand Up @@ -120,14 +121,14 @@ pub fn get_include_path(parser: Parser, allocator: std.mem.Allocator, rel_includ
return abs_include_path;
}

pub fn next(parser: *Parser) (Error || error{UnexpectedEndOfFile})![]const u8 {
return if (try parser.next_or_eof()) |word|
pub fn next(parser: *Parser, stdio: std.Io) (Error || error{UnexpectedEndOfFile})![]const u8 {
return if (try parser.next_or_eof(stdio)) |word|
word
else
error.UnexpectedEndOfFile;
}

pub fn next_or_eof(parser: *Parser) Error!?[]const u8 {
pub fn next_or_eof(parser: *Parser, stdio: std.Io) Error!?[]const u8 {
fetch_loop: while (parser.file_stack.len > 0) {
const top = &parser.file_stack[parser.file_stack.len - 1];

Expand All @@ -141,7 +142,7 @@ pub fn next_or_eof(parser: *Parser) Error!?[]const u8 {
switch (token.type) {
.whitespace, .comment => unreachable,

.word, .variable, .string => return try parser.resolve_value(
.word, .variable, .string => return try parser.resolve_value(stdio,
token.type,
top.tokenizer.get_text(token),
),
Expand All @@ -152,14 +153,14 @@ pub fn next_or_eof(parser: *Parser) Error!?[]const u8 {
if (std.mem.eql(u8, directive, "!include")) {
if (try fetch_token(&top.tokenizer)) |path_token| {
const rel_include_path = switch (path_token.type) {
.word, .variable, .string => try parser.resolve_value(
.word, .variable, .string => try parser.resolve_value(stdio,
path_token.type,
top.tokenizer.get_text(path_token),
),
.comment, .directive, .whitespace => return error.BadDirective,
};

try parser.push_file(rel_include_path);
try parser.push_file(stdio, rel_include_path);
} else {
return error.ExpectedIncludePath;
}
Expand Down Expand Up @@ -189,11 +190,11 @@ fn fetch_token(tok: *Tokenizer) Tokenizer.Error!?Token {
}
}

fn resolve_value(parser: *Parser, token_type: TokenType, text: []const u8) ![]const u8 {
fn resolve_value(parser: *Parser, stdio: std.Io, token_type: TokenType, text: []const u8) ![]const u8 {
return switch (token_type) {
.word => text,

.variable => try parser.io.resolve_variable(
.variable => try parser.io.resolve_variable(stdio,
text[1..],
),

Expand All @@ -208,10 +209,12 @@ 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());
defer unescaped.deinit();
const allocator = parser.arena.allocator();

try unescaped.ensureTotalCapacityPrecise(content_slice.len);
var unescaped = std.ArrayList(u8).empty;
defer unescaped.deinit(allocator);

try unescaped.ensureTotalCapacityPrecise(allocator, content_slice.len);

{
var i: usize = 0;
Expand All @@ -220,7 +223,7 @@ fn resolve_value(parser: *Parser, token_type: TokenType, text: []const u8) ![]co
i += 1;

if (c != '\\') {
try unescaped.append(c);
try unescaped.append(allocator, c);
continue;
}

Expand All @@ -233,20 +236,20 @@ fn resolve_value(parser: *Parser, token_type: TokenType, text: []const u8) ![]co
errdefer std.log.err("invalid escape sequence: \\{s}", .{[_]u8{esc_code}});

switch (esc_code) {
'r' => try unescaped.append('\r'),
'n' => try unescaped.append('\n'),
't' => try unescaped.append('\t'),
'\\' => try unescaped.append('\\'),
'\"' => try unescaped.append('\"'),
'\'' => try unescaped.append('\''),
'e' => try unescaped.append('\x1B'),
'r' => try unescaped.append(allocator, '\r'),
'n' => try unescaped.append(allocator, '\n'),
't' => try unescaped.append(allocator, '\t'),
'\\' => try unescaped.append(allocator, '\\'),
'\"' => try unescaped.append(allocator, '\"'),
'\'' => try unescaped.append(allocator, '\''),
'e' => try unescaped.append(allocator, '\x1B'),

else => return error.InvalidEscapeSequence,
}
}
}

return try unescaped.toOwnedSlice();
return try unescaped.toOwnedSlice(allocator);
},

.comment, .directive, .whitespace => unreachable,
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
6 changes: 4 additions & 2 deletions src/components/EmptyData.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ const dim = @import("../dim.zig");

const EmptyData = @This();

pub fn parse(ctx: dim.Context) !dim.Content {
pub fn parse(ctx: dim.Context, stdio: std.Io) !dim.Content {
_ = ctx;
_ = stdio;
return .create_handle(undefined, .create(@This(), .{
.render_fn = render,
}));
}

fn render(self: *EmptyData, stream: *dim.BinaryStream) dim.Content.RenderError!void {
fn render(self: *EmptyData, io: std.Io, stream: *dim.BinaryStream) dim.Content.RenderError!void {
_ = self;
_ = stream;
_ = io;
}
Loading
Loading