TDPL: Foreach over Unicode string

Sean Kelly sean at invisibleduck.org
Fri Jul 30 16:34:28 PDT 2010


Walter Bright Wrote:

> Sean Kelly wrote:
> > 
> > Surprisingly, they don't appear to work properly. The locale used for
> > the UTF16 to multibyte conversion is the currently set locale, and that
> > prints garbage on my Windows install. I had to use the OEM locale for it
> > to work. I was going to fix this but wasn't sure if std.stdio should be
> > setting the codepage it requires, or if the DMC code is broken (which
> > doesn't seem likely).
> 
> The D functions are supposed to send UTF16 to Windows via the "W" interface. 
> What Windows does with it is up to Windows. The functions are NOT supposed to do 
> a multibyte conversion and send it to the Windows "A" interface, except for the 
> Win9x versions.

So the relevant code for printing the described string is essentially as follows:

module std.stdio;

alias _fputc_nlock FPUTC;
alias _fputwc_nlock FPUTWC;

void put(C)(C c) if (is(C : const(dchar)))
{
    int orientation = fwide(fps, 0);
    if (orientation <= 0) {
        auto b = std.utf.toUTF8(buf, c);
        foreach (i ; 0 .. b.length)
            FPUTC(b[i], handle);
    } else {
        if (c <= 0xFFFF)
            FPUTWC(c, handle);
    }
}

Assuming the orientation is wide and the file is open in text mode:

wint_t _fputwc_nlock(wint_t wch, FILE *fp)
{
    char mbc[3];
    int size = wctomb(mbc, wch);
    _fputc_nlock(mbc[0], fp);
    _fputc_nlock(mbc[1], fp);
}

int wctomb(char *s, wchar_t wch) {
    len = WideCharToMultiByte(__locale_codepage, ...);
}

I found the C code via grep so I may not be looking at the correct implementation of each function, but it matches the behavior I'm seeing.  I think the standard C routines were used in D to make sure IO buffers were shared with C, etc.  Are you saying this should be changed to use the Windows routines instead?  Alternately, is fputwc() really doing the right thing by using the default locale?  I'd imagine so except that this approach doesn't work in my tests on Windows.


More information about the Digitalmars-d mailing list