Issue 6878 - Mutable result for toStringz()
Summary: Mutable result for toStringz()
Status: RESOLVED WONTFIX
Alias: None
Product: D
Classification: Unclassified
Component: phobos (show other issues)
Version: D2
Hardware: All All
: P2 enhancement
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-11-01 17:48 UTC by bearophile_hugs
Modified: 2011-11-01 18:30 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description bearophile_hugs 2011-11-01 17:48:57 UTC
In some situations you have to call C functions that accept a char* (not const). For simplify such usage cases I'd like std.string.toStringz to be closer to this:


import core.stdc.string;

char* toStringz(immutable(char[]) s) pure nothrow
in
{
    // The assert below contradicts the unittests!
    //assert(memchr(s.ptr, 0, s.length) == null,
    //text(s.length, ": `", s, "'"));
}
out (result)
{
    if (result)
    {
        auto slen = s.length;
        while (slen > 0 && s[slen-1] == 0) --slen;
        assert(strlen(result) == slen);
        assert(memcmp(result, s.ptr, slen) == 0); // overkill?
    }
}
body
{
    /+ Unfortunately, this isn't reliable.
     We could make this work if string literals are put
     in read-only memory and we test if s[] is pointing into
     that.

     /* Peek past end of s[], if it's 0, no conversion necessary.
     * Note that the compiler will put a 0 past the end of static
     * strings, and the storage allocator will put a 0 past the end
     * of newly allocated char[]'s.
     */
     char* p = &s[0] + s.length;
     if (*p == 0)
     return s;
     +/

    // Need to make a copy
    auto copy = new char[s.length + 1];
    copy[0 .. s.length] = s[];
    copy[s.length] = '\0';

    return copy.ptr;
}

void main() {
    string t = "hello";
    char* s1 = toStringz(t);
    const(char*) s2 = toStringz(t);
    immutable(char*) s3 = toStringz(t);
    immutable(char)* s4 = toStringz(t);
}
Comment 1 Jonathan M Davis 2011-11-01 18:30:50 UTC
Use std.utf.toUTFz. It allows you to get a pointer to whatever zero-terminate string type you want (both in terms of character type and constness). toStringz is simplified function for the common use case. We're not going to complicate it further. toUTFz gives you the functionality that you're looking for.