Skip to content

Fix #10699 - std.format with position with omitted second number does not work #10716

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions std/format/spec.d
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,16 @@ if (is(Unqual!Char == Char))

Counting starts with `1`. Set to `0` if not used. Default: `0`.
*/
ubyte indexStart;
ushort indexStart;

/**
Index of the last argument for positional parameter ranges.

Counting starts with `1`. Set to `0` if not used. Default: `0`.

The maximum value of this field is used as a sentinel to indicate the arguments' length.
*/
ubyte indexEnd;
ushort indexEnd;

version (StdDdoc)
{
Expand Down Expand Up @@ -851,6 +853,18 @@ if (is(Unqual!Char == Char))
assert(f.indexStart == 0);
}

// https://github.com/dlang/phobos/issues/10699
@safe pure unittest
{
import std.array : appender;
auto f = FormatSpec!char("%1:$d");
auto w = appender!(char[])();

f.writeUpToNextSpec(w);
assert(f.indexStart == 1);
assert(f.indexEnd == ushort.max);
}

/**
Helper function that returns a `FormatSpec` for a single format specifier.

Expand Down
23 changes: 20 additions & 3 deletions std/format/write.d
Original file line number Diff line number Diff line change
Expand Up @@ -648,9 +648,16 @@ uint formattedWrite(Writer, Char, Args...)(auto ref Writer w, const scope Char[]
break SWITCH;
}
default:
throw new FormatException(
text("Positional specifier %", spec.indexStart, '$', spec.spec,
" index exceeds ", Args.length));
if (spec.indexEnd == spec.indexEnd.max)
break;
else if (spec.indexEnd == spec.indexStart)
throw new FormatException(
text("Positional specifier %", spec.indexStart, '$', spec.spec,
" index exceeds ", Args.length));
else
throw new FormatException(
text("Positional specifier %", spec.indexStart, ":", spec.indexEnd, '$', spec.spec,
" index exceeds ", Args.length));
}
}
return currentArg;
Expand Down Expand Up @@ -1199,6 +1206,16 @@ if (isSomeString!(typeof(fmt)))
formattedWrite(stream, "%s", aa);
}

// https://github.com/dlang/phobos/issues/10699
@safe pure unittest
{
import std.array : appender;
auto w = appender!(char[])();

formattedWrite(w, "%1:$d", 1, 2, 3);
assert(w.data == "123");
}

/**
Formats a value of any type according to a format specifier and
writes the result to an output range.
Expand Down
Loading