diff options
| author | 2025-07-20 21:40:56 +0200 | |
|---|---|---|
| committer | 2025-07-21 18:52:54 +0200 | |
| commit | 6f103922a8133ba11773e6ad9a52e26e1d99b3e7 (patch) | |
| tree | 66bc5fa5fc36f20575be1e1a59ff890ab9c8b23e /clap.zig | |
| parent | chore: Update setup-zig to v2 (diff) | |
| download | zig-clap-6f103922a8133ba11773e6ad9a52e26e1d99b3e7.tar.gz zig-clap-6f103922a8133ba11773e6ad9a52e26e1d99b3e7.tar.xz zig-clap-6f103922a8133ba11773e6ad9a52e26e1d99b3e7.zip | |
Update to Zig 0.15.0-dev.1147
Diffstat (limited to 'clap.zig')
| -rw-r--r-- | clap.zig | 128 |
1 files changed, 62 insertions, 66 deletions
| @@ -542,7 +542,7 @@ pub const Diagnostic = struct { | |||
| 542 | 542 | ||
| 543 | /// Default diagnostics reporter when all you want is English with no colors. | 543 | /// Default diagnostics reporter when all you want is English with no colors. |
| 544 | /// Use this as a reference for implementing your own if needed. | 544 | /// Use this as a reference for implementing your own if needed. |
| 545 | pub fn report(diag: Diagnostic, stream: anytype, err: anyerror) !void { | 545 | pub fn report(diag: Diagnostic, stream: *std.Io.Writer, err: anyerror) !void { |
| 546 | var longest = diag.name.longest(); | 546 | var longest = diag.name.longest(); |
| 547 | if (longest.kind == .positional) | 547 | if (longest.kind == .positional) |
| 548 | longest.name = diag.arg; | 548 | longest.name = diag.arg; |
| @@ -567,9 +567,9 @@ pub const Diagnostic = struct { | |||
| 567 | 567 | ||
| 568 | fn testDiag(diag: Diagnostic, err: anyerror, expected: []const u8) !void { | 568 | fn testDiag(diag: Diagnostic, err: anyerror, expected: []const u8) !void { |
| 569 | var buf: [1024]u8 = undefined; | 569 | var buf: [1024]u8 = undefined; |
| 570 | var slice_stream = std.io.fixedBufferStream(&buf); | 570 | var writer = std.Io.Writer.fixed(&buf); |
| 571 | diag.report(slice_stream.writer(), err) catch unreachable; | 571 | diag.report(&writer, err) catch unreachable; |
| 572 | try std.testing.expectEqualStrings(expected, slice_stream.getWritten()); | 572 | try std.testing.expectEqualStrings(expected, writer.buffered()); |
| 573 | } | 573 | } |
| 574 | 574 | ||
| 575 | test "Diagnostic.report" { | 575 | test "Diagnostic.report" { |
| @@ -1263,9 +1263,9 @@ fn testErr( | |||
| 1263 | .diagnostic = &diag, | 1263 | .diagnostic = &diag, |
| 1264 | }) catch |err| { | 1264 | }) catch |err| { |
| 1265 | var buf: [1024]u8 = undefined; | 1265 | var buf: [1024]u8 = undefined; |
| 1266 | var fbs = std.io.fixedBufferStream(&buf); | 1266 | var writer = std.Io.Writer.fixed(&buf); |
| 1267 | diag.report(fbs.writer(), err) catch return error.TestFailed; | 1267 | diag.report(&writer, err) catch return error.TestFailed; |
| 1268 | try std.testing.expectEqualStrings(expected, fbs.getWritten()); | 1268 | try std.testing.expectEqualStrings(expected, writer.buffered()); |
| 1269 | return; | 1269 | return; |
| 1270 | }; | 1270 | }; |
| 1271 | 1271 | ||
| @@ -1366,7 +1366,7 @@ pub const HelpOptions = struct { | |||
| 1366 | /// The output can be constumized with the `opt` parameter. For default formatting `.{}` can | 1366 | /// The output can be constumized with the `opt` parameter. For default formatting `.{}` can |
| 1367 | /// be passed. | 1367 | /// be passed. |
| 1368 | pub fn help( | 1368 | pub fn help( |
| 1369 | writer: anytype, | 1369 | writer: *std.Io.Writer, |
| 1370 | comptime Id: type, | 1370 | comptime Id: type, |
| 1371 | params: []const Param(Id), | 1371 | params: []const Param(Id), |
| 1372 | opt: HelpOptions, | 1372 | opt: HelpOptions, |
| @@ -1374,8 +1374,9 @@ pub fn help( | |||
| 1374 | const max_spacing = blk: { | 1374 | const max_spacing = blk: { |
| 1375 | var res: usize = 0; | 1375 | var res: usize = 0; |
| 1376 | for (params) |param| { | 1376 | for (params) |param| { |
| 1377 | var cs = ccw.codepointCountingWriter(std.io.null_writer); | 1377 | var discarding = std.Io.Writer.Discarding.init(&.{}); |
| 1378 | try printParam(cs.writer(), Id, param); | 1378 | var cs = ccw.CodepointCountingWriter.init(&discarding.writer); |
| 1379 | try printParam(&cs.interface, Id, param); | ||
| 1379 | if (res < cs.codepoints_written) | 1380 | if (res < cs.codepoints_written) |
| 1380 | res = @intCast(cs.codepoints_written); | 1381 | res = @intCast(cs.codepoints_written); |
| 1381 | } | 1382 | } |
| @@ -1390,16 +1391,15 @@ pub fn help( | |||
| 1390 | var first_parameter: bool = true; | 1391 | var first_parameter: bool = true; |
| 1391 | for (params) |param| { | 1392 | for (params) |param| { |
| 1392 | if (!first_parameter) | 1393 | if (!first_parameter) |
| 1393 | try writer.writeByteNTimes('\n', opt.spacing_between_parameters); | 1394 | try writer.splatByteAll('\n', opt.spacing_between_parameters); |
| 1394 | 1395 | ||
| 1395 | first_parameter = false; | 1396 | first_parameter = false; |
| 1396 | try writer.writeByteNTimes(' ', opt.indent); | 1397 | try writer.splatByteAll(' ', opt.indent); |
| 1397 | 1398 | ||
| 1398 | var cw = ccw.codepointCountingWriter(writer); | 1399 | var cw = ccw.CodepointCountingWriter.init(writer); |
| 1399 | try printParam(cw.writer(), Id, param); | 1400 | try printParam(&cw.interface, Id, param); |
| 1400 | 1401 | ||
| 1401 | const Writer = DescriptionWriter(@TypeOf(writer)); | 1402 | var description_writer = DescriptionWriter{ |
| 1402 | var description_writer = Writer{ | ||
| 1403 | .underlying_writer = writer, | 1403 | .underlying_writer = writer, |
| 1404 | .indentation = description_indentation, | 1404 | .indentation = description_indentation, |
| 1405 | .printed_chars = @intCast(cw.codepoints_written), | 1405 | .printed_chars = @intCast(cw.codepoints_written), |
| @@ -1498,57 +1498,53 @@ pub fn help( | |||
| 1498 | } | 1498 | } |
| 1499 | } | 1499 | } |
| 1500 | 1500 | ||
| 1501 | fn DescriptionWriter(comptime UnderlyingWriter: type) type { | 1501 | const DescriptionWriter = struct { |
| 1502 | return struct { | 1502 | underlying_writer: *std.Io.Writer, |
| 1503 | pub const WriteError = UnderlyingWriter.Error; | ||
| 1504 | |||
| 1505 | underlying_writer: UnderlyingWriter, | ||
| 1506 | |||
| 1507 | indentation: usize, | ||
| 1508 | max_width: usize, | ||
| 1509 | printed_chars: usize, | ||
| 1510 | |||
| 1511 | pub fn writeWord(writer: *@This(), word: []const u8) !void { | ||
| 1512 | std.debug.assert(word.len != 0); | ||
| 1513 | 1503 | ||
| 1514 | var first_word = writer.printed_chars <= writer.indentation; | 1504 | indentation: usize, |
| 1515 | const chars_to_write = try std.unicode.utf8CountCodepoints(word) + @intFromBool(!first_word); | 1505 | max_width: usize, |
| 1516 | if (chars_to_write + writer.printed_chars > writer.max_width) { | 1506 | printed_chars: usize, |
| 1517 | // If the word does not fit on this line, then we insert a new line and print | ||
| 1518 | // it on that line. The only exception to this is if this was the first word. | ||
| 1519 | // If the first word does not fit on this line, then it will also not fit on the | ||
| 1520 | // next one. In that case, all we can really do is just output the word. | ||
| 1521 | if (!first_word) | ||
| 1522 | try writer.newline(); | ||
| 1523 | 1507 | ||
| 1524 | first_word = true; | 1508 | pub fn writeWord(writer: *@This(), word: []const u8) !void { |
| 1525 | } | 1509 | std.debug.assert(word.len != 0); |
| 1526 | 1510 | ||
| 1511 | var first_word = writer.printed_chars <= writer.indentation; | ||
| 1512 | const chars_to_write = try std.unicode.utf8CountCodepoints(word) + @intFromBool(!first_word); | ||
| 1513 | if (chars_to_write + writer.printed_chars > writer.max_width) { | ||
| 1514 | // If the word does not fit on this line, then we insert a new line and print | ||
| 1515 | // it on that line. The only exception to this is if this was the first word. | ||
| 1516 | // If the first word does not fit on this line, then it will also not fit on the | ||
| 1517 | // next one. In that case, all we can really do is just output the word. | ||
| 1527 | if (!first_word) | 1518 | if (!first_word) |
| 1528 | try writer.underlying_writer.writeAll(" "); | 1519 | try writer.newline(); |
| 1529 | 1520 | ||
| 1530 | try writer.ensureIndented(); | 1521 | first_word = true; |
| 1531 | try writer.underlying_writer.writeAll(word); | ||
| 1532 | writer.printed_chars += chars_to_write; | ||
| 1533 | } | 1522 | } |
| 1534 | 1523 | ||
| 1535 | pub fn newline(writer: *@This()) !void { | 1524 | if (!first_word) |
| 1536 | try writer.underlying_writer.writeAll("\n"); | 1525 | try writer.underlying_writer.writeAll(" "); |
| 1537 | writer.printed_chars = 0; | ||
| 1538 | } | ||
| 1539 | 1526 | ||
| 1540 | fn ensureIndented(writer: *@This()) !void { | 1527 | try writer.ensureIndented(); |
| 1541 | if (writer.printed_chars < writer.indentation) { | 1528 | try writer.underlying_writer.writeAll(word); |
| 1542 | const to_indent = writer.indentation - writer.printed_chars; | 1529 | writer.printed_chars += chars_to_write; |
| 1543 | try writer.underlying_writer.writeByteNTimes(' ', to_indent); | 1530 | } |
| 1544 | writer.printed_chars += to_indent; | 1531 | |
| 1545 | } | 1532 | pub fn newline(writer: *@This()) !void { |
| 1533 | try writer.underlying_writer.writeAll("\n"); | ||
| 1534 | writer.printed_chars = 0; | ||
| 1535 | } | ||
| 1536 | |||
| 1537 | fn ensureIndented(writer: *@This()) !void { | ||
| 1538 | if (writer.printed_chars < writer.indentation) { | ||
| 1539 | const to_indent = writer.indentation - writer.printed_chars; | ||
| 1540 | try writer.underlying_writer.splatByteAll(' ', to_indent); | ||
| 1541 | writer.printed_chars += to_indent; | ||
| 1546 | } | 1542 | } |
| 1547 | }; | 1543 | } |
| 1548 | } | 1544 | }; |
| 1549 | 1545 | ||
| 1550 | fn printParam( | 1546 | fn printParam( |
| 1551 | stream: anytype, | 1547 | stream: *std.Io.Writer, |
| 1552 | comptime Id: type, | 1548 | comptime Id: type, |
| 1553 | param: Param(Id), | 1549 | param: Param(Id), |
| 1554 | ) !void { | 1550 | ) !void { |
| @@ -1583,9 +1579,9 @@ fn testHelp(opt: HelpOptions, str: []const u8) !void { | |||
| 1583 | defer std.testing.allocator.free(params); | 1579 | defer std.testing.allocator.free(params); |
| 1584 | 1580 | ||
| 1585 | var buf: [2048]u8 = undefined; | 1581 | var buf: [2048]u8 = undefined; |
| 1586 | var fbs = std.io.fixedBufferStream(&buf); | 1582 | var writer = std.Io.Writer.fixed(&buf); |
| 1587 | try help(fbs.writer(), Help, params, opt); | 1583 | try help(&writer, Help, params, opt); |
| 1588 | try std.testing.expectEqualStrings(str, fbs.getWritten()); | 1584 | try std.testing.expectEqualStrings(str, writer.buffered()); |
| 1589 | } | 1585 | } |
| 1590 | 1586 | ||
| 1591 | test "clap.help" { | 1587 | test "clap.help" { |
| @@ -2015,9 +2011,9 @@ test "clap.help" { | |||
| 2015 | /// | 2011 | /// |
| 2016 | /// First all none value taking parameters, which have a short name are printed, then non | 2012 | /// First all none value taking parameters, which have a short name are printed, then non |
| 2017 | /// positional parameters and finally the positional. | 2013 | /// positional parameters and finally the positional. |
| 2018 | pub fn usage(stream: anytype, comptime Id: type, params: []const Param(Id)) !void { | 2014 | pub fn usage(stream: *std.Io.Writer, comptime Id: type, params: []const Param(Id)) !void { |
| 2019 | var cos = ccw.codepointCountingWriter(stream); | 2015 | var cos = ccw.CodepointCountingWriter.init(stream); |
| 2020 | const cs = cos.writer(); | 2016 | const cs = &cos.interface; |
| 2021 | for (params) |param| { | 2017 | for (params) |param| { |
| 2022 | const name = param.names.short orelse continue; | 2018 | const name = param.names.short orelse continue; |
| 2023 | if (param.takes_value != .none) | 2019 | if (param.takes_value != .none) |
| @@ -2060,7 +2056,7 @@ pub fn usage(stream: anytype, comptime Id: type, params: []const Param(Id)) !voi | |||
| 2060 | try cs.writeAll("..."); | 2056 | try cs.writeAll("..."); |
| 2061 | } | 2057 | } |
| 2062 | 2058 | ||
| 2063 | try cs.writeByte(']'); | 2059 | try cs.writeAll("]"); |
| 2064 | } | 2060 | } |
| 2065 | 2061 | ||
| 2066 | if (!has_positionals) | 2062 | if (!has_positionals) |
| @@ -2083,9 +2079,9 @@ pub fn usage(stream: anytype, comptime Id: type, params: []const Param(Id)) !voi | |||
| 2083 | 2079 | ||
| 2084 | fn testUsage(expected: []const u8, params: []const Param(Help)) !void { | 2080 | fn testUsage(expected: []const u8, params: []const Param(Help)) !void { |
| 2085 | var buf: [1024]u8 = undefined; | 2081 | var buf: [1024]u8 = undefined; |
| 2086 | var fbs = std.io.fixedBufferStream(&buf); | 2082 | var writer = std.Io.Writer.fixed(&buf); |
| 2087 | try usage(fbs.writer(), Help, params); | 2083 | try usage(&writer, Help, params); |
| 2088 | try std.testing.expectEqualStrings(expected, fbs.getWritten()); | 2084 | try std.testing.expectEqualStrings(expected, writer.buffered()); |
| 2089 | } | 2085 | } |
| 2090 | 2086 | ||
| 2091 | test "usage" { | 2087 | test "usage" { |