The following switch statement ignores a case when there's a smart quote involved (and other characters like "`"). The behavior is identical with both DMD (v2.072.0 and earlier) and LDC.
import std.array;
import std.conv;
import std.stdio;
void main()
{
auto tokens = to!(dchar[][])(["D"d, "’"d, "Addario"d, "'"d]);
// Or use this below:
//~ dstring[] tokens = ["D"d, "’"d, "Addario"d, "'"d];
while (!tokens.empty)
{
switch (tokens[0])
{
case "\u2019"d:
writeln("Apostrophe smart " ~ tokens[0]);
break;
case "\u0027"d:
writeln("Apostrophe straight " ~ tokens[0]);
break;
default:
writeln("Other " ~ tokens[0]);
break;
}
tokens = tokens[1..$];
}
}
Prints:
Other D
Apostrophe smart ’
Other Addario
Other '
Expected:
Other D
Apostrophe smart ’
Other Addario
Apostrophe straight ' <== expected
cf. http://forum.dlang.org/post/[email protected]
Comment #1 by ag0aep6g — 2016-11-23T19:15:05Z
Simplified test case:
----
void main()
{
int result = 0;
switch ("a"d)
{
case "\u0100"d: result = 1; break;
case "a"d: result = 2; break;
default: result = 3; break;
}
assert(result == 2); /* fails; result is 3 */
}
----
Seems to be problem with code points > 0xFF. Doesn't fail with "00FF"d instead of "0100"d.
Also fails with wstrings. Doesn't fail with strings.
Comment #2 by schveiguy — 2016-11-23T21:34:18Z
Interesting find by ketmar in https://forum.dlang.org/post/[email protected]
The binary search through the list of possible strings is flawed -- it uses memcmp to do the binary search, and so allows the endianness of the machine to mess with the results.
Comment #3 by ketmar — 2016-11-25T19:28:37Z
as i am incompatible with github ;-), anybody is, of course, free to take my hackfix and turn it into real fix (mostly by adding unittests, i guess). no credits required.