zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit a6fded0810cdc9998101cc56804b1dc7274f9671 (tree)
parent 6043fbb2b7f263c0bab308f46f4ef393fec4a678
Author: fardragon <michaldrozd@protonmail.ch>
Date:   Thu,  4 Jun 2026 19:26:32 +0000

Make ConfigHeader newline aware

Diffstat:
Mlib/compiler/Maker/Step/ConfigHeader.zig | 92+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
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 }), } }