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 }