| ... | ... | @@ -11,8 +11,10 @@ const Step = @import("../Step.zig"); |
| 11 | 11 | const Maker = @import("../../Maker.zig"); |
| 12 | 12 | |
| 13 | 13 | const header_text = "This file was generated by ConfigHeader using the Zig Build System."; |
| 14 | | const c_generated_line = "/* " ++ header_text ++ " */\n"; |
| 15 | | const asm_generated_line = "; " ++ header_text ++ "\n"; |
| 14 | const c_generated_line = "/* " ++ header_text ++ " */"; |
| 15 | const asm_generated_line = "; " ++ header_text; |
| 16 | |
| 17 | const os_newline = if (@import("builtin").os.tag == .windows) "\r\n" else "\n"; |
| 16 | 18 | |
| 17 | 19 | /// Table value is whether the value is used. |
| 18 | 20 | const ValueMap = std.array_hash_map.String(bool); |
| ... | ... | @@ -160,6 +162,15 @@ fn ensureAllValuesUsed( |
| 160 | 162 | if (any_errors) return error.MakeFailed; |
| 161 | 163 | } |
| 162 | 164 | |
| 165 | fn detectNewline(contents: []const u8) []const u8 { |
| 166 | return if (std.mem.endsWith(u8, contents, "\r\n")) |
| 167 | "\r\n" |
| 168 | else if (std.mem.endsWith(u8, contents, "\n")) |
| 169 | "\n" |
| 170 | else |
| 171 | os_newline; |
| 172 | } |
| 173 | |
| 163 | 174 | fn renderAutoConfUndef( |
| 164 | 175 | maker: *Maker, |
| 165 | 176 | step: *Step, |
| ... | ... | @@ -170,25 +181,28 @@ fn renderAutoConfUndef( |
| 170 | 181 | src_path: Path, |
| 171 | 182 | ) !void { |
| 172 | 183 | const conf = &maker.scanned_config.configuration; |
| 184 | const newline = detectNewline(contents); |
| 173 | 185 | |
| 174 | 186 | try w.writeAll(c_generated_line); |
| 187 | try w.writeAll(newline); |
| 175 | 188 | |
| 176 | 189 | var any_errors = false; |
| 177 | 190 | var line_index: u32 = 0; |
| 178 | 191 | var line_it = std.mem.splitScalar(u8, contents, '\n'); |
| 179 | | while (line_it.next()) |line| : (line_index += 1) { |
| 192 | while (line_it.next()) |raw_line| : (line_index += 1) { |
| 180 | 193 | const last_line = line_it.index == line_it.buffer.len; |
| 194 | const line = std.mem.trimEnd(u8, raw_line, "\r"); |
| 181 | 195 | |
| 182 | 196 | if (!std.mem.startsWith(u8, line, "#")) { |
| 183 | 197 | try w.writeAll(line); |
| 184 | | if (!last_line) try w.writeByte('\n'); |
| 198 | if (!last_line) try w.writeAll(newline); |
| 185 | 199 | continue; |
| 186 | 200 | } |
| 187 | 201 | var it = std.mem.tokenizeAny(u8, line[1..], " \t\r"); |
| 188 | 202 | const undef = it.next().?; |
| 189 | 203 | if (!std.mem.eql(u8, undef, "undef")) { |
| 190 | 204 | try w.writeAll(line); |
| 191 | | if (!last_line) try w.writeByte('\n'); |
| 205 | if (!last_line) try w.writeAll(newline); |
| 192 | 206 | continue; |
| 193 | 207 | } |
| 194 | 208 | const name = it.next().?; |
| ... | ... | @@ -200,7 +214,7 @@ fn renderAutoConfUndef( |
| 200 | 214 | continue; |
| 201 | 215 | }; |
| 202 | 216 | value_map.values()[index] = true; // Set to used. |
| 203 | | try renderValueC(conf, w, name, value_pairs[index].index); |
| 217 | try renderValueC(conf, w, newline, name, value_pairs[index].index); |
| 204 | 218 | } |
| 205 | 219 | |
| 206 | 220 | try ensureAllValuesUsed(maker, step, value_map, src_path); |
| ... | ... | @@ -218,14 +232,17 @@ fn renderAutoconfAt( |
| 218 | 232 | ) !void { |
| 219 | 233 | const w = &aw.writer; |
| 220 | 234 | const conf = &maker.scanned_config.configuration; |
| 235 | const newline = detectNewline(contents); |
| 221 | 236 | |
| 222 | 237 | try w.writeAll(c_generated_line); |
| 238 | try w.writeAll(newline); |
| 223 | 239 | |
| 224 | 240 | var any_errors = false; |
| 225 | 241 | var line_index: u32 = 0; |
| 226 | 242 | var line_it = std.mem.splitScalar(u8, contents, '\n'); |
| 227 | | while (line_it.next()) |line| : (line_index += 1) { |
| 243 | while (line_it.next()) |raw_line| : (line_index += 1) { |
| 228 | 244 | const last_line = line_it.index == line_it.buffer.len; |
| 245 | const line = std.mem.trimEnd(u8, raw_line, "\r"); |
| 229 | 246 | |
| 230 | 247 | const old_len = aw.written().len; |
| 231 | 248 | expandVariablesAutoconfAt(w, line, conf, value_pairs, value_map) catch |err| switch (err) { |
| ... | ... | @@ -246,7 +263,7 @@ fn renderAutoconfAt( |
| 246 | 263 | continue; |
| 247 | 264 | }, |
| 248 | 265 | }; |
| 249 | | if (!last_line) try w.writeByte('\n'); |
| 266 | if (!last_line) try w.writeAll(newline); |
| 250 | 267 | } |
| 251 | 268 | |
| 252 | 269 | try ensureAllValuesUsed(maker, step, value_map, src_path); |
| ... | ... | @@ -264,16 +281,19 @@ fn renderCmake( |
| 264 | 281 | src_path: Path, |
| 265 | 282 | ) !void { |
| 266 | 283 | const conf = &maker.scanned_config.configuration; |
| 284 | const newline = detectNewline(contents); |
| 267 | 285 | |
| 268 | 286 | try w.writeAll(c_generated_line); |
| 287 | try w.writeAll(newline); |
| 269 | 288 | |
| 270 | 289 | var any_errors = false; |
| 271 | 290 | var line_index: u32 = 0; |
| 272 | 291 | var line_it = std.mem.splitScalar(u8, contents, '\n'); |
| 273 | 292 | while (line_it.next()) |raw_line| : (line_index += 1) { |
| 274 | 293 | const last_line = line_it.index == line_it.buffer.len; |
| 294 | const stripped_line = std.mem.trimEnd(u8, raw_line, "\r"); |
| 275 | 295 | |
| 276 | | const line = expandVariablesCmake(arena, raw_line, conf, value_pairs, value_map) catch |err| switch (err) { |
| 296 | const line = expandVariablesCmake(arena, stripped_line, conf, value_pairs, value_map) catch |err| switch (err) { |
| 277 | 297 | error.InvalidCharacter => { |
| 278 | 298 | try step.addError(maker, "{f}:{d}: invalid character in a variable name", .{ |
| 279 | 299 | src_path, line_index + 1, |
| ... | ... | @@ -292,7 +312,7 @@ fn renderCmake( |
| 292 | 312 | |
| 293 | 313 | const line_start = std.mem.findNone(u8, line, " \t\r") orelse { |
| 294 | 314 | try w.writeAll(line); |
| 295 | | if (!last_line) try w.writeByte('\n'); |
| 315 | if (!last_line) try w.writeAll(newline); |
| 296 | 316 | continue; |
| 297 | 317 | }; |
| 298 | 318 | const whitespace_prefix = line[0..line_start]; |
| ... | ... | @@ -300,7 +320,7 @@ fn renderCmake( |
| 300 | 320 | |
| 301 | 321 | if (!std.mem.startsWith(u8, trimmed_line, "#")) { |
| 302 | 322 | try w.writeAll(line); |
| 303 | | if (!last_line) try w.writeByte('\n'); |
| 323 | if (!last_line) try w.writeAll(newline); |
| 304 | 324 | continue; |
| 305 | 325 | } |
| 306 | 326 | |
| ... | ... | @@ -313,7 +333,7 @@ fn renderCmake( |
| 313 | 333 | false |
| 314 | 334 | else { |
| 315 | 335 | try w.writeAll(line); |
| 316 | | if (!last_line) try w.writeByte('\n'); |
| 336 | if (!last_line) try w.writeAll(newline); |
| 317 | 337 | continue; |
| 318 | 338 | }; |
| 319 | 339 | |
| ... | ... | @@ -337,7 +357,7 @@ fn renderCmake( |
| 337 | 357 | try w.writeAll(whitespace_prefix); |
| 338 | 358 | |
| 339 | 359 | if (booldefine) { |
| 340 | | try renderValueCBool(w, name, switch (value.unpack(conf)) { |
| 360 | try renderValueCBool(w, newline, name, switch (value.unpack(conf)) { |
| 341 | 361 | .undef, .defined => false, |
| 342 | 362 | .bool => |b| b, |
| 343 | 363 | inline .u64, .i64 => |i| i != 0, |
| ... | ... | @@ -345,9 +365,9 @@ fn renderCmake( |
| 345 | 365 | .ident => false, |
| 346 | 366 | }); |
| 347 | 367 | } else if (value != .undef) { |
| 348 | | try renderValueCIdent(w, name, it.rest()); |
| 368 | try renderValueCIdent(w, newline, name, it.rest()); |
| 349 | 369 | } else { |
| 350 | | try renderValueC(conf, w, name, value); |
| 370 | try renderValueC(conf, w, newline, name, value); |
| 351 | 371 | } |
| 352 | 372 | } |
| 353 | 373 | |
| ... | ... | @@ -364,6 +384,7 @@ fn renderBlank( |
| 364 | 384 | include_guard_override: ?[]const u8, |
| 365 | 385 | ) !void { |
| 366 | 386 | try w.writeAll(c_generated_line); |
| 387 | try w.writeAll(os_newline); |
| 367 | 388 | |
| 368 | 389 | const include_guard_fmt: IncludeGuardFmt = .{ |
| 369 | 390 | .include_path = include_path, |
| ... | ... | @@ -376,7 +397,7 @@ fn renderBlank( |
| 376 | 397 | \\ |
| 377 | 398 | , .{include_guard_fmt}); |
| 378 | 399 | |
| 379 | | for (value_map.keys(), value_pairs) |name, pair| try renderValueC(conf, w, name, pair.index); |
| 400 | for (value_map.keys(), value_pairs) |name, pair| try renderValueC(conf, w, os_newline, name, pair.index); |
| 380 | 401 | |
| 381 | 402 | try w.print( |
| 382 | 403 | \\#endif /* {f} */ |
| ... | ... | @@ -405,41 +426,42 @@ fn renderNasm( |
| 405 | 426 | value_map: *const ValueMap, |
| 406 | 427 | ) !void { |
| 407 | 428 | try w.writeAll(asm_generated_line); |
| 408 | | for (value_map.keys(), value_pairs) |name, pair| try renderValueNasm(conf, w, name, pair.index); |
| 429 | try w.writeAll(os_newline); |
| 430 | for (value_map.keys(), value_pairs) |name, pair| try renderValueNasm(conf, w, os_newline, name, pair.index); |
| 409 | 431 | } |
| 410 | 432 | |
| 411 | | fn renderValueC(conf: *const Configuration, w: *Writer, name: []const u8, value: Value.Index) !void { |
| 433 | fn renderValueC(conf: *const Configuration, w: *Writer, newline: []const u8, name: []const u8, value: Value.Index) !void { |
| 412 | 434 | switch (value.unpack(conf)) { |
| 413 | | .undef => try w.print("/* #undef {s} */\n", .{name}), |
| 414 | | .defined => try w.print("#define {s}\n", .{name}), |
| 415 | | .bool => |b| return renderValueCBool(w, name, b), |
| 416 | | inline .u64, .i64 => |i| try w.print("#define {s} {d}\n", .{ name, i }), |
| 417 | | .ident => |ident| return renderValueCIdent(w, name, ident), |
| 418 | | .string => |string| try w.print("#define {s} \"{f}\"\n", .{ name, std.zig.fmtString(string) }), |
| 435 | .undef => try w.print("/* #undef {s} */{s}", .{ name, newline }), |
| 436 | .defined => try w.print("#define {s}{s}", .{ name, newline }), |
| 437 | .bool => |b| return renderValueCBool(w, newline, name, b), |
| 438 | inline .u64, .i64 => |i| try w.print("#define {s} {d}{s}", .{ name, i, newline }), |
| 439 | .ident => |ident| return renderValueCIdent(w, newline, name, ident), |
| 440 | .string => |string| try w.print("#define {s} \"{f}\"{s}", .{ name, std.zig.fmtString(string), newline }), |
| 419 | 441 | } |
| 420 | 442 | } |
| 421 | 443 | |
| 422 | | fn renderValueCIdent(w: *Writer, name: []const u8, ident: []const u8) Writer.Error!void { |
| 444 | fn renderValueCIdent(w: *Writer, newline: []const u8, name: []const u8, ident: []const u8) Writer.Error!void { |
| 423 | 445 | try w.print("#define {s}", .{name}); |
| 424 | 446 | if (ident.len > 0) { |
| 425 | 447 | try w.writeByte(' '); |
| 426 | 448 | try w.writeAll(ident); |
| 427 | 449 | } |
| 428 | | return w.writeByte('\n'); |
| 450 | return w.writeAll(newline); |
| 429 | 451 | } |
| 430 | 452 | |
| 431 | | fn renderValueCBool(w: *Writer, name: []const u8, b: bool) Writer.Error!void { |
| 432 | | return w.print("#define {s} {c}\n", .{ name, @as(u8, '0') + @intFromBool(b) }); |
| 453 | fn renderValueCBool(w: *Writer, newline: []const u8, name: []const u8, b: bool) Writer.Error!void { |
| 454 | return w.print("#define {s} {c}{s}", .{ name, @as(u8, '0') + @intFromBool(b), newline }); |
| 433 | 455 | } |
| 434 | 456 | |
| 435 | | fn renderValueNasm(conf: *const Configuration, w: *Writer, name: []const u8, value: Value.Index) !void { |
| 457 | fn renderValueNasm(conf: *const Configuration, w: *Writer, newline: []const u8, name: []const u8, value: Value.Index) !void { |
| 436 | 458 | switch (value.unpack(conf)) { |
| 437 | | .undef => try w.print("; %undef {s}\n", .{name}), |
| 438 | | .defined => try w.print("%define {s}\n", .{name}), |
| 439 | | .bool => |b| try w.print("%define {s} {c}\n", .{ name, @as(u8, '0') + @intFromBool(b) }), |
| 440 | | inline .u64, .i64 => |i| try w.print("%define {s} {d}\n", .{ name, i }), |
| 441 | | .ident => |ident| try w.print("%define {s} {s}\n", .{ name, ident }), |
| 442 | | .string => |string| try w.print("%define {s} \"{f}\"\n", .{ name, std.zig.fmtString(string) }), |
| 459 | .undef => try w.print("; %undef {s}{s}", .{ name, newline }), |
| 460 | .defined => try w.print("%define {s}{s}", .{ name, newline }), |
| 461 | .bool => |b| try w.print("%define {s} {c}{s}", .{ name, @as(u8, '0') + @intFromBool(b), newline }), |
| 462 | inline .u64, .i64 => |i| try w.print("%define {s} {d}{s}", .{ name, i, newline }), |
| 463 | .ident => |ident| try w.print("%define {s} {s}{s}", .{ name, ident, newline }), |
| 464 | .string => |string| try w.print("%define {s} \"{f}\"{s}", .{ name, std.zig.fmtString(string), newline }), |
| 443 | 465 | } |
| 444 | 466 | } |
| 445 | 467 | |