1 /**
2 Contains code to help interfacing with C code.
3 */
4 module more.c;
5 
6 import more.sentinel : SentinelPtr, StringLiteral;
7 
8 // TODO: this definitions may change depending on the
9 //       platform.  These types are meant to be used
10 //       when declaring extern (C) functions who return
11 //       types int/unsigned.
12 alias cint = int;
13 alias cuint = uint;
14 
15 /**
16 A `cstring`` is pointer to an array of characters that is terminated
17 with a '\0' (null) character.
18 */
19 alias cstring = SentinelPtr!(const(char));
20 /// ditto
21 alias cwstring = SentinelPtr!(const(wchar));
22 /// ditto
23 alias cdstring = SentinelPtr!(const(dchar));
24 
25 version(unittest)
26 {
27     // demonstrate that C functions can be redefined using SentinelPtr
28     extern(C) size_t strlen(cstring str);
29 }
30 
31 unittest
32 {
33     assert(5 == strlen(StringLiteral!"hello".ptr));
34 
35     // NEED MULTIPLE ALIAS THIS to allow SentinelArray to implicitly convert to SentinelPtr
36     //assert(5 == strlen(StringLiteral!"hello"));
37 
38     // type of string literals should be changed to SentinelString in order for this to work
39     //assert(5 == strlen("hello".ptr");
40 
41     // this requires both conditions above to work
42     //assert(5 == strlen("hello"));
43 }
44 
45 unittest
46 {
47     import more.sentinel;
48 
49     char[10] buffer = void;
50     buffer[0 .. 5] = "hello";
51     buffer[5] = '\0';
52     SentinelArray!char hello = buffer[0..5].verifySentinel;
53     assert(5 == strlen(hello.ptr));
54 }
55 
56 pragma(inline) auto tempCString(const(char)[] str)
57 {
58     import more.sentinel : verifySentinel, assumeSentinel, SentinelArray;
59     static import std.internal.cstring;
60     static struct TempCString
61     {
62         typeof(std.internal.cstring.tempCString(str)) result;
63         size_t length;
64         SentinelPtr!(const(char)) ptr() inout { return result.ptr.assumeSentinel; }
65         SentinelArray!(const(char)) array() inout { return result.ptr[0 .. length].assumeSentinel; }
66         alias ptr this;
67     }
68     return TempCString(std.internal.cstring.tempCString(str), str.length);
69 }