Skip to content

Commit 8d899bf

Browse files
committed
fix(zig): align --mappings JSON/CSV with the C/Lua/Node canonical
Zig was the lone outlier: JSON omitted the hex+dec fields, the ascii column was the bare char (vs single-quoted '!'), and CSV wrapped fields in quotes without doubling internal quotes -> byte 0x22 produced the malformed row """. Now: - ascii column matches C's ascii_name_for_byte (single-quoted printables, SPACE/DEL, 0xNN for high bytes), via a generated table; - JSON includes byte,hex,dec,ascii,mapping (was byte,ascii,mapping); - CSV and JSON fields are properly escaped (csvEscapeInto/jsonEscapeInto). --mappings-csv is now byte-identical to Lua; --mappings-json carries the same field set and is valid JSON.
1 parent aef111f commit 8d899bf

1 file changed

Lines changed: 68 additions & 27 deletions

File tree

src/zig/main.zig

Lines changed: 68 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -408,61 +408,102 @@ const ascii_names = [_][]const u8{
408408
"BS", "TAB", "LF", "VT", "FF", "CR", "SO", "SI",
409409
"DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
410410
"CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US",
411-
"SPACE", "!", "\"", "#", "$", "%", "&", "'",
412-
"(", ")", "*", "+", ",", "-", ".", "/",
413-
"0", "1", "2", "3", "4", "5", "6", "7",
414-
"8", "9", ":", ";", "<", "=", ">", "?",
415-
"@", "A", "B", "C", "D", "E", "F", "G",
416-
"H", "I", "J", "K", "L", "M", "N", "O",
417-
"P", "Q", "R", "S", "T", "U", "V", "W",
418-
"X", "Y", "Z", "[", "\\", "]", "^", "_",
419-
"`", "a", "b", "c", "d", "e", "f", "g",
420-
"h", "i", "j", "k", "l", "m", "n", "o",
421-
"p", "q", "r", "s", "t", "u", "v", "w",
422-
"x", "y", "z", "{", "|", "}", "~", "DEL",
411+
"SPACE", "'!'", "'\"'", "'#'", "'$'", "'%'", "'&'", "'\\''",
412+
"'('", "')'", "'*'", "'+'", "','", "'-'", "'.'", "'/'",
413+
"'0'", "'1'", "'2'", "'3'", "'4'", "'5'", "'6'", "'7'",
414+
"'8'", "'9'", "':'", "';'", "'<'", "'='", "'>'", "'?'",
415+
"'@'", "'A'", "'B'", "'C'", "'D'", "'E'", "'F'", "'G'",
416+
"'H'", "'I'", "'J'", "'K'", "'L'", "'M'", "'N'", "'O'",
417+
"'P'", "'Q'", "'R'", "'S'", "'T'", "'U'", "'V'", "'W'",
418+
"'X'", "'Y'", "'Z'", "'['", "'\\\\'", "']'", "'^'", "'_'",
419+
"'`'", "'a'", "'b'", "'c'", "'d'", "'e'", "'f'", "'g'",
420+
"'h'", "'i'", "'j'", "'k'", "'l'", "'m'", "'n'", "'o'",
421+
"'p'", "'q'", "'r'", "'s'", "'t'", "'u'", "'v'", "'w'",
422+
"'x'", "'y'", "'z'", "'{'", "'|'", "'}'", "'~'", "DEL",
423423
};
424424

425425
fn writeStdout(data: []const u8) void {
426426
rawWriteAll(std.Io.File.stdout(), data);
427427
}
428428

429+
// Append `s` to `buf` (at *len), doubling any '"' so the result is a safe CSV
430+
// field body (RFC 4180). Returns the new length.
431+
fn csvEscapeInto(buf: []u8, len_in: usize, s: []const u8) usize {
432+
var len = len_in;
433+
for (s) |c| {
434+
if (c == '"') {
435+
if (len + 2 > buf.len) return len;
436+
buf[len] = '"';
437+
buf[len + 1] = '"';
438+
len += 2;
439+
} else {
440+
if (len + 1 > buf.len) return len;
441+
buf[len] = c;
442+
len += 1;
443+
}
444+
}
445+
return len;
446+
}
447+
448+
// Append `s` to `buf`, escaping '"' and '\\' for a JSON string body.
449+
fn jsonEscapeInto(buf: []u8, len_in: usize, s: []const u8) usize {
450+
var len = len_in;
451+
for (s) |c| {
452+
if (c == '"' or c == '\\') {
453+
if (len + 2 > buf.len) return len;
454+
buf[len] = '\\';
455+
buf[len + 1] = c;
456+
len += 2;
457+
} else {
458+
if (len + 1 > buf.len) return len;
459+
buf[len] = c;
460+
len += 1;
461+
}
462+
}
463+
return len;
464+
}
465+
429466
fn printMappings(mode: MappingsMode) !void {
430467
var line_buf: [256]u8 = undefined;
431468
switch (mode) {
432469
.table => {
433470
writeStdout("Byte Dec ASCII Mapping\n");
434471
for (0..256) |i| {
435-
const ascii_name = if (i < 128) ascii_names[i] else "";
472+
var hex_ascii: [8]u8 = undefined;
473+
const ascii_name = if (i < 128) ascii_names[i] else (std.fmt.bufPrint(&hex_ascii, "0x{X:0>2}", .{i}) catch "");
436474
const line = std.fmt.bufPrint(&line_buf, "0x{X:0>2} {d:<5} {s:<12} {s}\n", .{
437475
i, i, ascii_name, pb.character_map[i],
438476
}) catch continue;
439477
writeStdout(line);
440478
}
441479
},
442480
.json => {
443-
writeStdout("[\n");
481+
writeStdout("[");
444482
for (0..256) |i| {
445-
const raw_ascii = if (i < 128) ascii_names[i] else "";
446-
// Escape special JSON characters
447-
const ascii_escaped = if (std.mem.eql(u8, raw_ascii, "\""))
448-
"\\\""
449-
else if (std.mem.eql(u8, raw_ascii, "\\"))
450-
"\\\\"
451-
else
452-
raw_ascii;
453-
const line = std.fmt.bufPrint(&line_buf, " {{\"byte\": {d}, \"ascii\": \"{s}\", \"mapping\": \"{s}\"}}{s}\n", .{
454-
i, ascii_escaped, pb.character_map[i], if (i < 255) "," else "",
483+
var hex_ascii: [8]u8 = undefined;
484+
const raw_ascii = if (i < 128) ascii_names[i] else (std.fmt.bufPrint(&hex_ascii, "0x{X:0>2}", .{i}) catch "");
485+
var ab: [64]u8 = undefined;
486+
const ascii_len = jsonEscapeInto(&ab, 0, raw_ascii);
487+
var mb: [64]u8 = undefined;
488+
const map_len = jsonEscapeInto(&mb, 0, pb.character_map[i]);
489+
const line = std.fmt.bufPrint(&line_buf, "{s}\n {{\"byte\": {d}, \"hex\": \"0x{X:0>2}\", \"dec\": {d}, \"ascii\": \"{s}\", \"mapping\": \"{s}\"}}", .{
490+
if (i == 0) "" else ",", i, i, i, ab[0..ascii_len], mb[0..map_len],
455491
}) catch continue;
456492
writeStdout(line);
457493
}
458-
writeStdout("]\n");
494+
writeStdout("\n]\n");
459495
},
460496
.csv => {
461497
writeStdout("byte,hex,dec,ascii,mapping\n");
462498
for (0..256) |i| {
463-
const raw_ascii = if (i < 128) ascii_names[i] else "";
499+
var hex_ascii: [8]u8 = undefined;
500+
const raw_ascii = if (i < 128) ascii_names[i] else (std.fmt.bufPrint(&hex_ascii, "0x{X:0>2}", .{i}) catch "");
501+
var ab: [64]u8 = undefined;
502+
const ascii_len = csvEscapeInto(&ab, 0, raw_ascii);
503+
var mb: [64]u8 = undefined;
504+
const map_len = csvEscapeInto(&mb, 0, pb.character_map[i]);
464505
const line = std.fmt.bufPrint(&line_buf, "{d},0x{X:0>2},{d},\"{s}\",\"{s}\"\n", .{
465-
i, i, i, raw_ascii, pb.character_map[i],
506+
i, i, i, ab[0..ascii_len], mb[0..map_len],
466507
}) catch continue;
467508
writeStdout(line);
468509
}

0 commit comments

Comments
 (0)