Skip to content

Commit 205256a

Browse files
authored
Fix #10699 - std.format with position with omitted second number does not work (#10716)
1 parent 530660b commit 205256a

File tree

2 files changed

+36
-5
lines changed

2 files changed

+36
-5
lines changed

std/format/spec.d

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,14 +127,16 @@ if (is(Unqual!Char == Char))
127127
128128
Counting starts with `1`. Set to `0` if not used. Default: `0`.
129129
*/
130-
ubyte indexStart;
130+
ushort indexStart;
131131

132132
/**
133133
Index of the last argument for positional parameter ranges.
134134
135135
Counting starts with `1`. Set to `0` if not used. Default: `0`.
136+
137+
The maximum value of this field is used as a sentinel to indicate the arguments' length.
136138
*/
137-
ubyte indexEnd;
139+
ushort indexEnd;
138140

139141
version (StdDdoc)
140142
{
@@ -851,6 +853,18 @@ if (is(Unqual!Char == Char))
851853
assert(f.indexStart == 0);
852854
}
853855

856+
// https://github.com/dlang/phobos/issues/10699
857+
@safe pure unittest
858+
{
859+
import std.array : appender;
860+
auto f = FormatSpec!char("%1:$d");
861+
auto w = appender!(char[])();
862+
863+
f.writeUpToNextSpec(w);
864+
assert(f.indexStart == 1);
865+
assert(f.indexEnd == ushort.max);
866+
}
867+
854868
/**
855869
Helper function that returns a `FormatSpec` for a single format specifier.
856870

std/format/write.d

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -648,9 +648,16 @@ uint formattedWrite(Writer, Char, Args...)(auto ref Writer w, const scope Char[]
648648
break SWITCH;
649649
}
650650
default:
651-
throw new FormatException(
652-
text("Positional specifier %", spec.indexStart, '$', spec.spec,
653-
" index exceeds ", Args.length));
651+
if (spec.indexEnd == spec.indexEnd.max)
652+
break;
653+
else if (spec.indexEnd == spec.indexStart)
654+
throw new FormatException(
655+
text("Positional specifier %", spec.indexStart, '$', spec.spec,
656+
" index exceeds ", Args.length));
657+
else
658+
throw new FormatException(
659+
text("Positional specifier %", spec.indexStart, ":", spec.indexEnd, '$', spec.spec,
660+
" index exceeds ", Args.length));
654661
}
655662
}
656663
return currentArg;
@@ -1199,6 +1206,16 @@ if (isSomeString!(typeof(fmt)))
11991206
formattedWrite(stream, "%s", aa);
12001207
}
12011208

1209+
// https://github.com/dlang/phobos/issues/10699
1210+
@safe pure unittest
1211+
{
1212+
import std.array : appender;
1213+
auto w = appender!(char[])();
1214+
1215+
formattedWrite(w, "%1:$d", 1, 2, 3);
1216+
assert(w.data == "123");
1217+
}
1218+
12021219
/**
12031220
Formats a value of any type according to a format specifier and
12041221
writes the result to an output range.

0 commit comments

Comments
 (0)