| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const ConfigHeader = @This(); |
| 3 | 3 | const Step = std.Build.Step; |
| 4 | const Allocator = std.mem.Allocator; |
| 4 | 5 | |
| 5 | 6 | pub const Style = union(enum) { |
| 6 | 7 | /// The configure format supported by autotools. It uses `#undef foo` to |
| ... | ... | @@ -292,18 +293,27 @@ fn render_cmake( |
| 292 | 293 | values: std.StringArrayHashMap(Value), |
| 293 | 294 | src_path: []const u8, |
| 294 | 295 | ) !void { |
| 296 | var build = step.owner; |
| 297 | var allocator = build.allocator; |
| 298 | |
| 295 | 299 | var values_copy = try values.clone(); |
| 296 | 300 | defer values_copy.deinit(); |
| 297 | 301 | |
| 298 | 302 | var any_errors = false; |
| 299 | 303 | var line_index: u32 = 0; |
| 300 | 304 | var line_it = std.mem.splitScalar(u8, contents, '\n'); |
| 301 | | while (line_it.next()) |line| : (line_index += 1) { |
| 305 | while (line_it.next()) |raw_line| : (line_index += 1) { |
| 302 | 306 | // if we reached the end of the buffer there is nothing worth doing anymore |
| 303 | 307 | if (line_it.index == line_it.buffer.len) { |
| 304 | 308 | continue; |
| 305 | 309 | } |
| 306 | 310 | |
| 311 | const first_pass = replace_variables(allocator, raw_line, values, "@", "@") catch @panic("Failed to substitute"); |
| 312 | const line = replace_variables(allocator, first_pass, values, "${", "}") catch @panic("Failed to substitute"); |
| 313 | |
| 314 | allocator.free(first_pass); |
| 315 | defer allocator.free(line); |
| 316 | |
| 307 | 317 | if (!std.mem.startsWith(u8, line, "#")) { |
| 308 | 318 | try output.appendSlice(line); |
| 309 | 319 | try output.appendSlice("\n"); |
| ... | ... | @@ -491,3 +501,65 @@ fn renderValueNasm(output: *std.ArrayList(u8), name: []const u8, value: Value) ! |
| 491 | 501 | }, |
| 492 | 502 | } |
| 493 | 503 | } |
| 504 | |
| 505 | fn replace_variables( |
| 506 | allocator: Allocator, |
| 507 | contents: []const u8, |
| 508 | values: std.StringArrayHashMap(Value), |
| 509 | prefix: []const u8, |
| 510 | suffix: []const u8, |
| 511 | ) ![]const u8 { |
| 512 | var content_buf = allocator.dupe(u8, contents) catch @panic("OOM"); |
| 513 | |
| 514 | var last_index: usize = 0; |
| 515 | while (std.mem.indexOfPos(u8, content_buf, last_index, prefix)) |prefix_index| { |
| 516 | const start_index = prefix_index + prefix.len; |
| 517 | if (std.mem.indexOfPos(u8, content_buf, start_index, suffix)) |suffix_index| { |
| 518 | const end_index = suffix_index + suffix.len; |
| 519 | |
| 520 | const beginline = content_buf[0..prefix_index]; |
| 521 | const endline = content_buf[end_index..]; |
| 522 | const key = content_buf[start_index..suffix_index]; |
| 523 | const value = values.get(key) orelse .undef; |
| 524 | |
| 525 | switch (value) { |
| 526 | .boolean => |b| { |
| 527 | const buf = try std.fmt.allocPrint(allocator, "{s}{}{s}", .{ beginline, @intFromBool(b), endline }); |
| 528 | last_index = start_index + 1; |
| 529 | |
| 530 | allocator.free(content_buf); |
| 531 | content_buf = buf; |
| 532 | }, |
| 533 | .int => |i| { |
| 534 | const buf = try std.fmt.allocPrint(allocator, "{s}{}{s}", .{ beginline, i, endline }); |
| 535 | const isNegative = i < 0; |
| 536 | const digits = (if (0 < i) std.math.log10(std.math.absCast(i)) else 0) + 1; |
| 537 | last_index = start_index + @intFromBool(isNegative) + digits + 1; |
| 538 | |
| 539 | allocator.free(content_buf); |
| 540 | content_buf = buf; |
| 541 | }, |
| 542 | .string => |string| { |
| 543 | const buf = try std.fmt.allocPrint(allocator, "{s}{s}{s}", .{ beginline, string, endline }); |
| 544 | last_index = start_index + string.len + 1; |
| 545 | |
| 546 | allocator.free(content_buf); |
| 547 | content_buf = buf; |
| 548 | }, |
| 549 | |
| 550 | else => { |
| 551 | const buf = try std.fmt.allocPrint(allocator, "{s}{s}", .{ beginline, endline }); |
| 552 | last_index = start_index + 1; |
| 553 | |
| 554 | allocator.free(content_buf); |
| 555 | content_buf = buf; |
| 556 | }, |
| 557 | } |
| 558 | continue; |
| 559 | } |
| 560 | |
| 561 | last_index = start_index + 1; |
| 562 | } |
| 563 | |
| 564 | return content_buf; |
| 565 | } |