2

I have been using the following code to get the default directories of all drives, however I don't want to use _CWD$

is there a more efficient way to do this?

REM get default directory of drives.
ON ERROR GOTO ErrSub
FOR D = 1 TO 26
    D$ = CHR$(D + 64) + ":"
    DataError = 0
    CHDIR D$
    IF DataError = 0 THEN
        PRINT _CWD$
    END IF
NEXT
END

ErrSub:
DataError = ERR
RESUME NEXT
eoredson
  • 1,167
  • 2
  • 14
  • 29
  • 1
    Why don't you want to use `_CWD$` and what about it is not efficient enough? – BdR Sep 06 '16 at 19:49
  • My quadcore won't run recent QB64 dirty builds, only an old dialect of QB64 which does not support _CWD$ and it's not efficient to error bounce when there's only one error routine and 1,000s line of code. – eoredson Sep 07 '16 at 01:16

3 Answers3

2

For the _CWD$ replacement, you can do this:

' Need to use DECLARE LIBRARY for the C function getcwd(string, stringSize).
DECLARE LIBRARY ""
    FUNCTION getcwd$ (buffer$, BYVAL buflen)
END DECLARE

' Wrapper function for making usage of getcwd$ more BASIC-like.
DECLARE FUNCTION qb64cwd$ ()

' Print the current working directory.
PRINT qb64cwd$

FUNCTION qb64cwd$ ()
    ' 32768 characters should be more than large enough on any OS.
    REDIM s AS STRING * 32768
    qb64cwd$ = getcwd$(s, 32768)
END FUNCTION

While you don't really need to have a wrapper function, the C function requires you to pass a string with a sufficient amount of writable memory. That is, getcwd doesn't allocate memory. It expects you to pass a sufficient amount of memory, and QB64's dynamically sized STRING type won't do that, so a wrapper is used to create a fixed-length string of sufficient size and pass that to the function. wrapper does that well enough to suffice in most cases. Note that this should also work on OS X and Linux (and pretty much any other POSIX-like system that QB64 runs on, possibly even including Android). I haven't tested on those systems, but it should work since getcwd is a POSIX function.

What happens when that number isn't large enough? Well, QB64 doesn't allow arrays to be passed to library functions, and you can't use STRING * variable unless variable is CONST variable = .... That means you can't enlarge the string and try again. You should probably raise an error if that happens to to tell you that something went wrong (e.g. ERROR 75).

1

One way to get default directories of all drives in QB64 without error trapping:

REM get default directory of drives.
FOR D = 65 TO 90
    D$ = CHR$(D) + ":"
    IF _DIREXISTS(D$) THEN
        CHDIR D$
        PRINT _CWD$
    END IF
NEXT
END
eoredson
  • 1,167
  • 2
  • 14
  • 29
0

Have also noticed the default directory is not always the directory where a file was started from, so, here is a sample describing each:

' directory file was loaded from
PRINT _CWD$

' declare external libraries.
DECLARE DYNAMIC LIBRARY "kernel32"
    FUNCTION SetCurrentDirectoryA% (f$)
END DECLARE

' force default path
x$ = _STARTDIR$
f$ = x$ + CHR$(0)
x = SetCurrentDirectoryA(f$)

' directory where user is in dos
PRINT _CWD$
eoredson
  • 1,167
  • 2
  • 14
  • 29