Commit 8d80d67693
Changed files (6)
lib
compiler
aro
lib/compiler/aro/aro/Compilation.zig
@@ -537,8 +537,15 @@ pub fn generateBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefi
var allocating: std.Io.Writer.Allocating = .init(comp.gpa);
defer allocating.deinit();
- const buf = &allocating.writer;
+ generateBuiltinMacrosWriter(comp, system_defines_mode, &allocating.writer) catch |err| switch (err) {
+ error.WriteFailed => return error.OutOfMemory,
+ else => |e| return e,
+ };
+ return comp.addSourceFromBuffer("<builtin>", allocating.written());
+}
+
+pub fn generateBuiltinMacrosWriter(comp: *Compilation, system_defines_mode: SystemDefinesMode, buf: *Writer) !void {
if (system_defines_mode == .include_system_defines) {
try buf.writeAll(
\\#define __VERSION__ "Aro
@@ -576,8 +583,6 @@ pub fn generateBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefi
if (system_defines_mode == .include_system_defines) {
try comp.generateSystemDefines(buf);
}
-
- return comp.addSourceFromBuffer("<builtin>", allocating.written());
}
fn generateFloatMacros(w: *Writer, prefix: []const u8, semantics: target_util.FPSemantics, ext: []const u8) !void {
lib/compiler/resinator/cli.zig
@@ -520,8 +520,7 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
// - or / on its own is an error
else => {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = arg.optionAndAfterSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("invalid option: {s}", .{arg.prefixSlice()});
+ try err_details.msg.print(allocator, "invalid option: {s}", .{arg.prefixSlice()});
try diagnostics.append(err_details);
arg_i += 1;
continue :next_arg;
@@ -532,8 +531,7 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
const args_remaining = args.len - arg_i;
if (args_remaining <= 2 and arg.looksLikeFilepath()) {
var err_details = Diagnostics.ErrorDetails{ .type = .note, .print_args = true, .arg_index = arg_i };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.writeAll("this argument was inferred to be a filepath, so argument parsing was terminated");
+ try err_details.msg.appendSlice(allocator, "this argument was inferred to be a filepath, so argument parsing was terminated");
try diagnostics.append(err_details);
break;
@@ -550,16 +548,14 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
} else if (std.ascii.startsWithIgnoreCase(arg_name, ":output-format")) {
const value = arg.value(":output-format".len, arg_i, args) catch {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = arg.missingSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("missing value after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(":output-format".len) });
+ try err_details.msg.print(allocator, "missing value after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(":output-format".len) });
try diagnostics.append(err_details);
arg_i += 1;
break :next_arg;
};
output_format = std.meta.stringToEnum(Options.OutputFormat, value.slice) orelse blk: {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = value.argSpan(arg) };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("invalid output format setting: {s} ", .{value.slice});
+ try err_details.msg.print(allocator, "invalid output format setting: {s} ", .{value.slice});
try diagnostics.append(err_details);
break :blk output_format;
};
@@ -569,16 +565,14 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
} else if (std.ascii.startsWithIgnoreCase(arg_name, ":auto-includes")) {
const value = arg.value(":auto-includes".len, arg_i, args) catch {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = arg.missingSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("missing value after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(":auto-includes".len) });
+ try err_details.msg.print(allocator, "missing value after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(":auto-includes".len) });
try diagnostics.append(err_details);
arg_i += 1;
break :next_arg;
};
options.auto_includes = std.meta.stringToEnum(Options.AutoIncludes, value.slice) orelse blk: {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = value.argSpan(arg) };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("invalid auto includes setting: {s} ", .{value.slice});
+ try err_details.msg.print(allocator, "invalid auto includes setting: {s} ", .{value.slice});
try diagnostics.append(err_details);
break :blk options.auto_includes;
};
@@ -587,16 +581,14 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
} else if (std.ascii.startsWithIgnoreCase(arg_name, ":input-format")) {
const value = arg.value(":input-format".len, arg_i, args) catch {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = arg.missingSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("missing value after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(":input-format".len) });
+ try err_details.msg.print(allocator, "missing value after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(":input-format".len) });
try diagnostics.append(err_details);
arg_i += 1;
break :next_arg;
};
input_format = std.meta.stringToEnum(Options.InputFormat, value.slice) orelse blk: {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = value.argSpan(arg) };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("invalid input format setting: {s} ", .{value.slice});
+ try err_details.msg.print(allocator, "invalid input format setting: {s} ", .{value.slice});
try diagnostics.append(err_details);
break :blk input_format;
};
@@ -606,16 +598,14 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
} else if (std.ascii.startsWithIgnoreCase(arg_name, ":depfile-fmt")) {
const value = arg.value(":depfile-fmt".len, arg_i, args) catch {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = arg.missingSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("missing value after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(":depfile-fmt".len) });
+ try err_details.msg.print(allocator, "missing value after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(":depfile-fmt".len) });
try diagnostics.append(err_details);
arg_i += 1;
break :next_arg;
};
options.depfile_fmt = std.meta.stringToEnum(Options.DepfileFormat, value.slice) orelse blk: {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = value.argSpan(arg) };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("invalid depfile format setting: {s} ", .{value.slice});
+ try err_details.msg.print(allocator, "invalid depfile format setting: {s} ", .{value.slice});
try diagnostics.append(err_details);
break :blk options.depfile_fmt;
};
@@ -624,8 +614,7 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
} else if (std.ascii.startsWithIgnoreCase(arg_name, ":depfile")) {
const value = arg.value(":depfile".len, arg_i, args) catch {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = arg.missingSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("missing value after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(":depfile".len) });
+ try err_details.msg.print(allocator, "missing value after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(":depfile".len) });
try diagnostics.append(err_details);
arg_i += 1;
break :next_arg;
@@ -643,8 +632,7 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
} else if (std.ascii.startsWithIgnoreCase(arg_name, ":target")) {
const value = arg.value(":target".len, arg_i, args) catch {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = arg.missingSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("missing value after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(":target".len) });
+ try err_details.msg.print(allocator, "missing value after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(":target".len) });
try diagnostics.append(err_details);
arg_i += 1;
break :next_arg;
@@ -655,8 +643,7 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
const arch_str = target_it.first();
const arch = cvtres.supported_targets.Arch.fromStringIgnoreCase(arch_str) orelse {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = value.argSpan(arg) };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("invalid or unsupported target architecture: {s}", .{arch_str});
+ try err_details.msg.print(allocator, "invalid or unsupported target architecture: {s}", .{arch_str});
try diagnostics.append(err_details);
arg_i += value.index_increment;
continue :next_arg;
@@ -680,13 +667,11 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
.prefix_len = arg.prefixSlice().len,
.value_offset = arg.name_offset + 3,
} };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("missing value for {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(3) });
+ try err_details.msg.print(allocator, "missing value for {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(3) });
try diagnostics.append(err_details);
}
var err_details = Diagnostics.ErrorDetails{ .type = .err, .arg_index = arg_i, .arg_span = arg.optionAndAfterSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("the {s}{s} option is unsupported", .{ arg.prefixSlice(), arg.optionWithoutPrefix(3) });
+ try err_details.msg.print(allocator, "the {s}{s} option is unsupported", .{ arg.prefixSlice(), arg.optionWithoutPrefix(3) });
try diagnostics.append(err_details);
arg_i += 1;
continue :next_arg;
@@ -695,16 +680,14 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
else if (std.ascii.startsWithIgnoreCase(arg_name, "tn")) {
const value = arg.value(2, arg_i, args) catch no_value: {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = arg.missingSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("missing value after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(2) });
+ try err_details.msg.print(allocator, "missing value after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(2) });
try diagnostics.append(err_details);
// dummy zero-length slice starting where the value would have been
const value_start = arg.name_offset + 2;
break :no_value Arg.Value{ .slice = arg.full[value_start..value_start] };
};
var err_details = Diagnostics.ErrorDetails{ .type = .err, .arg_index = arg_i, .arg_span = arg.optionAndAfterSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("the {s}{s} option is unsupported", .{ arg.prefixSlice(), arg.optionWithoutPrefix(2) });
+ try err_details.msg.print(allocator, "the {s}{s} option is unsupported", .{ arg.prefixSlice(), arg.optionWithoutPrefix(2) });
try diagnostics.append(err_details);
arg_i += value.index_increment;
continue :next_arg;
@@ -716,16 +699,14 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
{
const value = arg.value(2, arg_i, args) catch no_value: {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = arg.missingSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("missing value after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(2) });
+ try err_details.msg.print(allocator, "missing value after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(2) });
try diagnostics.append(err_details);
// dummy zero-length slice starting where the value would have been
const value_start = arg.name_offset + 2;
break :no_value Arg.Value{ .slice = arg.full[value_start..value_start] };
};
var err_details = Diagnostics.ErrorDetails{ .type = .err, .arg_index = arg_i, .arg_span = arg.optionAndAfterSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("the {s}{s} option is unsupported", .{ arg.prefixSlice(), arg.optionWithoutPrefix(2) });
+ try err_details.msg.print(allocator, "the {s}{s} option is unsupported", .{ arg.prefixSlice(), arg.optionWithoutPrefix(2) });
try diagnostics.append(err_details);
arg_i += value.index_increment;
continue :next_arg;
@@ -733,8 +714,7 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
// Unsupported MUI options that do not need a value
else if (std.ascii.startsWithIgnoreCase(arg_name, "g1")) {
var err_details = Diagnostics.ErrorDetails{ .type = .err, .arg_index = arg_i, .arg_span = arg.optionSpan(2) };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("the {s}{s} option is unsupported", .{ arg.prefixSlice(), arg.optionWithoutPrefix(2) });
+ try err_details.msg.print(allocator, "the {s}{s} option is unsupported", .{ arg.prefixSlice(), arg.optionWithoutPrefix(2) });
try diagnostics.append(err_details);
arg.name_offset += 2;
}
@@ -747,15 +727,13 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
std.ascii.startsWithIgnoreCase(arg_name, "ta"))
{
var err_details = Diagnostics.ErrorDetails{ .type = .err, .arg_index = arg_i, .arg_span = arg.optionSpan(2) };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("the {s}{s} option is unsupported", .{ arg.prefixSlice(), arg.optionWithoutPrefix(2) });
+ try err_details.msg.print(allocator, "the {s}{s} option is unsupported", .{ arg.prefixSlice(), arg.optionWithoutPrefix(2) });
try diagnostics.append(err_details);
arg.name_offset += 2;
} else if (std.ascii.startsWithIgnoreCase(arg_name, "fo")) {
const value = arg.value(2, arg_i, args) catch {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = arg.missingSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("missing output path after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(2) });
+ try err_details.msg.print(allocator, "missing output path after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(2) });
try diagnostics.append(err_details);
arg_i += 1;
break :next_arg;
@@ -767,8 +745,7 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
} else if (std.ascii.startsWithIgnoreCase(arg_name, "sl")) {
const value = arg.value(2, arg_i, args) catch {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = arg.missingSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("missing language tag after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(2) });
+ try err_details.msg.print(allocator, "missing language tag after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(2) });
try diagnostics.append(err_details);
arg_i += 1;
break :next_arg;
@@ -776,24 +753,20 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
const percent_str = value.slice;
const percent: u32 = parsePercent(percent_str) catch {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = value.argSpan(arg) };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("invalid percent format '{s}'", .{percent_str});
+ try err_details.msg.print(allocator, "invalid percent format '{s}'", .{percent_str});
try diagnostics.append(err_details);
var note_details = Diagnostics.ErrorDetails{ .type = .note, .print_args = false, .arg_index = arg_i };
- var note_writer = note_details.msg.writer(allocator);
- try note_writer.writeAll("string length percent must be an integer between 1 and 100 (inclusive)");
+ try note_details.msg.appendSlice(allocator, "string length percent must be an integer between 1 and 100 (inclusive)");
try diagnostics.append(note_details);
arg_i += value.index_increment;
continue :next_arg;
};
if (percent == 0 or percent > 100) {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = value.argSpan(arg) };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("percent out of range: {} (parsed from '{s}')", .{ percent, percent_str });
+ try err_details.msg.print(allocator, "percent out of range: {} (parsed from '{s}')", .{ percent, percent_str });
try diagnostics.append(err_details);
var note_details = Diagnostics.ErrorDetails{ .type = .note, .print_args = false, .arg_index = arg_i };
- var note_writer = note_details.msg.writer(allocator);
- try note_writer.writeAll("string length percent must be an integer between 1 and 100 (inclusive)");
+ try note_details.msg.appendSlice(allocator, "string length percent must be an integer between 1 and 100 (inclusive)");
try diagnostics.append(note_details);
arg_i += value.index_increment;
continue :next_arg;
@@ -805,8 +778,7 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
} else if (std.ascii.startsWithIgnoreCase(arg_name, "ln")) {
const value = arg.value(2, arg_i, args) catch {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = arg.missingSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("missing language tag after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(2) });
+ try err_details.msg.print(allocator, "missing language tag after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(2) });
try diagnostics.append(err_details);
arg_i += 1;
break :next_arg;
@@ -814,16 +786,14 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
const tag = value.slice;
options.default_language_id = lang.tagToInt(tag) catch {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = value.argSpan(arg) };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("invalid language tag: {s}", .{tag});
+ try err_details.msg.print(allocator, "invalid language tag: {s}", .{tag});
try diagnostics.append(err_details);
arg_i += value.index_increment;
continue :next_arg;
};
if (options.default_language_id.? == lang.LOCALE_CUSTOM_UNSPECIFIED) {
var err_details = Diagnostics.ErrorDetails{ .type = .warning, .arg_index = arg_i, .arg_span = value.argSpan(arg) };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("language tag '{s}' does not have an assigned ID so it will be resolved to LOCALE_CUSTOM_UNSPECIFIED (id=0x{x})", .{ tag, lang.LOCALE_CUSTOM_UNSPECIFIED });
+ try err_details.msg.print(allocator, "language tag '{s}' does not have an assigned ID so it will be resolved to LOCALE_CUSTOM_UNSPECIFIED (id=0x{x})", .{ tag, lang.LOCALE_CUSTOM_UNSPECIFIED });
try diagnostics.append(err_details);
}
arg_i += value.index_increment;
@@ -831,8 +801,7 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
} else if (std.ascii.startsWithIgnoreCase(arg_name, "l")) {
const value = arg.value(1, arg_i, args) catch {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = arg.missingSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("missing language ID after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(1) });
+ try err_details.msg.print(allocator, "missing language ID after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(1) });
try diagnostics.append(err_details);
arg_i += 1;
break :next_arg;
@@ -840,8 +809,7 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
const num_str = value.slice;
options.default_language_id = lang.parseInt(num_str) catch {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = value.argSpan(arg) };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("invalid language ID: {s}", .{num_str});
+ try err_details.msg.print(allocator, "invalid language ID: {s}", .{num_str});
try diagnostics.append(err_details);
arg_i += value.index_increment;
continue :next_arg;
@@ -860,16 +828,14 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
{
const value = arg.value(1, arg_i, args) catch no_value: {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = arg.missingSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("missing value after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(1) });
+ try err_details.msg.print(allocator, "missing value after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(1) });
try diagnostics.append(err_details);
// dummy zero-length slice starting where the value would have been
const value_start = arg.name_offset + 1;
break :no_value Arg.Value{ .slice = arg.full[value_start..value_start] };
};
var err_details = Diagnostics.ErrorDetails{ .type = .err, .arg_index = arg_i, .arg_span = arg.optionAndAfterSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("the {s}{s} option is unsupported", .{ arg.prefixSlice(), arg.optionWithoutPrefix(1) });
+ try err_details.msg.print(allocator, "the {s}{s} option is unsupported", .{ arg.prefixSlice(), arg.optionWithoutPrefix(1) });
try diagnostics.append(err_details);
arg_i += value.index_increment;
continue :next_arg;
@@ -882,16 +848,14 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
{
const value = arg.value(1, arg_i, args) catch no_value: {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = arg.missingSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("missing value after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(1) });
+ try err_details.msg.print(allocator, "missing value after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(1) });
try diagnostics.append(err_details);
// dummy zero-length slice starting where the value would have been
const value_start = arg.name_offset + 1;
break :no_value Arg.Value{ .slice = arg.full[value_start..value_start] };
};
var err_details = Diagnostics.ErrorDetails{ .type = .err, .arg_index = arg_i, .arg_span = arg.optionAndAfterSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("the {s}{s} option is unsupported", .{ arg.prefixSlice(), arg.optionWithoutPrefix(1) });
+ try err_details.msg.print(allocator, "the {s}{s} option is unsupported", .{ arg.prefixSlice(), arg.optionWithoutPrefix(1) });
try diagnostics.append(err_details);
arg_i += value.index_increment;
continue :next_arg;
@@ -899,15 +863,13 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
// 1 char unsupported LCX/LCE options that do not need a value
else if (std.ascii.startsWithIgnoreCase(arg_name, "t")) {
var err_details = Diagnostics.ErrorDetails{ .type = .err, .arg_index = arg_i, .arg_span = arg.optionSpan(1) };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("the {s}{s} option is unsupported", .{ arg.prefixSlice(), arg.optionWithoutPrefix(1) });
+ try err_details.msg.print(allocator, "the {s}{s} option is unsupported", .{ arg.prefixSlice(), arg.optionWithoutPrefix(1) });
try diagnostics.append(err_details);
arg.name_offset += 1;
} else if (std.ascii.startsWithIgnoreCase(arg_name, "c")) {
const value = arg.value(1, arg_i, args) catch {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = arg.missingSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("missing code page ID after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(1) });
+ try err_details.msg.print(allocator, "missing code page ID after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(1) });
try diagnostics.append(err_details);
arg_i += 1;
break :next_arg;
@@ -915,8 +877,7 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
const num_str = value.slice;
const code_page_id = std.fmt.parseUnsigned(u16, num_str, 10) catch {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = value.argSpan(arg) };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("invalid code page ID: {s}", .{num_str});
+ try err_details.msg.print(allocator, "invalid code page ID: {s}", .{num_str});
try diagnostics.append(err_details);
arg_i += value.index_increment;
continue :next_arg;
@@ -924,16 +885,14 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
options.default_code_page = code_pages.getByIdentifierEnsureSupported(code_page_id) catch |err| switch (err) {
error.InvalidCodePage => {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = value.argSpan(arg) };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("invalid or unknown code page ID: {}", .{code_page_id});
+ try err_details.msg.print(allocator, "invalid or unknown code page ID: {}", .{code_page_id});
try diagnostics.append(err_details);
arg_i += value.index_increment;
continue :next_arg;
},
error.UnsupportedCodePage => {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = value.argSpan(arg) };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("unsupported code page: {s} (id={})", .{
+ try err_details.msg.print(allocator, "unsupported code page: {s} (id={})", .{
@tagName(code_pages.getByIdentifier(code_page_id) catch unreachable),
code_page_id,
});
@@ -957,8 +916,7 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
} else if (std.ascii.startsWithIgnoreCase(arg_name, "i")) {
const value = arg.value(1, arg_i, args) catch {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = arg.missingSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("missing include path after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(1) });
+ try err_details.msg.print(allocator, "missing include path after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(1) });
try diagnostics.append(err_details);
arg_i += 1;
break :next_arg;
@@ -986,15 +944,13 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
// Undocumented option with unknown function
// TODO: More investigation to figure out what it does (if anything)
var err_details = Diagnostics.ErrorDetails{ .type = .warning, .arg_index = arg_i, .arg_span = arg.optionSpan(1) };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("option {s}{s} has no effect (it is undocumented and its function is unknown in the Win32 RC compiler)", .{ arg.prefixSlice(), arg.optionWithoutPrefix(1) });
+ try err_details.msg.print(allocator, "option {s}{s} has no effect (it is undocumented and its function is unknown in the Win32 RC compiler)", .{ arg.prefixSlice(), arg.optionWithoutPrefix(1) });
try diagnostics.append(err_details);
arg.name_offset += 1;
} else if (std.ascii.startsWithIgnoreCase(arg_name, "d")) {
const value = arg.value(1, arg_i, args) catch {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = arg.missingSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("missing symbol to define after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(1) });
+ try err_details.msg.print(allocator, "missing symbol to define after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(1) });
try diagnostics.append(err_details);
arg_i += 1;
break :next_arg;
@@ -1009,8 +965,7 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
try options.define(symbol, symbol_value);
} else {
var err_details = Diagnostics.ErrorDetails{ .type = .warning, .arg_index = arg_i, .arg_span = value.argSpan(arg) };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("symbol \"{s}\" is not a valid identifier and therefore cannot be defined", .{symbol});
+ try err_details.msg.print(allocator, "symbol \"{s}\" is not a valid identifier and therefore cannot be defined", .{symbol});
try diagnostics.append(err_details);
}
arg_i += value.index_increment;
@@ -1018,8 +973,7 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
} else if (std.ascii.startsWithIgnoreCase(arg_name, "u")) {
const value = arg.value(1, arg_i, args) catch {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = arg.missingSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("missing symbol to undefine after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(1) });
+ try err_details.msg.print(allocator, "missing symbol to undefine after {s}{s} option", .{ arg.prefixSlice(), arg.optionWithoutPrefix(1) });
try diagnostics.append(err_details);
arg_i += 1;
break :next_arg;
@@ -1029,16 +983,14 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
try options.undefine(symbol);
} else {
var err_details = Diagnostics.ErrorDetails{ .type = .warning, .arg_index = arg_i, .arg_span = value.argSpan(arg) };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("symbol \"{s}\" is not a valid identifier and therefore cannot be undefined", .{symbol});
+ try err_details.msg.print(allocator, "symbol \"{s}\" is not a valid identifier and therefore cannot be undefined", .{symbol});
try diagnostics.append(err_details);
}
arg_i += value.index_increment;
continue :next_arg;
} else {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i, .arg_span = arg.optionAndAfterSpan() };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("invalid option: {s}{s}", .{ arg.prefixSlice(), arg.name() });
+ try err_details.msg.print(allocator, "invalid option: {s}{s}", .{ arg.prefixSlice(), arg.name() });
try diagnostics.append(err_details);
arg_i += 1;
continue :next_arg;
@@ -1055,16 +1007,14 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
if (positionals.len == 0) {
var err_details = Diagnostics.ErrorDetails{ .print_args = false, .arg_index = arg_i };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.writeAll("missing input filename");
+ try err_details.msg.appendSlice(allocator, "missing input filename");
try diagnostics.append(err_details);
if (args.len > 0) {
const last_arg = args[args.len - 1];
if (arg_i > 0 and last_arg.len > 0 and last_arg[0] == '/' and isSupportedInputExtension(std.fs.path.extension(last_arg))) {
var note_details = Diagnostics.ErrorDetails{ .type = .note, .print_args = true, .arg_index = arg_i - 1 };
- var note_writer = note_details.msg.writer(allocator);
- try note_writer.writeAll("if this argument was intended to be the input filename, adding -- in front of it will exclude it from option parsing");
+ try note_details.msg.appendSlice(allocator, "if this argument was intended to be the input filename, adding -- in front of it will exclude it from option parsing");
try diagnostics.append(note_details);
}
}
@@ -1099,16 +1049,14 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
if (positionals.len > 1) {
if (output_filename != null) {
var err_details = Diagnostics.ErrorDetails{ .arg_index = arg_i + 1 };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.writeAll("output filename already specified");
+ try err_details.msg.appendSlice(allocator, "output filename already specified");
try diagnostics.append(err_details);
var note_details = Diagnostics.ErrorDetails{
.type = .note,
.arg_index = output_filename_context.arg.index,
.arg_span = output_filename_context.arg.value.argSpan(output_filename_context.arg.arg),
};
- var note_writer = note_details.msg.writer(allocator);
- try note_writer.writeAll("output filename previously specified here");
+ try note_details.msg.appendSlice(allocator, "output filename previously specified here");
try diagnostics.append(note_details);
} else {
output_filename = positionals[1];
@@ -1173,16 +1121,15 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
var print_output_format_source_note: bool = false;
if (options.depfile_path != null and (options.input_format == .res or options.output_format == .rcpp)) {
var err_details = Diagnostics.ErrorDetails{ .type = .warning, .arg_index = depfile_context.index, .arg_span = depfile_context.value.argSpan(depfile_context.arg) };
- var msg_writer = err_details.msg.writer(allocator);
if (options.input_format == .res) {
- try msg_writer.print("the {s}{s} option was ignored because the input format is '{s}'", .{
+ try err_details.msg.print(allocator, "the {s}{s} option was ignored because the input format is '{s}'", .{
depfile_context.arg.prefixSlice(),
depfile_context.arg.optionWithoutPrefix(depfile_context.option_len),
@tagName(options.input_format),
});
print_input_format_source_note = true;
} else if (options.output_format == .rcpp) {
- try msg_writer.print("the {s}{s} option was ignored because the output format is '{s}'", .{
+ try err_details.msg.print(allocator, "the {s}{s} option was ignored because the output format is '{s}'", .{
depfile_context.arg.prefixSlice(),
depfile_context.arg.optionWithoutPrefix(depfile_context.option_len),
@tagName(options.output_format),
@@ -1193,16 +1140,14 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
}
if (!isSupportedTransformation(options.input_format, options.output_format)) {
var err_details = Diagnostics.ErrorDetails{ .arg_index = input_filename_arg_i, .print_args = false };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("input format '{s}' cannot be converted to output format '{s}'", .{ @tagName(options.input_format), @tagName(options.output_format) });
+ try err_details.msg.print(allocator, "input format '{s}' cannot be converted to output format '{s}'", .{ @tagName(options.input_format), @tagName(options.output_format) });
try diagnostics.append(err_details);
print_input_format_source_note = true;
print_output_format_source_note = true;
}
if (options.preprocess == .only and options.output_format != .rcpp) {
var err_details = Diagnostics.ErrorDetails{ .arg_index = preprocess_only_context.index };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("the {s}{s} option cannot be used with output format '{s}'", .{
+ try err_details.msg.print(allocator, "the {s}{s} option cannot be used with output format '{s}'", .{
preprocess_only_context.arg.prefixSlice(),
preprocess_only_context.arg.optionWithoutPrefix(preprocess_only_context.option_len),
@tagName(options.output_format),
@@ -1214,8 +1159,7 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
switch (input_format_source) {
.inferred_from_input_filename => {
var err_details = Diagnostics.ErrorDetails{ .type = .note, .arg_index = input_filename_arg_i };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.writeAll("the input format was inferred from the input filename");
+ try err_details.msg.appendSlice(allocator, "the input format was inferred from the input filename");
try diagnostics.append(err_details);
},
.input_format_arg => {
@@ -1224,8 +1168,7 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
.arg_index = input_format_context.index,
.arg_span = input_format_context.value.argSpan(input_format_context.arg),
};
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.writeAll("the input format was specified here");
+ try err_details.msg.appendSlice(allocator, "the input format was specified here");
try diagnostics.append(err_details);
},
}
@@ -1234,11 +1177,10 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
switch (output_format_source) {
.inferred_from_input_filename, .unable_to_infer_from_input_filename => {
var err_details = Diagnostics.ErrorDetails{ .type = .note, .arg_index = input_filename_arg_i };
- var msg_writer = err_details.msg.writer(allocator);
if (output_format_source == .inferred_from_input_filename) {
- try msg_writer.writeAll("the output format was inferred from the input filename");
+ try err_details.msg.appendSlice(allocator, "the output format was inferred from the input filename");
} else {
- try msg_writer.writeAll("the output format was unable to be inferred from the input filename, so the default was used");
+ try err_details.msg.appendSlice(allocator, "the output format was unable to be inferred from the input filename, so the default was used");
}
try diagnostics.append(err_details);
},
@@ -1248,11 +1190,10 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
.arg => |ctx| .{ .type = .note, .arg_index = ctx.index, .arg_span = ctx.value.argSpan(ctx.arg) },
.unspecified => unreachable,
};
- var msg_writer = err_details.msg.writer(allocator);
if (output_format_source == .inferred_from_output_filename) {
- try msg_writer.writeAll("the output format was inferred from the output filename");
+ try err_details.msg.appendSlice(allocator, "the output format was inferred from the output filename");
} else {
- try msg_writer.writeAll("the output format was unable to be inferred from the output filename, so the default was used");
+ try err_details.msg.appendSlice(allocator, "the output format was unable to be inferred from the output filename, so the default was used");
}
try diagnostics.append(err_details);
},
@@ -1262,14 +1203,12 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn
.arg_index = output_format_context.index,
.arg_span = output_format_context.value.argSpan(output_format_context.arg),
};
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.writeAll("the output format was specified here");
+ try err_details.msg.appendSlice(allocator, "the output format was specified here");
try diagnostics.append(err_details);
},
.inferred_from_preprocess_only => {
var err_details = Diagnostics.ErrorDetails{ .type = .note, .arg_index = preprocess_only_context.index };
- var msg_writer = err_details.msg.writer(allocator);
- try msg_writer.print("the output format was inferred from the usage of the {s}{s} option", .{
+ try err_details.msg.print(allocator, "the output format was inferred from the usage of the {s}{s} option", .{
preprocess_only_context.arg.prefixSlice(),
preprocess_only_context.arg.optionWithoutPrefix(preprocess_only_context.option_len),
});
lib/compiler/resinator/compile.zig
@@ -61,7 +61,7 @@ pub const CompileOptions = struct {
warn_instead_of_error_on_invalid_code_page: bool = false,
};
-pub fn compile(allocator: Allocator, source: []const u8, writer: anytype, options: CompileOptions) !void {
+pub fn compile(allocator: Allocator, source: []const u8, writer: *std.Io.Writer, options: CompileOptions) !void {
var lexer = lex.Lexer.init(source, .{
.default_code_page = options.default_code_page,
.source_mappings = options.source_mappings,
@@ -194,7 +194,7 @@ pub const Compiler = struct {
characteristics: u32 = 0,
};
- pub fn writeRoot(self: *Compiler, root: *Node.Root, writer: anytype) !void {
+ pub fn writeRoot(self: *Compiler, root: *Node.Root, writer: *std.Io.Writer) !void {
try writeEmptyResource(writer);
for (root.body) |node| {
try self.writeNode(node, writer);
@@ -236,7 +236,7 @@ pub const Compiler = struct {
}
}
- pub fn writeNode(self: *Compiler, node: *Node, writer: anytype) !void {
+ pub fn writeNode(self: *Compiler, node: *Node, writer: *std.Io.Writer) !void {
switch (node.id) {
.root => unreachable, // writeRoot should be called directly instead
.resource_external => try self.writeResourceExternal(@alignCast(@fieldParentPtr("base", node)), writer),
@@ -479,7 +479,7 @@ pub const Compiler = struct {
return buf.toOwnedSlice();
}
- pub fn writeResourceExternal(self: *Compiler, node: *Node.ResourceExternal, writer: anytype) !void {
+ pub fn writeResourceExternal(self: *Compiler, node: *Node.ResourceExternal, writer: *std.Io.Writer) !void {
// Init header with data size zero for now, will need to fill it in later
var header = try self.resourceHeader(node.id, node.type, .{});
defer header.deinit(self.allocator);
@@ -1226,33 +1226,31 @@ pub const Compiler = struct {
}
pub fn writeResourceRawData(self: *Compiler, node: *Node.ResourceRawData, writer: anytype) !void {
- var data_buffer = std.array_list.Managed(u8).init(self.allocator);
+ var data_buffer: std.Io.Writer.Allocating = .init(self.allocator);
defer data_buffer.deinit();
// The header's data length field is a u32 so limit the resource's data size so that
// we know we can always specify the real size.
- var limited_writer = limitedWriter(data_buffer.writer(), std.math.maxInt(u32));
- const data_writer = limited_writer.writer();
+ const data_writer = &data_buffer.writer;
for (node.raw_data) |expression| {
const data = try self.evaluateDataExpression(expression);
defer data.deinit(self.allocator);
data.write(data_writer) catch |err| switch (err) {
- error.NoSpaceLeft => {
+ error.WriteFailed => {
return self.addErrorDetailsAndFail(.{
.err = .resource_data_size_exceeds_max,
.token = node.id,
});
},
- else => |e| return e,
};
}
// This intCast can't fail because the limitedWriter above guarantees that
// we will never write more than maxInt(u32) bytes.
- const data_len: u32 = @intCast(data_buffer.items.len);
+ const data_len: u32 = @intCast(data_buffer.written().len);
try self.writeResourceHeader(writer, node.id, node.type, data_len, node.common_resource_attributes, self.state.language);
- var data_fbs: std.Io.Reader = .fixed(data_buffer.items);
+ var data_fbs: std.Io.Reader = .fixed(data_buffer.written());
try writeResourceData(writer, &data_fbs, data_len);
}
@@ -1306,16 +1304,15 @@ pub const Compiler = struct {
}
pub fn writeAccelerators(self: *Compiler, node: *Node.Accelerators, writer: anytype) !void {
- var data_buffer = std.array_list.Managed(u8).init(self.allocator);
+ var data_buffer: std.Io.Writer.Allocating = .init(self.allocator);
defer data_buffer.deinit();
// The header's data length field is a u32 so limit the resource's data size so that
// we know we can always specify the real size.
- var limited_writer = limitedWriter(data_buffer.writer(), std.math.maxInt(u32));
- const data_writer = limited_writer.writer();
+ const data_writer = &data_buffer.writer;
self.writeAcceleratorsData(node, data_writer) catch |err| switch (err) {
- error.NoSpaceLeft => {
+ error.WriteFailed => {
return self.addErrorDetailsAndFail(.{
.err = .resource_data_size_exceeds_max,
.token = node.id,
@@ -1326,7 +1323,7 @@ pub const Compiler = struct {
// This intCast can't fail because the limitedWriter above guarantees that
// we will never write more than maxInt(u32) bytes.
- const data_size: u32 = @intCast(data_buffer.items.len);
+ const data_size: u32 = @intCast(data_buffer.written().len);
var header = try self.resourceHeader(node.id, node.type, .{
.data_size = data_size,
});
@@ -1337,7 +1334,7 @@ pub const Compiler = struct {
try header.write(writer, self.errContext(node.id));
- var data_fbs: std.Io.Reader = .fixed(data_buffer.items);
+ var data_fbs: std.Io.Reader = .fixed(data_buffer.written());
try writeResourceData(writer, &data_fbs, data_size);
}
@@ -1405,12 +1402,11 @@ pub const Compiler = struct {
};
pub fn writeDialog(self: *Compiler, node: *Node.Dialog, writer: anytype) !void {
- var data_buffer = std.array_list.Managed(u8).init(self.allocator);
+ var data_buffer: std.Io.Writer.Allocating = .init(self.allocator);
defer data_buffer.deinit();
// The header's data length field is a u32 so limit the resource's data size so that
// we know we can always specify the real size.
- var limited_writer = limitedWriter(data_buffer.writer(), std.math.maxInt(u32));
- const data_writer = limited_writer.writer();
+ const data_writer = &data_buffer.writer;
const resource = ResourceType.fromString(.{
.slice = node.type.slice(self.source),
@@ -1683,7 +1679,7 @@ pub const Compiler = struct {
) catch |err| switch (err) {
// Dialog header and menu/class/title strings can never exceed u32 bytes
// on their own, so this error is unreachable.
- error.NoSpaceLeft => unreachable,
+ error.WriteFailed => unreachable,
else => |e| return e,
};
@@ -1700,10 +1696,10 @@ pub const Compiler = struct {
data_writer,
resource,
// We know the data_buffer len is limited to u32 max.
- @intCast(data_buffer.items.len),
+ @intCast(data_buffer.written().len),
&controls_by_id,
) catch |err| switch (err) {
- error.NoSpaceLeft => {
+ error.WriteFailed => {
try self.addErrorDetails(.{
.err = .resource_data_size_exceeds_max,
.token = node.id,
@@ -1719,7 +1715,7 @@ pub const Compiler = struct {
}
// We know the data_buffer len is limited to u32 max.
- const data_size: u32 = @intCast(data_buffer.items.len);
+ const data_size: u32 = @intCast(data_buffer.written().len);
var header = try self.resourceHeader(node.id, node.type, .{
.data_size = data_size,
});
@@ -1730,7 +1726,7 @@ pub const Compiler = struct {
try header.write(writer, self.errContext(node.id));
- var data_fbs: std.Io.Reader = .fixed(data_buffer.items);
+ var data_fbs: std.Io.Reader = .fixed(data_buffer.written());
try writeResourceData(writer, &data_fbs, data_size);
}
@@ -1821,7 +1817,7 @@ pub const Compiler = struct {
.token = control.type,
});
}
- try data_writer.writeByteNTimes(0, num_padding);
+ try data_writer.splatByteAll(0, num_padding);
const style = if (control.style) |style_expression|
// Certain styles are implied by the control type
@@ -1973,16 +1969,15 @@ pub const Compiler = struct {
try NameOrOrdinal.writeEmpty(data_writer);
}
- var extra_data_buf = std.array_list.Managed(u8).init(self.allocator);
+ var extra_data_buf: std.Io.Writer.Allocating = .init(self.allocator);
defer extra_data_buf.deinit();
// The extra data byte length must be able to fit within a u16.
- var limited_extra_data_writer = limitedWriter(extra_data_buf.writer(), std.math.maxInt(u16));
- const extra_data_writer = limited_extra_data_writer.writer();
+ const extra_data_writer = &extra_data_buf.writer;
for (control.extra_data) |data_expression| {
const data = try self.evaluateDataExpression(data_expression);
defer data.deinit(self.allocator);
data.write(extra_data_writer) catch |err| switch (err) {
- error.NoSpaceLeft => {
+ error.WriteFailed => {
try self.addErrorDetails(.{
.err = .control_extra_data_size_exceeds_max,
.token = control.type,
@@ -1998,15 +1993,15 @@ pub const Compiler = struct {
};
}
// We know the extra_data_buf size fits within a u16.
- const extra_data_size: u16 = @intCast(extra_data_buf.items.len);
+ const extra_data_size: u16 = @intCast(extra_data_buf.written().len);
try data_writer.writeInt(u16, extra_data_size, .little);
- try data_writer.writeAll(extra_data_buf.items);
+ try data_writer.writeAll(extra_data_buf.written());
}
pub fn writeToolbar(self: *Compiler, node: *Node.Toolbar, writer: anytype) !void {
- var data_buffer = std.array_list.Managed(u8).init(self.allocator);
+ var data_buffer: std.Io.Writer.Allocating = .init(self.allocator);
defer data_buffer.deinit();
- const data_writer = data_buffer.writer();
+ const data_writer = &data_buffer.writer;
const button_width = evaluateNumberExpression(node.button_width, self.source, self.input_code_pages);
const button_height = evaluateNumberExpression(node.button_height, self.source, self.input_code_pages);
@@ -2034,7 +2029,7 @@ pub const Compiler = struct {
}
}
- const data_size: u32 = @intCast(data_buffer.items.len);
+ const data_size: u32 = @intCast(data_buffer.written().len);
var header = try self.resourceHeader(node.id, node.type, .{
.data_size = data_size,
});
@@ -2044,7 +2039,7 @@ pub const Compiler = struct {
try header.write(writer, self.errContext(node.id));
- var data_fbs: std.Io.Reader = .fixed(data_buffer.items);
+ var data_fbs: std.Io.Reader = .fixed(data_buffer.written());
try writeResourceData(writer, &data_fbs, data_size);
}
@@ -2082,12 +2077,11 @@ pub const Compiler = struct {
}
pub fn writeMenu(self: *Compiler, node: *Node.Menu, writer: anytype) !void {
- var data_buffer = std.array_list.Managed(u8).init(self.allocator);
+ var data_buffer: std.Io.Writer.Allocating = .init(self.allocator);
defer data_buffer.deinit();
// The header's data length field is a u32 so limit the resource's data size so that
// we know we can always specify the real size.
- var limited_writer = limitedWriter(data_buffer.writer(), std.math.maxInt(u32));
- const data_writer = limited_writer.writer();
+ const data_writer = &data_buffer.writer;
const type_bytes = SourceBytes{
.slice = node.type.slice(self.source),
@@ -2096,9 +2090,7 @@ pub const Compiler = struct {
const resource = ResourceType.fromString(type_bytes);
std.debug.assert(resource == .menu or resource == .menuex);
- var adapted = data_writer.adaptToNewApi(&.{});
-
- self.writeMenuData(node, &adapted.new_interface, resource) catch |err| switch (err) {
+ self.writeMenuData(node, data_writer, resource) catch |err| switch (err) {
error.WriteFailed => {
return self.addErrorDetailsAndFail(.{
.err = .resource_data_size_exceeds_max,
@@ -2110,7 +2102,7 @@ pub const Compiler = struct {
// This intCast can't fail because the limitedWriter above guarantees that
// we will never write more than maxInt(u32) bytes.
- const data_size: u32 = @intCast(data_buffer.items.len);
+ const data_size: u32 = @intCast(data_buffer.written().len);
var header = try self.resourceHeader(node.id, node.type, .{
.data_size = data_size,
});
@@ -2121,7 +2113,7 @@ pub const Compiler = struct {
try header.write(writer, self.errContext(node.id));
- var data_fbs: std.Io.Reader = .fixed(data_buffer.items);
+ var data_fbs: std.Io.Reader = .fixed(data_buffer.written());
try writeResourceData(writer, &data_fbs, data_size);
}
@@ -2265,12 +2257,11 @@ pub const Compiler = struct {
}
pub fn writeVersionInfo(self: *Compiler, node: *Node.VersionInfo, writer: anytype) !void {
- var data_buffer = std.array_list.Managed(u8).init(self.allocator);
+ var data_buffer: std.Io.Writer.Allocating = .init(self.allocator);
defer data_buffer.deinit();
// The node's length field (which is inclusive of the length of all of its children) is a u16
// so limit the node's data size so that we know we can always specify the real size.
- var limited_writer = limitedWriter(data_buffer.writer(), std.math.maxInt(u16));
- const data_writer = limited_writer.writer();
+ const data_writer = &data_buffer.writer;
try data_writer.writeInt(u16, 0, .little); // placeholder size
try data_writer.writeInt(u16, res.FixedFileInfo.byte_len, .little);
@@ -2354,8 +2345,7 @@ pub const Compiler = struct {
try fixed_file_info.write(data_writer);
for (node.block_statements) |statement| {
- var adapted = data_writer.adaptToNewApi(&.{});
- self.writeVersionNode(statement, &adapted.new_interface, &data_buffer) catch |err| switch (err) {
+ self.writeVersionNode(statement, data_writer, &data_buffer) catch |err| switch (err) {
error.WriteFailed => {
try self.addErrorDetails(.{
.err = .version_node_size_exceeds_max,
@@ -2374,9 +2364,9 @@ pub const Compiler = struct {
// We know that data_buffer.items.len is within the limits of a u16, since we
// limited the writer to maxInt(u16)
- const data_size: u16 = @intCast(data_buffer.items.len);
+ const data_size: u16 = @intCast(data_buffer.written().len);
// And now that we know the full size of this node (including its children), set its size
- std.mem.writeInt(u16, data_buffer.items[0..2], data_size, .little);
+ std.mem.writeInt(u16, data_buffer.written()[0..2], data_size, .little);
var header = try self.resourceHeader(node.id, node.versioninfo, .{
.data_size = data_size,
@@ -2387,22 +2377,22 @@ pub const Compiler = struct {
try header.write(writer, self.errContext(node.id));
- var data_fbs: std.Io.Reader = .fixed(data_buffer.items);
+ var data_fbs: std.Io.Reader = .fixed(data_buffer.written());
try writeResourceData(writer, &data_fbs, data_size);
}
/// Expects writer to be a LimitedWriter limited to u16, meaning all writes to
/// the writer within this function could return error.NoSpaceLeft, and that buf.items.len
/// will never be able to exceed maxInt(u16).
- pub fn writeVersionNode(self: *Compiler, node: *Node, writer: *std.Io.Writer, buf: *std.array_list.Managed(u8)) !void {
+ pub fn writeVersionNode(self: *Compiler, node: *Node, writer: *std.Io.Writer, buf: *std.Io.Writer.Allocating) !void {
// We can assume that buf.items.len will never be able to exceed the limits of a u16
- try writeDataPadding(writer, @as(u16, @intCast(buf.items.len)));
+ try writeDataPadding(writer, @as(u16, @intCast(buf.written().len)));
- const node_and_children_size_offset = buf.items.len;
+ const node_and_children_size_offset = buf.written().len;
try writer.writeInt(u16, 0, .little); // placeholder for size
- const data_size_offset = buf.items.len;
+ const data_size_offset = buf.written().len;
try writer.writeInt(u16, 0, .little); // placeholder for data size
- const data_type_offset = buf.items.len;
+ const data_type_offset = buf.written().len;
// Data type is string unless the node contains values that are numbers.
try writer.writeInt(u16, res.VersionNode.type_string, .little);
@@ -2432,7 +2422,7 @@ pub const Compiler = struct {
// during parsing, so we can just do the correct thing here.
var values_size: usize = 0;
- try writeDataPadding(writer, @intCast(buf.items.len));
+ try writeDataPadding(writer, @intCast(buf.written().len));
for (block_or_value.values, 0..) |value_value_node_uncasted, i| {
const value_value_node = value_value_node_uncasted.cast(.block_value_value).?;
@@ -2471,11 +2461,11 @@ pub const Compiler = struct {
}
}
}
- var data_size_slice = buf.items[data_size_offset..];
+ var data_size_slice = buf.written()[data_size_offset..];
std.mem.writeInt(u16, data_size_slice[0..@sizeOf(u16)], @as(u16, @intCast(values_size)), .little);
if (has_number_value) {
- const data_type_slice = buf.items[data_type_offset..];
+ const data_type_slice = buf.written()[data_type_offset..];
std.mem.writeInt(u16, data_type_slice[0..@sizeOf(u16)], res.VersionNode.type_binary, .little);
}
@@ -2489,8 +2479,8 @@ pub const Compiler = struct {
else => unreachable,
}
- const node_and_children_size = buf.items.len - node_and_children_size_offset;
- const node_and_children_size_slice = buf.items[node_and_children_size_offset..];
+ const node_and_children_size = buf.written().len - node_and_children_size_offset;
+ const node_and_children_size_slice = buf.written()[node_and_children_size_offset..];
std.mem.writeInt(u16, node_and_children_size_slice[0..@sizeOf(u16)], @as(u16, @intCast(node_and_children_size)), .little);
}
@@ -2973,54 +2963,6 @@ pub fn headerSlurpingReader(comptime size: usize, reader: anytype) HeaderSlurpin
return .{ .child_reader = reader };
}
-/// Sort of like std.io.LimitedReader, but a Writer.
-/// Returns an error if writing the requested number of bytes
-/// would ever exceed bytes_left, i.e. it does not always
-/// write up to the limit and instead will error if the
-/// limit would be breached if the entire slice was written.
-pub fn LimitedWriter(comptime WriterType: type) type {
- return struct {
- inner_writer: WriterType,
- bytes_left: u64,
-
- pub const Error = error{NoSpaceLeft} || WriterType.Error;
- pub const Writer = std.io.GenericWriter(*Self, Error, write);
-
- const Self = @This();
-
- pub fn write(self: *Self, bytes: []const u8) Error!usize {
- if (bytes.len > self.bytes_left) return error.NoSpaceLeft;
- const amt = try self.inner_writer.write(bytes);
- self.bytes_left -= amt;
- return amt;
- }
-
- pub fn writer(self: *Self) Writer {
- return .{ .context = self };
- }
- };
-}
-
-/// Returns an initialised `LimitedWriter`
-/// `bytes_left` is a `u64` to be able to take 64 bit file offsets
-pub fn limitedWriter(inner_writer: anytype, bytes_left: u64) LimitedWriter(@TypeOf(inner_writer)) {
- return .{ .inner_writer = inner_writer, .bytes_left = bytes_left };
-}
-
-test "limitedWriter basic usage" {
- var buf: [4]u8 = undefined;
- var fbs = std.io.fixedBufferStream(&buf);
- var limited_stream = limitedWriter(fbs.writer(), 4);
- var writer = limited_stream.writer();
-
- try std.testing.expectEqual(@as(usize, 3), try writer.write("123"));
- try std.testing.expectEqualSlices(u8, "123", buf[0..3]);
- try std.testing.expectError(error.NoSpaceLeft, writer.write("45"));
- try std.testing.expectEqual(@as(usize, 1), try writer.write("4"));
- try std.testing.expectEqualSlices(u8, "1234", buf[0..4]);
- try std.testing.expectError(error.NoSpaceLeft, writer.write("5"));
-}
-
pub const FontDir = struct {
fonts: std.ArrayListUnmanaged(Font) = .empty,
/// To keep track of which ids are set and where they were set from
@@ -3246,9 +3188,9 @@ pub const StringTable = struct {
}
pub fn writeResData(self: *Block, compiler: *Compiler, language: res.Language, block_id: u16, writer: anytype) !void {
- var data_buffer = std.array_list.Managed(u8).init(compiler.allocator);
+ var data_buffer: std.Io.Writer.Allocating = .init(compiler.allocator);
defer data_buffer.deinit();
- const data_writer = data_buffer.writer();
+ const data_writer = &data_buffer.writer;
var i: u8 = 0;
var string_i: u8 = 0;
@@ -3307,7 +3249,7 @@ pub const StringTable = struct {
// 16 * (131,070 + 2) = 2,097,152 which is well within the u32 max.
//
// Note: The string literal maximum length is enforced by the lexer.
- const data_size: u32 = @intCast(data_buffer.items.len);
+ const data_size: u32 = @intCast(data_buffer.written().len);
const header = Compiler.ResourceHeader{
.name_value = .{ .ordinal = block_id },
@@ -3322,7 +3264,7 @@ pub const StringTable = struct {
// we fully control and know are numbers, so they have a fixed size.
try header.writeAssertNoOverflow(writer);
- var data_fbs: std.Io.Reader = .fixed(data_buffer.items);
+ var data_fbs: std.Io.Reader = .fixed(data_buffer.written());
try Compiler.writeResourceData(writer, &data_fbs, data_size);
}
};
lib/compiler/resinator/errors.zig
@@ -1102,11 +1102,10 @@ const CorrespondingLines = struct {
corresponding_lines.buffered_reader = corresponding_lines.file.reader(&.{});
errdefer corresponding_lines.deinit();
- var fbs = std.io.fixedBufferStream(&corresponding_lines.line_buf);
- const writer = fbs.writer();
+ var writer: std.Io.Writer = .fixed(&corresponding_lines.line_buf);
try corresponding_lines.writeLineFromStreamVerbatim(
- writer,
+ &writer,
corresponding_lines.buffered_reader.interface.adaptToOldInterface(),
corresponding_span.start_line,
);
@@ -1145,11 +1144,10 @@ const CorrespondingLines = struct {
self.line_len = 0;
self.visual_line_len = 0;
- var fbs = std.io.fixedBufferStream(&self.line_buf);
- const writer = fbs.writer();
+ var writer: std.Io.Writer = .fixed(&self.line_buf);
try self.writeLineFromStreamVerbatim(
- writer,
+ &writer,
self.buffered_reader.interface.adaptToOldInterface(),
self.line_num,
);
@@ -1164,7 +1162,7 @@ const CorrespondingLines = struct {
return visual_line;
}
- fn writeLineFromStreamVerbatim(self: *CorrespondingLines, writer: anytype, input: anytype, line_num: usize) !void {
+ fn writeLineFromStreamVerbatim(self: *CorrespondingLines, writer: *std.Io.Writer, input: anytype, line_num: usize) !void {
while (try readByteOrEof(input)) |byte| {
switch (byte) {
'\n', '\r' => {
@@ -1188,7 +1186,7 @@ const CorrespondingLines = struct {
if (writer.writeByte(byte)) {
self.line_len += 1;
} else |err| switch (err) {
- error.NoSpaceLeft => {},
+ error.WriteFailed => {},
else => |e| return e,
}
}
lib/compiler/resinator/main.zig
@@ -43,11 +43,11 @@ pub fn main() !void {
cli_args = args[3..];
}
- var stdout_writer2 = std.fs.File.stdout().writer(&stdout_buffer);
+ var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer);
var error_handler: ErrorHandler = switch (zig_integration) {
true => .{
.server = .{
- .out = &stdout_writer2.interface,
+ .out = &stdout_writer.interface,
.in = undefined, // won't be receiving messages
},
},
@@ -83,18 +83,18 @@ pub fn main() !void {
defer options.deinit();
if (options.print_help_and_exit) {
- const stdout = std.fs.File.stdout();
- try cli.writeUsage(stdout.deprecatedWriter(), "zig rc");
+ try cli.writeUsage(&stdout_writer.interface, "zig rc");
+ try stdout_writer.interface.flush();
return;
}
// Don't allow verbose when integrating with Zig via stdout
options.verbose = false;
- const stdout_writer = std.fs.File.stdout().deprecatedWriter();
if (options.verbose) {
- try options.dumpVerbose(stdout_writer);
- try stdout_writer.writeByte('\n');
+ try options.dumpVerbose(&stdout_writer.interface);
+ try stdout_writer.interface.writeByte('\n');
+ try stdout_writer.interface.flush();
}
var dependencies_list = std.array_list.Managed([]const u8).init(allocator);
@@ -115,7 +115,7 @@ pub fn main() !void {
const full_input = full_input: {
if (options.input_format == .rc and options.preprocess != .no) {
- var preprocessed_buf = std.array_list.Managed(u8).init(allocator);
+ var preprocessed_buf: std.Io.Writer.Allocating = .init(allocator);
errdefer preprocessed_buf.deinit();
// We're going to throw away everything except the final preprocessed output anyway,
@@ -139,14 +139,15 @@ pub fn main() !void {
});
if (options.verbose) {
- try stdout_writer.writeAll("Preprocessor: arocc (built-in)\n");
+ try stdout_writer.interface.writeAll("Preprocessor: arocc (built-in)\n");
for (argv.items[0 .. argv.items.len - 1]) |arg| {
- try stdout_writer.print("{s} ", .{arg});
+ try stdout_writer.interface.print("{s} ", .{arg});
}
- try stdout_writer.print("{s}\n\n", .{argv.items[argv.items.len - 1]});
+ try stdout_writer.interface.print("{s}\n\n", .{argv.items[argv.items.len - 1]});
+ try stdout_writer.interface.flush();
}
- preprocess.preprocess(&comp, preprocessed_buf.writer(), argv.items, maybe_dependencies_list) catch |err| switch (err) {
+ preprocess.preprocess(&comp, &preprocessed_buf.writer, argv.items, maybe_dependencies_list) catch |err| switch (err) {
error.GeneratedSourceError => {
try error_handler.emitAroDiagnostics(allocator, "failed during preprocessor setup (this is always a bug):", &comp);
std.process.exit(1);
@@ -249,8 +250,9 @@ pub fn main() !void {
defer diagnostics.deinit();
var output_buffer: [4096]u8 = undefined;
- var res_stream_writer = res_stream.source.writer(allocator).adaptToNewApi(&output_buffer);
- const output_buffered_stream = &res_stream_writer.new_interface;
+ var res_stream_writer = res_stream.source.writer(allocator, &output_buffer);
+ defer res_stream_writer.deinit(&res_stream.source);
+ const output_buffered_stream = res_stream_writer.interface();
compile(allocator, final_input, output_buffered_stream, .{
.cwd = std.fs.cwd(),
@@ -342,10 +344,10 @@ pub fn main() !void {
defer coff_stream.deinit(allocator);
var coff_output_buffer: [4096]u8 = undefined;
- var coff_output_buffered_stream = coff_stream.source.writer(allocator).adaptToNewApi(&coff_output_buffer);
+ var coff_output_buffered_stream = coff_stream.source.writer(allocator, &coff_output_buffer);
var cvtres_diagnostics: cvtres.Diagnostics = .{ .none = {} };
- cvtres.writeCoff(allocator, &coff_output_buffered_stream.new_interface, resources.list.items, options.coff_options, &cvtres_diagnostics) catch |err| {
+ cvtres.writeCoff(allocator, coff_output_buffered_stream.interface(), resources.list.items, options.coff_options, &cvtres_diagnostics) catch |err| {
switch (err) {
error.DuplicateResource => {
const duplicate_resource = resources.list.items[cvtres_diagnostics.duplicate_resource];
@@ -382,7 +384,7 @@ pub fn main() !void {
std.process.exit(1);
};
- try coff_output_buffered_stream.new_interface.flush();
+ try coff_output_buffered_stream.interface().flush();
}
const IoStream = struct {
@@ -425,7 +427,7 @@ const IoStream = struct {
pub const Source = union(enum) {
file: std.fs.File,
stdio: std.fs.File,
- memory: std.ArrayListUnmanaged(u8),
+ memory: std.ArrayList(u8),
/// The source has been closed and any usage of the Source in this state is illegal (except deinit).
closed: void,
@@ -472,26 +474,34 @@ const IoStream = struct {
};
}
- pub const WriterContext = struct {
- self: *Source,
- allocator: std.mem.Allocator,
- };
- pub const WriteError = std.mem.Allocator.Error || std.fs.File.WriteError;
- pub const Writer = std.io.GenericWriter(WriterContext, WriteError, write);
-
- pub fn write(ctx: WriterContext, bytes: []const u8) WriteError!usize {
- switch (ctx.self.*) {
- inline .file, .stdio => |file| return file.write(bytes),
- .memory => |*list| {
- try list.appendSlice(ctx.allocator, bytes);
- return bytes.len;
- },
- .closed => unreachable,
+ pub const Writer = union(enum) {
+ file: std.fs.File.Writer,
+ allocating: std.Io.Writer.Allocating,
+
+ pub const Error = std.mem.Allocator.Error || std.fs.File.WriteError;
+
+ pub fn interface(this: *@This()) *std.Io.Writer {
+ return switch (this.*) {
+ .file => |*fw| &fw.interface,
+ .allocating => |*a| &a.writer,
+ };
}
- }
- pub fn writer(self: *Source, allocator: std.mem.Allocator) Writer {
- return .{ .context = .{ .self = self, .allocator = allocator } };
+ pub fn deinit(this: *@This(), source: *Source) void {
+ switch (this.*) {
+ .file => {},
+ .allocating => |*a| source.memory = a.toArrayList(),
+ }
+ this.* = undefined;
+ }
+ };
+
+ pub fn writer(source: *Source, allocator: std.mem.Allocator, buffer: []u8) Writer {
+ return switch (source.*) {
+ .file, .stdio => |file| .{ .file = file.writer(buffer) },
+ .memory => |*list| .{ .allocating = .fromArrayList(allocator, list) },
+ .closed => unreachable,
+ };
}
};
};
@@ -721,7 +731,7 @@ fn cliDiagnosticsToErrorBundle(
});
var cur_err: ?ErrorBundle.ErrorMessage = null;
- var cur_notes: std.ArrayListUnmanaged(ErrorBundle.ErrorMessage) = .empty;
+ var cur_notes: std.ArrayList(ErrorBundle.ErrorMessage) = .empty;
defer cur_notes.deinit(gpa);
for (diagnostics.errors.items) |err_details| {
switch (err_details.type) {
@@ -763,10 +773,10 @@ fn diagnosticsToErrorBundle(
try bundle.init(gpa);
errdefer bundle.deinit();
- var msg_buf: std.ArrayListUnmanaged(u8) = .empty;
- defer msg_buf.deinit(gpa);
+ var msg_buf: std.Io.Writer.Allocating = .init(gpa);
+ defer msg_buf.deinit();
var cur_err: ?ErrorBundle.ErrorMessage = null;
- var cur_notes: std.ArrayListUnmanaged(ErrorBundle.ErrorMessage) = .empty;
+ var cur_notes: std.ArrayList(ErrorBundle.ErrorMessage) = .empty;
defer cur_notes.deinit(gpa);
for (diagnostics.errors.items) |err_details| {
switch (err_details.type) {
@@ -789,7 +799,7 @@ fn diagnosticsToErrorBundle(
const column = err_details.token.calculateColumn(source, 1, source_line_start) + 1;
msg_buf.clearRetainingCapacity();
- try err_details.render(msg_buf.writer(gpa), source, diagnostics.strings.items);
+ try err_details.render(&msg_buf.writer, source, diagnostics.strings.items);
const src_loc = src_loc: {
var src_loc: ErrorBundle.SourceLocation = .{
@@ -817,7 +827,7 @@ fn diagnosticsToErrorBundle(
try flushErrorMessageIntoBundle(&bundle, err, cur_notes.items);
}
cur_err = .{
- .msg = try bundle.addString(msg_buf.items),
+ .msg = try bundle.addString(msg_buf.written()),
.src_loc = src_loc,
};
cur_notes.clearRetainingCapacity();
@@ -825,7 +835,7 @@ fn diagnosticsToErrorBundle(
.note => {
cur_err.?.notes_len += 1;
try cur_notes.append(gpa, .{
- .msg = try bundle.addString(msg_buf.items),
+ .msg = try bundle.addString(msg_buf.written()),
.src_loc = src_loc,
});
},
@@ -876,7 +886,7 @@ fn aroDiagnosticsToErrorBundle(
var msg_writer = MsgWriter.init(gpa);
defer msg_writer.deinit();
var cur_err: ?ErrorBundle.ErrorMessage = null;
- var cur_notes: std.ArrayListUnmanaged(ErrorBundle.ErrorMessage) = .empty;
+ var cur_notes: std.ArrayList(ErrorBundle.ErrorMessage) = .empty;
defer cur_notes.deinit(gpa);
for (comp.diagnostics.list.items) |msg| {
switch (msg.kind) {
@@ -971,11 +981,11 @@ const MsgWriter = struct {
}
pub fn print(m: *MsgWriter, comptime fmt: []const u8, args: anytype) void {
- m.buf.writer().print(fmt, args) catch {};
+ m.buf.print(fmt, args) catch {};
}
pub fn write(m: *MsgWriter, msg: []const u8) void {
- m.buf.writer().writeAll(msg) catch {};
+ m.buf.appendSlice(msg) catch {};
}
pub fn setColor(m: *MsgWriter, color: std.io.tty.Color) void {
lib/compiler/resinator/preprocess.zig
@@ -18,12 +18,15 @@ pub fn preprocess(
var driver: aro.Driver = .{ .comp = comp, .aro_name = "arocc" };
defer driver.deinit();
- var macro_buf = std.array_list.Managed(u8).init(comp.gpa);
+ var macro_buf: std.Io.Writer.Allocating = .init(comp.gpa);
defer macro_buf.deinit();
- _ = driver.parseArgs(std.io.null_writer, macro_buf.writer(), argv) catch |err| switch (err) {
+ var trash: [64]u8 = undefined;
+ var discarding: std.Io.Writer.Discarding = .init(&trash);
+ _ = driver.parseArgs(&discarding.writer, ¯o_buf.writer, argv) catch |err| switch (err) {
error.FatalError => return error.ArgError,
error.OutOfMemory => |e| return e,
+ error.WriteFailed => return error.OutOfMemory,
};
if (hasAnyErrors(comp)) return error.ArgError;
@@ -33,7 +36,7 @@ pub fn preprocess(
error.FatalError => return error.GeneratedSourceError,
else => |e| return e,
};
- const user_macros = comp.addSourceFromBuffer("<command line>", macro_buf.items) catch |err| switch (err) {
+ const user_macros = comp.addSourceFromBuffer("<command line>", macro_buf.written()) catch |err| switch (err) {
error.FatalError => return error.GeneratedSourceError,
else => |e| return e,
};
@@ -59,7 +62,9 @@ pub fn preprocess(
if (hasAnyErrors(comp)) return error.PreprocessError;
- try pp.prettyPrintTokens(writer, .result_only);
+ pp.prettyPrintTokens(writer, .result_only) catch |err| switch (err) {
+ error.WriteFailed => return error.OutOfMemory,
+ };
if (maybe_dependencies_list) |dependencies_list| {
for (comp.sources.values()) |comp_source| {