Skip to content

Commit

Permalink
FIX: READ %/ doesn't return the list of drives on Windows
Browse files Browse the repository at this point in the history
fixes: metaeducation/rebol-issues#2031

This is not a perfect fix. It would be probably better to have `read %""` to get list of drives instead and implement `read %/` for reading root of the current drive (for which is now used `read %//`)
  • Loading branch information
Oldes committed Feb 12, 2020
1 parent 14e4b9e commit 47f7b46
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 8 deletions.
7 changes: 7 additions & 0 deletions src/core/s-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,13 @@
out = UNI_HEAD(dst);
#ifdef TO_WINDOWS
i++;
if (len == 1) {
// special case: reading drive letters -> read %/
// https://github.com/rebol/rebol-issues/issues/2031
out[0] = 0;
SERIES_TAIL(dst) = 0;
return dst;
}
if (i < len) {
c = GET_CHAR_UNI(uni, bp, i);
i++;
Expand Down
46 changes: 38 additions & 8 deletions src/os/win32/dev-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,21 +134,51 @@ static BOOL Seek_File_64(REBREQ *file)
WIN32_FIND_DATA info;
HANDLE h= (HANDLE)(dir->handle);
REBCHR *cp = 0;
REBCNT len;

if (!h) {

// Read first file entry:
h = FindFirstFile(dir->file.path, &info);
if (h == INVALID_HANDLE_VALUE) {
dir->error = -RFE_OPEN_FAIL;
return DR_ERROR;
file->modes = 0;
if (dir->file.path[0] == 0) {
// Reading drives.. Rebol code: read %/
len = (1 + GetLogicalDriveStrings(0, NULL)) << 1;
h = MAKE_MEM(len);
GetLogicalDriveStrings(len, h);
dir->length = len;
dir->actual = 0;
file->modes = 0;
SET_FLAG(file->modes, RFM_DIR);
} else {
// Read first file entry:
h = FindFirstFile(dir->file.path, &info);
if (h == INVALID_HANDLE_VALUE) {
dir->error = -RFE_OPEN_FAIL;
return DR_ERROR;
}
cp = info.cFileName;
}
dir->handle = h;
CLR_FLAG(dir->flags, RRF_DONE);
cp = info.cFileName;

}

if (dir->length > 0) {
// Drive names processing...
cp = (REBCHR*)h + dir->actual;
file->file.path = cp;
if (cp[0] == 0 || dir->length <= dir->actual) {
// end
FREE_MEM(dir->handle);
dir->handle = NULL;
SET_FLAG(dir->flags, RRF_DONE); // no more files
return DR_DONE;
}
while (cp[0] != 0 && dir->length > dir->actual) {
cp++; dir->actual++;
}
cp[-2] = 0; // the names are as: "C:\" but we want just "C", so just terminate the string sooner
dir->actual++; // skip the null after current drive name
return DR_DONE;
}
// regular DIR processing follows...
// Skip over the . and .. dir cases:
while (cp == 0 || (cp[0] == '.' && (cp[1] == 0 || (cp[1] == '.' && cp[2] == 0)))) {

Expand Down

0 comments on commit 47f7b46

Please sign in to comment.