June 16, 2002
    switch ((char []) "c")
    {
        case "coo":
        default:
            break;
    }

Throws an assertion failure during runtime in switch.d(54).  The reason is that the out contract assertion check is wrong - it's checking that the switch failed correctly, but in doing so it's only comparing the first bytes of the match, not the lengths, so it thinks it's buggy when in fact the contract is.  Simply adding a length check should fix the problem.  The out check for success is also wrong - it could give a false positive for a broken implementation, so it should have a length check too.

Also, "Symbol Undefined __d_switch_ustring" if the "(char [])" cast is removed - wchar[] switching isn't implemented.  Here's the function converted over, I think, with the length fixes applied:

/******************************************************
 * Support for switch statements switching on wide strings.
 * Input:
 *	table[] 	sorted array of strings generated by compiler
 *	ca 	string to look up in table
 * Output:
 *	result 	index of match in table[]
 *	 	-1 if not in table
 */

extern (C):

int _d_switch_ustring(wchar[][] table, wchar[] ca)
    in
    {
	//printf("in _d_switch_string()\n");
	assert(table.length >= 0);
	assert(ca.length >= 0);

	// Make sure table[] is sorted correctly
	int i;

	for (i = 1; i < table.length; i++)
	{
	    int len1 = table[i - 1].length;
	    int len2 = table[i].length;

	    assert(len1 <= len2);
	    if (len1 == len2)
	    {
		int c;

		c = memcmp(table[i - 1], table[i], len1 * wchar.size);
		assert(c < 0);	// c==0 means a duplicate
	    }
	}
    }
    out (result)
    {
	int i;
	int c;

	//printf("out _d_switch_string()\n");
	if (result == -1)
	{
	    // Not found
	    for (i = 0; i < table.length; i++)
	    {
                if (table[i].length !=
		c = memcmp(table[i], ca, ca.length * wchar.size);
		assert(c != 0);
	    }
	}
	else
	{
	    assert(0 <= result && result < table.length);
	    for (i = 0; 1; i++)
	    {
		assert(i < table.length);
                if (table[i].length != ca.length)
                    continue;
		c = memcmp(table[i], ca, ca.length * wchar.size);
		if (c == 0)
		{
		    assert(i == result);
		    break;
		}
	    }
	}
    }
    body
    {
	//printf("body _d_switch_string()\n");
	int low;
	int high;
	int mid;
	int c;
	wchar[] pca;

	low = 0;
	high = table.length;

	// Do binary search
	while (low < high)
	{
	    mid = (low + high) >> 1;
	    pca = table[mid];
	    c = ca.length - pca.length;
	    if (c == 0)
	    {
		c = memcmp(ca, pca, ca.length * wchar.size);
		if (c == 0)
		{   //printf("found %d\n", mid);
		    return mid;
		}
	    }
	    if (c < 0)
	    {
		high = mid;
	    }
	    else
	    {
		low = mid + 1;
	    }
	}
	//printf("not found\n");
	return -1;		// not found
    }

June 18, 2002
Thanks, Burton! -Walter