commit a6fded0810cdc9998101cc56804b1dc7274f9671 (tree)
parent 6043fbb2b7f263c0bab308f46f4ef393fec4a678
Author: fardragon <michaldrozd@protonmail.ch>
Date: Thu, 4 Jun 2026 19:26:32 +0000
Make ConfigHeader newline aware
Diffstat:
1 file changed, 57 insertions(+), 35 deletions(-)
diff --git a/lib/compiler/Maker/Step/ConfigHeader.zig b/lib/compiler/Maker/Step/ConfigHeader.zig
@@ -11,8 +11,10 @@ const Step = @import("../Step.zig");
const Maker = @import("../../Maker.zig");
const header_text = "This file was generated by ConfigHeader using the Zig Build System.";
-const c_generated_line = "/* " ++ header_text ++ " */\n";
-const asm_generated_line = "; " ++ header_text ++ "\n";
+const c_generated_line = "/* " ++ header_text ++ " */";
+const asm_generated_line = "; " ++ header_text;
+
+const os_newline = if (@import("builtin").os.tag == .windows) "\r\n" else "\n";
/// Table value is whether the value is used.
const ValueMap = std.array_hash_map.String(bool);
@@ -160,6 +162,15 @@ fn ensureAllValuesUsed(
if (any_errors) return error.MakeFailed;
}
+fn detectNewline(contents: []const u8) []const u8 {
+ return if (std.mem.endsWith(u8, contents, "\r\n"))
+ "\r\n"
+ else if (std.mem.endsWith(u8, contents, "\n"))
+ "\n"
+ else
+ os_newline;
+}
+
fn renderAutoConfUndef(
maker: *Maker,
step: *Step,
@@ -170,25 +181,28 @@ fn renderAutoConfUndef(
src_path: Path,
) !void {
const conf = &maker.scanned_config.configuration;
+ const newline = detectNewline(contents);
try w.writeAll(c_generated_line);
+ try w.writeAll(newline);
var any_errors = false;
var line_index: u32 = 0;
var line_it = std.mem.splitScalar(u8, contents, '\n');
- while (line_it.next()) |line| : (line_index += 1) {
+ while (line_it.next()) |raw_line| : (line_index += 1) {
const last_line = line_it.index == line_it.buffer.len;
+ const line = std.mem.trimEnd(u8, raw_line, "\r");
if (!std.mem.startsWith(u8, line, "#")) {
try w.writeAll(line);
- if (!last_line) try w.writeByte('\n');
+ if (!last_line) try w.writeAll(newline);
continue;
}
var it = std.mem.tokenizeAny(u8, line[1..], " \t\r");
const undef = it.next().?;
if (!std.mem.eql(u8, undef, "undef")) {
try w.writeAll(line);
- if (!last_line) try w.writeByte('\n');
+ if (!last_line) try w.writeAll(newline);
continue;
}
const name = it.next().?;
@@ -200,7 +214,7 @@ fn renderAutoConfUndef(
continue;
};
value_map.values()[index] = true; // Set to used.
- try renderValueC(conf, w, name, value_pairs[index].index);
+ try renderValueC(conf, w, newline, name, value_pairs[index].index);
}
try ensureAllValuesUsed(maker, step, value_map, src_path);
@@ -218,14 +232,17 @@ fn renderAutoconfAt(
) !void {
const w = &aw.writer;
const conf = &maker.scanned_config.configuration;
+ const newline = detectNewline(contents);
try w.writeAll(c_generated_line);
+ try w.writeAll(newline);
var any_errors = false;
var line_index: u32 = 0;
var line_it = std.mem.splitScalar(u8, contents, '\n');
- while (line_it.next()) |line| : (line_index += 1) {
+ while (line_it.next()) |raw_line| : (line_index += 1) {
const last_line = line_it.index == line_it.buffer.len;
+ const line = std.mem.trimEnd(u8, raw_line, "\r");
const old_len = aw.written().len;
expandVariablesAutoconfAt(w, line, conf, value_pairs, value_map) catch |err| switch (err) {
@@ -246,7 +263,7 @@ fn renderAutoconfAt(
continue;
},
};
- if (!last_line) try w.writeByte('\n');
+ if (!last_line) try w.writeAll(newline);
}
try ensureAllValuesUsed(maker, step, value_map, src_path);
@@ -264,16 +281,19 @@ fn renderCmake(
src_path: Path,
) !void {
const conf = &maker.scanned_config.configuration;
+ const newline = detectNewline(contents);
try w.writeAll(c_generated_line);
+ try w.writeAll(newline);
var any_errors = false;
var line_index: u32 = 0;
var line_it = std.mem.splitScalar(u8, contents, '\n');
while (line_it.next()) |raw_line| : (line_index += 1) {
const last_line = line_it.index == line_it.buffer.len;
+ const stripped_line = std.mem.trimEnd(u8, raw_line, "\r");
- const line = expandVariablesCmake(arena, raw_line, conf, value_pairs, value_map) catch |err| switch (err) {
+ const line = expandVariablesCmake(arena, stripped_line, conf, value_pairs, value_map) catch |err| switch (err) {
error.InvalidCharacter => {
try step.addError(maker, "{f}:{d}: invalid character in a variable name", .{
src_path, line_index + 1,
@@ -292,7 +312,7 @@ fn renderCmake(
const line_start = std.mem.findNone(u8, line, " \t\r") orelse {
try w.writeAll(line);
- if (!last_line) try w.writeByte('\n');
+ if (!last_line) try w.writeAll(newline);
continue;
};
const whitespace_prefix = line[0..line_start];
@@ -300,7 +320,7 @@ fn renderCmake(
if (!std.mem.startsWith(u8, trimmed_line, "#")) {
try w.writeAll(line);
- if (!last_line) try w.writeByte('\n');
+ if (!last_line) try w.writeAll(newline);
continue;
}
@@ -313,7 +333,7 @@ fn renderCmake(
false
else {
try w.writeAll(line);
- if (!last_line) try w.writeByte('\n');
+ if (!last_line) try w.writeAll(newline);
continue;
};
@@ -337,7 +357,7 @@ fn renderCmake(
try w.writeAll(whitespace_prefix);
if (booldefine) {
- try renderValueCBool(w, name, switch (value.unpack(conf)) {
+ try renderValueCBool(w, newline, name, switch (value.unpack(conf)) {
.undef, .defined => false,
.bool => |b| b,
inline .u64, .i64 => |i| i != 0,
@@ -345,9 +365,9 @@ fn renderCmake(
.ident => false,
});
} else if (value != .undef) {
- try renderValueCIdent(w, name, it.rest());
+ try renderValueCIdent(w, newline, name, it.rest());
} else {
- try renderValueC(conf, w, name, value);
+ try renderValueC(conf, w, newline, name, value);
}
}
@@ -364,6 +384,7 @@ fn renderBlank(
include_guard_override: ?[]const u8,
) !void {
try w.writeAll(c_generated_line);
+ try w.writeAll(os_newline);
const include_guard_fmt: IncludeGuardFmt = .{
.include_path = include_path,
@@ -376,7 +397,7 @@ fn renderBlank(
\\
, .{include_guard_fmt});
- for (value_map.keys(), value_pairs) |name, pair| try renderValueC(conf, w, name, pair.index);
+ for (value_map.keys(), value_pairs) |name, pair| try renderValueC(conf, w, os_newline, name, pair.index);
try w.print(
\\#endif /* {f} */
@@ -405,41 +426,42 @@ fn renderNasm(
value_map: *const ValueMap,
) !void {
try w.writeAll(asm_generated_line);
- for (value_map.keys(), value_pairs) |name, pair| try renderValueNasm(conf, w, name, pair.index);
+ try w.writeAll(os_newline);
+ for (value_map.keys(), value_pairs) |name, pair| try renderValueNasm(conf, w, os_newline, name, pair.index);
}
-fn renderValueC(conf: *const Configuration, w: *Writer, name: []const u8, value: Value.Index) !void {
+fn renderValueC(conf: *const Configuration, w: *Writer, newline: []const u8, name: []const u8, value: Value.Index) !void {
switch (value.unpack(conf)) {
- .undef => try w.print("/* #undef {s} */\n", .{name}),
- .defined => try w.print("#define {s}\n", .{name}),
- .bool => |b| return renderValueCBool(w, name, b),
- inline .u64, .i64 => |i| try w.print("#define {s} {d}\n", .{ name, i }),
- .ident => |ident| return renderValueCIdent(w, name, ident),
- .string => |string| try w.print("#define {s} \"{f}\"\n", .{ name, std.zig.fmtString(string) }),
+ .undef => try w.print("/* #undef {s} */{s}", .{ name, newline }),
+ .defined => try w.print("#define {s}{s}", .{ name, newline }),
+ .bool => |b| return renderValueCBool(w, newline, name, b),
+ inline .u64, .i64 => |i| try w.print("#define {s} {d}{s}", .{ name, i, newline }),
+ .ident => |ident| return renderValueCIdent(w, newline, name, ident),
+ .string => |string| try w.print("#define {s} \"{f}\"{s}", .{ name, std.zig.fmtString(string), newline }),
}
}
-fn renderValueCIdent(w: *Writer, name: []const u8, ident: []const u8) Writer.Error!void {
+fn renderValueCIdent(w: *Writer, newline: []const u8, name: []const u8, ident: []const u8) Writer.Error!void {
try w.print("#define {s}", .{name});
if (ident.len > 0) {
try w.writeByte(' ');
try w.writeAll(ident);
}
- return w.writeByte('\n');
+ return w.writeAll(newline);
}
-fn renderValueCBool(w: *Writer, name: []const u8, b: bool) Writer.Error!void {
- return w.print("#define {s} {c}\n", .{ name, @as(u8, '0') + @intFromBool(b) });
+fn renderValueCBool(w: *Writer, newline: []const u8, name: []const u8, b: bool) Writer.Error!void {
+ return w.print("#define {s} {c}{s}", .{ name, @as(u8, '0') + @intFromBool(b), newline });
}
-fn renderValueNasm(conf: *const Configuration, w: *Writer, name: []const u8, value: Value.Index) !void {
+fn renderValueNasm(conf: *const Configuration, w: *Writer, newline: []const u8, name: []const u8, value: Value.Index) !void {
switch (value.unpack(conf)) {
- .undef => try w.print("; %undef {s}\n", .{name}),
- .defined => try w.print("%define {s}\n", .{name}),
- .bool => |b| try w.print("%define {s} {c}\n", .{ name, @as(u8, '0') + @intFromBool(b) }),
- inline .u64, .i64 => |i| try w.print("%define {s} {d}\n", .{ name, i }),
- .ident => |ident| try w.print("%define {s} {s}\n", .{ name, ident }),
- .string => |string| try w.print("%define {s} \"{f}\"\n", .{ name, std.zig.fmtString(string) }),
+ .undef => try w.print("; %undef {s}{s}", .{ name, newline }),
+ .defined => try w.print("%define {s}{s}", .{ name, newline }),
+ .bool => |b| try w.print("%define {s} {c}{s}", .{ name, @as(u8, '0') + @intFromBool(b), newline }),
+ inline .u64, .i64 => |i| try w.print("%define {s} {d}{s}", .{ name, i, newline }),
+ .ident => |ident| try w.print("%define {s} {s}{s}", .{ name, ident, newline }),
+ .string => |string| try w.print("%define {s} \"{f}\"{s}", .{ name, std.zig.fmtString(string), newline }),
}
}