Skip to content
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.zig-cache/
zig-out/
zig-pkg/
.vscode/
.dim-out/
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 = "git+https://github.com/ZigEmbeddedGroup/zfat.git#0571b0d8c8cc4fcb037a1d5e7ea5666cb2f83ddf",
.hash = "zfat-0.15.0-SNNK9RRqcgCLQ5mjXghbB6mokzcHORsGnY7GtbfOt2k3",
.url = "git+https://github.com/khitiara/zfat?ref=0.15#4ce2a6a95d4410573dcc1c159085f554465aea04",
.hash = "zfat-0.15.0-SNNK9QCZcgBdWwpwf_lzSuKP12w2HZQnIQwT4qn8TfZi",
},
.args = .{
.url = "git+https://github.com/ikskuh/zig-args.git#8ae26b44a884ff20dca98ee84c098e8f8e94902f",
.hash = "args-0.0.0-CiLiqojRAACGzDRO7A9dw7kWSchNk29caJZkXuMCb0Cn",
.url = "git+https://github.com/khitiara/zig-args#4085c9be55dfd2eeb6893694510a2ce97e89f9fe",
.hash = "args-0.0.0-CiLiqiLSAAArS0NVwnYLAarU-u1csj8zAkg5-q4pa1n8",
},
},
.paths = .{
Expand Down
48 changes: 28 additions & 20 deletions src/BuildInterface.zig
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,20 @@ pub fn createDisk(dimmer: Interface, size: u64, content: Content) std.Build.Lazy

const write_files = b.addWriteFiles();

const script_source, const variables = renderContent(write_files, b.allocator, content);
const script_source, const variables = renderContent(write_files, b.allocator, content, dimmer.builder.graph.io);

const script_file = write_files.add("image.dis", script_source);

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}));

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

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

Expand Down Expand Up @@ -67,6 +69,7 @@ fn renderContent(
wfs: *std.Build.Step.WriteFile,
allocator: std.mem.Allocator,
content: Content,
io: std.Io,
) struct { []const u8, ContentWriter.VariableMap } {
var code: std.Io.Writer.Allocating = .init(allocator);
defer code.deinit();
Expand All @@ -79,7 +82,7 @@ fn renderContent(
.vars = &variables,
};

cw.render(content) catch @panic("out of memory");
cw.render(content, io) catch @panic("out of memory");

const source = std.mem.trim(
u8,
Expand Down Expand Up @@ -107,7 +110,7 @@ const ContentWriter = struct {
code: *std.Io.Writer,
vars: *VariableMap,

fn render(cw: ContentWriter, content: Content) !void {
fn render(cw: ContentWriter, content: Content, io: std.Io) !void {
// Always insert some padding before and after:
try cw.code.writeAll(" ");
errdefer cw.code.writeAll(" ") catch {};
Expand All @@ -122,15 +125,15 @@ const ContentWriter = struct {
},

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

.mbr_part_table => |data| {
try cw.code.writeAll("mbr-part\n");

if (data.bootloader) |loader| {
try cw.code.writeAll(" bootloader ");
try cw.render(loader.*);
try cw.render(loader.*, io);
try cw.code.writeAll("\n");
}

Expand All @@ -151,7 +154,7 @@ const ContentWriter = struct {
try cw.code.print(" size {d}\n", .{size});
}
try cw.code.writeAll(" contains");
try cw.render(part.data);
try cw.render(part.data, io);
try cw.code.writeAll("\n");
try cw.code.writeAll(" endpart\n");
} else {
Expand Down Expand Up @@ -183,14 +186,17 @@ const ContentWriter = struct {
if (part.name) |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});
}
if (part.size) |size| {
try cw.code.print(" size {d}\n", .{size});
}
try cw.code.writeAll(" contains");
try cw.render(part.data);
try cw.render(part.data, io);
try cw.code.writeAll("\n");
try cw.code.writeAll(" endpart\n");
}
Expand All @@ -208,14 +214,14 @@ const ContentWriter = struct {
});
}

try cw.renderFileSystemTree(data.tree);
try cw.renderFileSystemTree(data.tree, io);

try cw.code.writeAll("endfat\n");
},
}
}

fn renderFileSystemTree(cw: ContentWriter, fs: FileSystem) !void {
fn renderFileSystemTree(cw: ContentWriter, fs: FileSystem, io: std.Io) !void {
for (fs.items) |item| {
switch (item) {
.empty_dir => |dir| try cw.code.print("mkdir {f}\n", .{
Expand All @@ -224,16 +230,16 @@ const ContentWriter = struct {

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

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

.include_script => |script| try cw.code.print("!include {f}\n", .{
cw.fmtLazyPath(script, .file),
cw.fmtLazyPath(script, .file, io),
}),
}
}
Expand Down Expand Up @@ -280,7 +286,7 @@ const ContentWriter = struct {
}
};
const LazyPathFormatter = std.fmt.Alt(
struct { ContentWriter, std.Build.LazyPath, UsageHint },
struct { ContentWriter, std.Build.LazyPath, UsageHint, std.Io },
formatLazyPath,
);
const UsageHint = enum { file, directory };
Expand All @@ -289,19 +295,20 @@ const ContentWriter = struct {
cw: ContentWriter,
path: std.Build.LazyPath,
hint: UsageHint,
io: std.Io,
) LazyPathFormatter {
return .{ .data = .{ cw, path, hint } };
return .{ .data = .{ cw, path, hint, io } };
}

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

fn formatLazyPath(
data: struct { ContentWriter, std.Build.LazyPath, UsageHint },
data: struct { ContentWriter, std.Build.LazyPath, UsageHint, std.Io },
writer: *std.Io.Writer,
) std.Io.Writer.Error!void {
const cw, const path, const hint = data;
const cw, const path, const hint, const io = data;

switch (path) {
.cwd_relative,
Expand All @@ -314,12 +321,12 @@ const ContentWriter = struct {
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")
std.Io.Dir.cwd().realPathFileAlloc(io, rel_path, cw.wfs.step.owner.allocator) 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");
const cwd = std.Io.Dir.cwd().realPathFileAlloc(io, ".", 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),
Expand Down Expand Up @@ -414,6 +421,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 @@ -439,7 +447,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.array_list.Managed(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
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