@@ -793,6 +793,7 @@ version(Windows)
793793 */
794794 private int _mkdir (const (char )* path) nothrow
795795 {
796+ import core.sys.windows.winbase : CreateDirectoryW;
796797 const createRet = path.extendedPathThen! (p => CreateDirectoryW(p,
797798 null /* securityAttributes*/ ));
798799 // different conventions for CreateDirectory and mkdir
@@ -810,8 +811,10 @@ version(Windows)
810811 * References:
811812 * https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
812813 */
813- package auto extendedPathThen(alias F)(const (char * ) path)
814+ auto extendedPathThen (alias F)(const (char * ) path)
814815 {
816+ import core.sys.windows.winbase : GetFullPathNameW;
817+
815818 return path.toWStringzThen! ((wpath)
816819 {
817820 // GetFullPathNameW expects a sized buffer to store the result in. Since we don't
@@ -823,7 +826,7 @@ version(Windows)
823826 null /* filePartBuffer*/ );
824827 if (pathLength == 0 )
825828 {
826- return F (" " w.ptr );
829+ return F (cast ( wchar * ) null );
827830 }
828831
829832 // wpath is the UTF16 version of path, but to be able to use
@@ -846,7 +849,7 @@ version(Windows)
846849
847850 if (absPathRet == 0 || absPathRet > absPath.length - prefix.length)
848851 {
849- return F (" " w.ptr );
852+ return F (cast ( wchar * ) null );
850853 }
851854
852855 return F (absPath.ptr);
@@ -867,13 +870,14 @@ version(Windows)
867870 {
868871 import core.stdc.string : strlen;
869872 import core.stdc.stdlib : malloc, free;
873+ import core.sys.windows.winnls : MultiByteToWideChar;
870874
871875 wchar [1024 ] buf;
872876 // cache this for efficiency
873877 const int strLength = cast (int )(strlen(str) + 1 );
874878 // first find out how long the buffer must be to store the result
875879 const length = MultiByteToWideChar(0 /* codepage*/ , 0 /* flags*/ , str, strLength, null , 0 );
876- if (! length) return F(" " w.ptr );
880+ if (! length) return F(cast ( wchar * ) null );
877881
878882 auto ret = length > buf.length
879883 ? (cast (wchar * )malloc(length * wchar .sizeof))
@@ -889,4 +893,77 @@ version(Windows)
889893
890894 return F (ret);
891895 }
896+
897+ }
898+
899+ version (Posix )
900+ {
901+
902+ /* *************************
903+ * Takes a callable F and applies it to the result of converting
904+ * `fileName` to an absolute file path (char*)
905+ */
906+ auto absPathThen (alias F)(const (char )* fileName)
907+ {
908+ char [1024 ] realPathBuffer;
909+ auto absPath = realpath(fileName, &realPathBuffer[0 ]);
910+ return F (absPath);
911+ }
912+
913+ extern (C ) char * realpath(const (char )* file_name, char * resolved_name) @nogc nothrow ;
914+ }
915+ else
916+ {
917+ /* *************************
918+ * Takes a callable F and applies it to the result of converting
919+ * `fileName` to an absolute file path (char*)
920+ */
921+ auto absPathThen (alias F)(const (char )* fileName)
922+ {
923+ import core.sys.windows.winnls : WideCharToMultiByte;
924+ import core.stdc.stdlib : malloc, free;
925+ import std.stdio : writeln;
926+ import std.conv : text;
927+
928+ return fileName.extendedPathThen! ((wpath) {
929+ // first find out how long the buffer must be to store the result
930+ const length = WideCharToMultiByte(0 , // code page
931+ 0 , // flags
932+ wpath,
933+ - 1 , // wpath len, -1 is null terminated
934+ null , // multibyte output ptr
935+ 0 , // multibyte output length
936+ null , // default char
937+ null , // if used default char
938+ );
939+
940+ if (! length) return F(cast (char * ) null );
941+
942+ char [1024 ] buf;
943+
944+ auto multibyteBuf = length > buf.length
945+ ? (cast (char * )malloc(length * char .sizeof))
946+ : &buf[0 ];
947+ scope (exit)
948+ {
949+ if (multibyteBuf != &buf[0 ])
950+ free(multibyteBuf);
951+ }
952+
953+ // first find out how long the buffer must be to store the result
954+ const length2 = WideCharToMultiByte(0 , // code page
955+ 0 , // flags
956+ wpath,
957+ - 1 , // wpath len, -1 is null terminated
958+ multibyteBuf,
959+ length,
960+ null , // default char
961+ null , // if used default char
962+ );
963+
964+ assert (length == length2);
965+
966+ return F (multibyteBuf);
967+ });
968+ }
892969}
0 commit comments