www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - getDirectory of FileSystem.d

reply Alberto <reda zioale.it> writes:
I must get the current dir, and, I'm using getDirectory() from
FileSystem.d to do that.
A simple example:

FilePath appDir = FileSystem.getDirectory;

it works but there is a space at the end of path, so I have many errors
when I try to join paths.
Here's a log:

giano.globals - appDir: 'C:\Documents and
Settings\Admin\Desktop\projects\giano '

I have tried to understand why by myself.
This is a cut of getDirectory() from FileSystem:

int length = GetCurrentDirectoryW (0, null);
if (length) {
    char[MAX_PATH] tmp = void;
    auto dir = new wchar [length];
    GetCurrentDirectoryW (length, dir.ptr);
    return new FilePath (Utf.toUtf8 (dir, tmp));
}

in MSDN I read:

Return Value
If the function succeeds, the return value specifies the number of
characters that are written to the buffer, not including the terminating
null character.
If the function fails, the return value is zero. To get extended error
information, call GetLastError.
If the buffer that is pointed to by lpBuffer is not large enough, the
return value specifies the required size of the buffer, in characters,
including the null-terminating character.

null is passed as buffer to GetCurrentDirectoryW, so the return value
should specifies the required size of the buffer including the
null-terminating character, but D string doesn't have one.
So, this line:

auto dir = new wchar [length];

should be fixed in:

auto dir = new wchar [length-1];

and the same for the ANSI version
or I'm wrong?
Feb 14 2007
next sibling parent kris <foo bar.com> writes:
Alberto wrote:
 I must get the current dir, and, I'm using getDirectory() from
 FileSystem.d to do that.
 A simple example:
 
 FilePath appDir = FileSystem.getDirectory;
 
 it works but there is a space at the end of path, so I have many errors
 when I try to join paths.
 Here's a log:
 
 giano.globals - appDir: 'C:\Documents and
 Settings\Admin\Desktop\projects\giano '
 
 I have tried to understand why by myself.
 This is a cut of getDirectory() from FileSystem:
 
 int length = GetCurrentDirectoryW (0, null);
 if (length) {
     char[MAX_PATH] tmp = void;
     auto dir = new wchar [length];
     GetCurrentDirectoryW (length, dir.ptr);
     return new FilePath (Utf.toUtf8 (dir, tmp));
 }
 
 in MSDN I read:
 
 Return Value
 If the function succeeds, the return value specifies the number of
 characters that are written to the buffer, not including the terminating
 null character.
 If the function fails, the return value is zero. To get extended error
 information, call GetLastError.
 If the buffer that is pointed to by lpBuffer is not large enough, the
 return value specifies the required size of the buffer, in characters,
 including the null-terminating character.
 
 null is passed as buffer to GetCurrentDirectoryW, so the return value
 should specifies the required size of the buffer including the
 null-terminating character, but D string doesn't have one.
 So, this line:
 
 auto dir = new wchar [length];
 
 should be fixed in:
 
 auto dir = new wchar [length-1];
 
 and the same for the ANSI version
 or I'm wrong?
 
 

That looks like a bug. Would you mind filing a bug-report over here, please? http://www.dsource.org/projects/tango/newticket
Feb 14 2007
prev sibling parent Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Alberto wrote:
 int length = GetCurrentDirectoryW (0, null);
 if (length) {
     char[MAX_PATH] tmp = void;
     auto dir = new wchar [length];
     GetCurrentDirectoryW (length, dir.ptr);
     return new FilePath (Utf.toUtf8 (dir, tmp));
 }
 

 null is passed as buffer to GetCurrentDirectoryW, so the return value
 should specifies the required size of the buffer including the
 null-terminating character, but D string doesn't have one.
 So, this line:
 
 auto dir = new wchar [length];
 
 should be fixed in:
 
 auto dir = new wchar [length-1];
 
 and the same for the ANSI version
 or I'm wrong?

The code is wrong, but I think you're also wrong about how to fix it ;). GetCurrentDirectoryW will _still_ try to write the null character to terminate the string. So space for it needs to be allocated. Since the null character shouldn't be returned, the length of 'dir' should be decreased by one before use. So the fix is to either insert something like 'dir = dir[0 .. $-1];' (or 'dir.length = length - 1;') before the return statement, or to change the 'dir' in the return statement to 'dir[0 .. $-1]'.
Feb 14 2007