mirror of
https://github.com/dlang/phobos.git
synced 2025-05-10 05:41:56 +03:00
Merge pull request #939 from 9rnsr/replace_format
Replacement std.string.format and sformat implementations in November 2012
This commit is contained in:
commit
d6100b404f
3 changed files with 150 additions and 189 deletions
|
@ -33660,7 +33660,7 @@ unittest
|
|||
this.value = value;
|
||||
}
|
||||
|
||||
string toString()
|
||||
string toString() const
|
||||
{
|
||||
return to!string(value);
|
||||
}
|
||||
|
@ -33963,7 +33963,7 @@ unittest
|
|||
return this;
|
||||
}
|
||||
|
||||
string toString()
|
||||
string toString() const
|
||||
{
|
||||
return to!string(value);
|
||||
}
|
||||
|
@ -33987,7 +33987,7 @@ unittest
|
|||
return IntWrapper_BadAssign(mixin("old " ~ op ~ " rhs.value"));
|
||||
}
|
||||
|
||||
string toString()
|
||||
string toString() const
|
||||
{
|
||||
return to!string(value);
|
||||
}
|
||||
|
@ -34009,7 +34009,7 @@ unittest
|
|||
return IntWrapper_BadReturn(rhs.value);
|
||||
}
|
||||
|
||||
string toString()
|
||||
string toString() const
|
||||
{
|
||||
return to!string(value);
|
||||
}
|
||||
|
|
92
std/format.d
92
std/format.d
|
@ -5454,20 +5454,20 @@ unittest
|
|||
|
||||
debug(format) printf("std.format.format.unittest\n");
|
||||
|
||||
s = std.string.format("hello world! %s %s ", true, 57, 1_000_000_000, 'x', " foo");
|
||||
s = std.string.format("hello world! %s %s %s%s%s", true, 57, 1_000_000_000, 'x', " foo");
|
||||
assert(s == "hello world! true 57 1000000000x foo");
|
||||
|
||||
s = std.string.format(1.67, " %A ", -1.28, float.nan);
|
||||
s = std.string.format("%s %A %s", 1.67, -1.28, float.nan);
|
||||
/* The host C library is used to format floats.
|
||||
* C99 doesn't specify what the hex digit before the decimal point
|
||||
* is for %A.
|
||||
*/
|
||||
version (linux)
|
||||
assert(s == "1.67 -0XA.3D70A3D70A3D8P-3 nan");
|
||||
else version (OSX)
|
||||
assert(s == "1.67 -0XA.3D70A3D70A3D8P-3 nan", s);
|
||||
else
|
||||
assert(s == "1.67 -0X1.47AE147AE147BP+0 nan");
|
||||
//version (linux)
|
||||
// assert(s == "1.67 -0XA.3D70A3D70A3D8P-3 nan");
|
||||
//else version (OSX)
|
||||
// assert(s == "1.67 -0XA.3D70A3D70A3D8P-3 nan", s);
|
||||
//else
|
||||
assert(s == "1.67 -0X1.47AE147AE147BP+0 nan", s);
|
||||
|
||||
s = std.string.format("%x %X", 0x1234AF, 0xAFAFAFAF);
|
||||
assert(s == "1234af AFAFAFAF");
|
||||
|
@ -5478,19 +5478,19 @@ unittest
|
|||
s = std.string.format("%d %s", 0x1234AF, 0xAFAFAFAF);
|
||||
assert(s == "1193135 2947526575");
|
||||
|
||||
version(X86_64)
|
||||
{
|
||||
pragma(msg, "several format tests disabled on x86_64 due to bug 5625");
|
||||
}
|
||||
else
|
||||
{
|
||||
//version(X86_64)
|
||||
//{
|
||||
// pragma(msg, "several format tests disabled on x86_64 due to bug 5625");
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
s = std.string.format("%s", 1.2 + 3.4i);
|
||||
assert(s == "1.2+3.4i");
|
||||
assert(s == "1.2+3.4i", s);
|
||||
|
||||
s = std.string.format("%x %X", 1.32, 6.78f);
|
||||
assert(s == "3ff51eb851eb851f 40D8F5C3");
|
||||
//s = std.string.format("%x %X", 1.32, 6.78f);
|
||||
//assert(s == "3ff51eb851eb851f 40D8F5C3");
|
||||
|
||||
}
|
||||
//}
|
||||
|
||||
s = std.string.format("%#06.*f",2,12.345);
|
||||
assert(s == "012.35");
|
||||
|
@ -5558,63 +5558,57 @@ unittest
|
|||
arrbyte[0] = 100;
|
||||
arrbyte[1] = -99;
|
||||
arrbyte[3] = 0;
|
||||
r = std.string.format(arrbyte);
|
||||
assert(r == "[100,-99,0,0]");
|
||||
r = std.string.format("%s", arrbyte);
|
||||
assert(r == "[100, -99, 0, 0]");
|
||||
|
||||
ubyte[] arrubyte = new ubyte[4];
|
||||
arrubyte[0] = 100;
|
||||
arrubyte[1] = 200;
|
||||
arrubyte[3] = 0;
|
||||
r = std.string.format(arrubyte);
|
||||
assert(r == "[100,200,0,0]");
|
||||
r = std.string.format("%s", arrubyte);
|
||||
assert(r == "[100, 200, 0, 0]");
|
||||
|
||||
short[] arrshort = new short[4];
|
||||
arrshort[0] = 100;
|
||||
arrshort[1] = -999;
|
||||
arrshort[3] = 0;
|
||||
r = std.string.format(arrshort);
|
||||
assert(r == "[100,-999,0,0]");
|
||||
r = std.string.format("%s",arrshort);
|
||||
assert(r == "[100,-999,0,0]");
|
||||
r = std.string.format("%s", arrshort);
|
||||
assert(r == "[100, -999, 0, 0]");
|
||||
|
||||
ushort[] arrushort = new ushort[4];
|
||||
arrushort[0] = 100;
|
||||
arrushort[1] = 20_000;
|
||||
arrushort[3] = 0;
|
||||
r = std.string.format(arrushort);
|
||||
assert(r == "[100,20000,0,0]");
|
||||
r = std.string.format("%s", arrushort);
|
||||
assert(r == "[100, 20000, 0, 0]");
|
||||
|
||||
int[] arrint = new int[4];
|
||||
arrint[0] = 100;
|
||||
arrint[1] = -999;
|
||||
arrint[3] = 0;
|
||||
r = std.string.format(arrint);
|
||||
assert(r == "[100,-999,0,0]");
|
||||
r = std.string.format("%s",arrint);
|
||||
assert(r == "[100,-999,0,0]");
|
||||
r = std.string.format("%s", arrint);
|
||||
assert(r == "[100, -999, 0, 0]");
|
||||
|
||||
long[] arrlong = new long[4];
|
||||
arrlong[0] = 100;
|
||||
arrlong[1] = -999;
|
||||
arrlong[3] = 0;
|
||||
r = std.string.format(arrlong);
|
||||
assert(r == "[100,-999,0,0]");
|
||||
r = std.string.format("%s",arrlong);
|
||||
assert(r == "[100,-999,0,0]");
|
||||
r = std.string.format("%s", arrlong);
|
||||
assert(r == "[100, -999, 0, 0]");
|
||||
|
||||
ulong[] arrulong = new ulong[4];
|
||||
arrulong[0] = 100;
|
||||
arrulong[1] = 999;
|
||||
arrulong[3] = 0;
|
||||
r = std.string.format(arrulong);
|
||||
assert(r == "[100,999,0,0]");
|
||||
r = std.string.format("%s", arrulong);
|
||||
assert(r == "[100, 999, 0, 0]");
|
||||
|
||||
string[] arr2 = new string[4];
|
||||
arr2[0] = "hello";
|
||||
arr2[1] = "world";
|
||||
arr2[3] = "foo";
|
||||
r = std.string.format(arr2);
|
||||
assert(r == "[hello,world,,foo]");
|
||||
r = std.string.format("%s", arr2);
|
||||
assert(r == `["hello", "world", "", "foo"]`);
|
||||
|
||||
r = std.string.format("%.8d", 7);
|
||||
assert(r == "00000007");
|
||||
|
@ -5643,7 +5637,7 @@ unittest
|
|||
assert(r == "ghi");
|
||||
|
||||
void* p = cast(void*)0xDEADBEEF;
|
||||
r = std.string.format(p);
|
||||
r = std.string.format("%s", p);
|
||||
assert(r == "DEADBEEF");
|
||||
|
||||
r = std.string.format("%#x", 0xabcd);
|
||||
|
@ -5716,21 +5710,21 @@ unittest
|
|||
assert(r == "F");
|
||||
|
||||
Object c = null;
|
||||
r = std.string.format(c);
|
||||
r = std.string.format("%s", c);
|
||||
assert(r == "null");
|
||||
|
||||
enum TestEnum
|
||||
{
|
||||
Value1, Value2
|
||||
Value1, Value2
|
||||
}
|
||||
r = std.string.format("%s", TestEnum.Value2);
|
||||
assert(r == "1");
|
||||
assert(r == "Value2");
|
||||
|
||||
immutable(char[5])[int] aa = ([3:"hello", 4:"betty"]);
|
||||
r = std.string.format("%s", aa.values);
|
||||
assert(r == "[[h,e,l,l,o],[b,e,t,t,y]]");
|
||||
assert(r == `["hello", "betty"]`);
|
||||
r = std.string.format("%s", aa);
|
||||
assert(r == "[3:[h,e,l,l,o],4:[b,e,t,t,y]]");
|
||||
assert(r == `[3:"hello", 4:"betty"]`);
|
||||
|
||||
static const dchar[] ds = ['a','b'];
|
||||
for (int j = 0; j < ds.length; ++j)
|
||||
|
@ -5742,11 +5736,11 @@ unittest
|
|||
assert(r == " 98");
|
||||
}
|
||||
|
||||
r = std.string.format(">%14d<, ", 15, [1,2,3]);
|
||||
assert(r == "> 15<, [1,2,3]");
|
||||
r = std.string.format(">%14d<, %s", 15, [1,2,3]);
|
||||
assert(r == "> 15<, [1, 2, 3]");
|
||||
|
||||
assert(std.string.format("%8s", "bar") == " bar");
|
||||
assert(std.string.format("%8s", "b\u00e9ll\u00f4") == " b\u00e9ll\u00f4");
|
||||
assert(std.string.format("%8s", "b\u00e9ll\u00f4") == " b\u00e9ll\u00f4");
|
||||
}
|
||||
|
||||
unittest
|
||||
|
|
239
std/string.d
239
std/string.d
|
@ -1179,7 +1179,7 @@ deprecated S capwords(S)(S s) if (isSomeString!S)
|
|||
return cast(S)retval.data;
|
||||
}
|
||||
|
||||
unittest
|
||||
deprecated unittest
|
||||
{
|
||||
debug(string) printf("string.capwords.unittest\n");
|
||||
|
||||
|
@ -2482,7 +2482,7 @@ unittest
|
|||
//Explicitly undocumented. Do not use. To be removed in March 2013.
|
||||
deprecated("Please use std.string.makeTrans instead.") alias makeTrans maketrans;
|
||||
|
||||
unittest
|
||||
deprecated unittest
|
||||
{
|
||||
debug(string) printf("string.translate.unittest\n");
|
||||
|
||||
|
@ -2501,83 +2501,55 @@ unittest
|
|||
}
|
||||
|
||||
|
||||
// @@@BUG@@@ workaround for bugzilla 2479
|
||||
private string bug2479format(TypeInfo[] arguments, va_list argptr)
|
||||
{
|
||||
char[] s;
|
||||
|
||||
void putc(dchar c)
|
||||
{
|
||||
std.utf.encode(s, c);
|
||||
}
|
||||
std.format.doFormat(&putc, arguments, argptr);
|
||||
return assumeUnique(s);
|
||||
}
|
||||
|
||||
// @@@BUG@@@ workaround for bugzilla 2479
|
||||
private char[] bug2479sformat(char[] s, TypeInfo[] arguments, va_list argptr)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
void putc(dchar c)
|
||||
{
|
||||
if(std.ascii.isASCII(c))
|
||||
{
|
||||
if (i >= s.length)
|
||||
onRangeError("std.string.sformat", 0);
|
||||
s[i] = cast(char)c;
|
||||
++i;
|
||||
}
|
||||
else
|
||||
{ char[4] buf;
|
||||
auto b = std.utf.toUTF8(buf, c);
|
||||
if (i + b.length > s.length)
|
||||
onRangeError("std.string.sformat", 0);
|
||||
s[i..i+b.length] = b[];
|
||||
i += b.length;
|
||||
}
|
||||
}
|
||||
|
||||
std.format.doFormat(&putc, arguments, argptr);
|
||||
return s[0 .. i];
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* Format arguments into a string.
|
||||
*
|
||||
* $(RED format's current implementation is scheduled for replacement in
|
||||
* November 2012. It will then be replaced with $(LREF xformat)'s implementation.
|
||||
* This will be seamless for most code, but it will make it so that the
|
||||
* only argument that can be a format string is the first one, so any
|
||||
* code which uses multiple format strings will break. Please change
|
||||
* $(RED format's current implementation has been replaced with $(LREF xformat)'s
|
||||
* implementation. in November 2012.
|
||||
* This is seamless for most code, but it makes it so that the only
|
||||
* argument that can be a format string is the first one, so any
|
||||
* code which used multiple format strings has broken. Please change
|
||||
* your calls to format accordingly.
|
||||
*
|
||||
* e.g.:
|
||||
----
|
||||
format("key = %s", key, ", value = %s", value)
|
||||
----
|
||||
* will need to be rewritten as:
|
||||
* needs to be rewritten as:
|
||||
----
|
||||
format("key = %s, value = %s", key, value)
|
||||
----
|
||||
* )
|
||||
*/
|
||||
|
||||
string format(...)
|
||||
string format(Char, Args...)(in Char[] fmt, Args args)
|
||||
{
|
||||
/+ // @@@BUG@@@ Fails due to regression bug 2479.
|
||||
char[] s;
|
||||
|
||||
void putc(dchar c)
|
||||
auto w = appender!string();
|
||||
auto n = formattedWrite(w, fmt, args);
|
||||
version (all)
|
||||
{
|
||||
std.utf.encode(s, c);
|
||||
// In the future, this check will be removed to increase consistency
|
||||
// with formattedWrite
|
||||
enforce(n == args.length, new FormatException(
|
||||
text("Orphan format arguments: args[", n, "..", args.length, "]")));
|
||||
}
|
||||
return w.data;
|
||||
}
|
||||
|
||||
std.format.doFormat(&putc, _arguments, _argptr);
|
||||
return assumeUnique(s);
|
||||
+/
|
||||
return bug2479format(_arguments, _argptr);
|
||||
unittest
|
||||
{
|
||||
debug(string) printf("std.string.format.unittest\n");
|
||||
|
||||
// assert(format(null) == "");
|
||||
assert(format("foo") == "foo");
|
||||
assert(format("foo%%") == "foo%");
|
||||
assert(format("foo%s", 'C') == "fooC");
|
||||
assert(format("%s foo", "bar") == "bar foo");
|
||||
assert(format("%s foo %s", "bar", "abc") == "bar foo abc");
|
||||
assert(format("foo %d", -123) == "foo -123");
|
||||
assert(format("foo %d", 123) == "foo 123");
|
||||
|
||||
assertThrown!FormatError(format("foo %s"));
|
||||
assertThrown!FormatError(format("foo %s", 123, 456));
|
||||
}
|
||||
|
||||
|
||||
|
@ -2586,103 +2558,97 @@ string format(...)
|
|||
* enough to hold the result. Throws RangeError if it is not.
|
||||
* Returns: s
|
||||
*
|
||||
* $(RED sformat's current implementation is scheduled for replacement in
|
||||
* November 2012. It will then be replaced with $(LREF xsformat)'s implementation.
|
||||
* This will be seamless for most code, but it will make it so that the
|
||||
* only argument that can be a format string is the first one, so any
|
||||
* code which uses multiple format strings will break. Please change
|
||||
* $(RED sformat's current implementation has been replaced with $(LREF xsformat)'s
|
||||
* implementation. in November 2012.
|
||||
* This is seamless for most code, but it makes it so that the only
|
||||
* argument that can be a format string is the first one, so any
|
||||
* code which used multiple format strings has broken. Please change
|
||||
* your calls to sformat accordingly.
|
||||
*
|
||||
* e.g.:
|
||||
----
|
||||
sformat(buf, "key = %s", key, ", value = %s", value)
|
||||
----
|
||||
* will need to be rewritten as:
|
||||
* needs to be rewritten as:
|
||||
----
|
||||
sformat(buf, "key = %s, value = %s", key, value)
|
||||
----
|
||||
* )
|
||||
*/
|
||||
char[] sformat(char[] s, ...)
|
||||
char[] sformat(Char, Args...)(char[] buf, in Char[] fmt, Args args)
|
||||
{
|
||||
/+ // @@@BUG@@@ Fails due to regression bug 2479.
|
||||
size_t i;
|
||||
|
||||
size_t i;
|
||||
|
||||
void putc(dchar c)
|
||||
struct Sink
|
||||
{
|
||||
if(std.ascii.isASCII(c))
|
||||
{
|
||||
if (i >= s.length)
|
||||
onRangeError("std.string.sformat", 0);
|
||||
s[i] = cast(char)c;
|
||||
++i;
|
||||
}
|
||||
else
|
||||
{ char[4] buf;
|
||||
auto b = std.utf.toUTF8(buf, c);
|
||||
if (i + b.length > s.length)
|
||||
onRangeError("std.string.sformat", 0);
|
||||
s[i..i+b.length] = b[];
|
||||
i += b.length;
|
||||
}
|
||||
}
|
||||
void put(dchar c)
|
||||
{
|
||||
char[4] enc;
|
||||
auto n = encode(enc, c);
|
||||
|
||||
std.format.doFormat(&putc, _arguments, _argptr);
|
||||
return s[0 .. i];
|
||||
+/
|
||||
return bug2479sformat(s, _arguments, _argptr);
|
||||
if (buf.length < i + n)
|
||||
onRangeError("std.string.sformat", 0);
|
||||
|
||||
buf[i .. i + n] = enc[0 .. n];
|
||||
i += n;
|
||||
}
|
||||
void put(const(char)[] s)
|
||||
{
|
||||
if (buf.length < i + s.length)
|
||||
onRangeError("std.string.sformat", 0);
|
||||
|
||||
buf[i .. i + s.length] = s[];
|
||||
i += s.length;
|
||||
}
|
||||
void put(const(wchar)[] s)
|
||||
{
|
||||
for (; !s.empty; s.popFront())
|
||||
put(s.front);
|
||||
}
|
||||
void put(const(dchar)[] s)
|
||||
{
|
||||
for (; !s.empty; s.popFront())
|
||||
put(s.front);
|
||||
}
|
||||
}
|
||||
auto n = formattedWrite(Sink(), fmt, args);
|
||||
version (all)
|
||||
{
|
||||
// In the future, this check will be removed to increase consistency
|
||||
// with formattedWrite
|
||||
enforce(n == args.length, new FormatException(
|
||||
text("Orphan format arguments: args[", n, "..", args.length, "]")));
|
||||
}
|
||||
return buf[0 .. i];
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
debug(string) printf("std.string.format.unittest\n");
|
||||
debug(string) printf("std.string.sformat.unittest\n");
|
||||
|
||||
string r;
|
||||
int i;
|
||||
/+
|
||||
r = format(null);
|
||||
i = cmp(r, "");
|
||||
assert(i == 0);
|
||||
+/
|
||||
r = format("foo");
|
||||
i = cmp(r, "foo");
|
||||
assert(i == 0);
|
||||
char[10] buf;
|
||||
|
||||
r = format("foo%%");
|
||||
i = cmp(r, "foo%");
|
||||
assert(i == 0);
|
||||
assert(sformat(buf[], "foo") == "foo");
|
||||
assert(sformat(buf[], "foo%%") == "foo%");
|
||||
assert(sformat(buf[], "foo%s", 'C') == "fooC");
|
||||
assert(sformat(buf[], "%s foo", "bar") == "bar foo");
|
||||
assertThrown!RangeError(sformat(buf[], "%s foo %s", "bar", "abc"));
|
||||
assert(sformat(buf[], "foo %d", -123) == "foo -123");
|
||||
assert(sformat(buf[], "foo %d", 123) == "foo 123");
|
||||
|
||||
r = format("foo%s", 'C');
|
||||
i = cmp(r, "fooC");
|
||||
assert(i == 0);
|
||||
assertThrown!FormatError(sformat(buf[], "foo %s"));
|
||||
assertThrown!FormatError(sformat(buf[], "foo %s", 123, 456));
|
||||
|
||||
r = format("%s foo", "bar");
|
||||
i = cmp(r, "bar foo");
|
||||
assert(i == 0);
|
||||
|
||||
r = format("%s foo %s", "bar", "abc");
|
||||
i = cmp(r, "bar foo abc");
|
||||
assert(i == 0);
|
||||
|
||||
r = format("foo %d", -123);
|
||||
i = cmp(r, "foo -123");
|
||||
assert(i == 0);
|
||||
|
||||
r = format("foo %d", 123);
|
||||
i = cmp(r, "foo 123");
|
||||
assert(i == 0);
|
||||
assert(sformat(buf[], "%s %s %s", "c"c, "w"w, "d"d) == "c w d");
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* Format arguments into a string.
|
||||
*
|
||||
* xformat is a version of $(LREF format) whose behavior matches that of
|
||||
* $(XREF stdio, writef). $(LREF format) will be changed to use this
|
||||
* implementation in November 2012. In the interim, xformat is provided for
|
||||
* those who need the improved implementation. It will be scheduled for
|
||||
* deprecation once format has been updated.
|
||||
* $(LREF format) has been changed to use this implementation in November 2012.
|
||||
* Then xformat has been scheduled for deprecation at the same time.
|
||||
* It will be deprecateed in May 2013.
|
||||
*/
|
||||
|
||||
string xformat(Char, Args...)(in Char[] fmt, Args args)
|
||||
|
@ -2699,7 +2665,7 @@ string xformat(Char, Args...)(in Char[] fmt, Args args)
|
|||
return w.data;
|
||||
}
|
||||
|
||||
unittest
|
||||
deprecated unittest
|
||||
{
|
||||
debug(string) printf("std.string.xformat.unittest\n");
|
||||
|
||||
|
@ -2721,11 +2687,9 @@ unittest
|
|||
* Format arguments into string $(D_PARAM buf) which must be large
|
||||
* enough to hold the result. Throws RangeError if it is not.
|
||||
*
|
||||
* xsformat is a version of $(LREF sformat) whose behavior matches that of
|
||||
* $(XREF stdio, writef). $(LREF sformat) will be changed to use this
|
||||
* implementation in November 2012. In the interim, xsformat is provided for
|
||||
* those who need the improved implementation. It will be scheduled for
|
||||
* deprecation once sformat has been updated.
|
||||
* $(LREF sformat) has been changed to use this implementation in November 2012.
|
||||
* Then xsformat has been scheduled for deprecation at the same time.
|
||||
* It will be deprecateed in May 2013.
|
||||
*
|
||||
* Returns: filled slice of $(D_PARAM buf)
|
||||
*/
|
||||
|
@ -2777,7 +2741,7 @@ char[] xsformat(Char, Args...)(char[] buf, in Char[] fmt, Args args)
|
|||
return buf[0 .. i];
|
||||
}
|
||||
|
||||
unittest
|
||||
deprecated unittest
|
||||
{
|
||||
debug(string) printf("std.string.xsformat.unittest\n");
|
||||
|
||||
|
@ -3674,7 +3638,10 @@ unittest
|
|||
assert(isNumeric(s[1..s.length - 2]) == true);
|
||||
assert(isNumeric(s) == false);
|
||||
assert(isNumeric(s[0..s.length - 1]) == false);
|
||||
}
|
||||
|
||||
deprecated unittest
|
||||
{
|
||||
// These test calling the isNumeric(...) function
|
||||
assert(isNumeric(1,123UL) == true);
|
||||
assert(isNumeric('2') == true);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue