[gambit-list] #ifdef equivalent in Scheme?

Marc Feeley feeley at iro.umontreal.ca
Tue Apr 16 22:05:38 EDT 2013


On 2013-04-16, at 4:43 PM, Ralph Moritz <ralph.moeritz at outlook.com> wrote:

> I'm trying to get Black Hole trunk to run on Windows & need to compile
> different Scheme code depending on the target OS.
> 
> eg. On Unix-like OSes the following is ok:
> 
>     (compile-file-to-target "/dev/null"
>                             output: fn
>                             options: options))
> 
> ...but on Windows `/dev/null' needs to be replaced with `\\\\.\\NUL'. In C  
> I'd
> do something like:
> 
>     #ifdef _WINDOWS /* or whatever */
>     # define NULLDEV "\\\\.\\NUL"
>     #else
>     # define NULLDEV "/dev/null"
>     #endif
> 
> Is there a Scheme equivalent to #ifdef et al? If the answer is `no' then  
> please
> tell me what you'd do in this case?

The closest thing to #ifdef is (cond-expand ...).  For example:

  (cond-expand (gambit
                (define (arguments) (cdr (command-line))))
               (else
                (define (arguments) '())))

However you can't test the host operating system that way.  You could call (system-type) at run time to get some information on the host environment:

  (system-type) => (i386 apple darwin12.3.0)

But to use this you will need to parse the last element of the list.

It may seem like a hack, but the most reliable way to detect different filesystems is to check the path separator character, which is \ on Windows and / on Unix:

  (define windows?
    (char=? #\\ (let ((cd (current-directory))) (string-ref cd (- (string-length cd) 1)))))

In Gambit, directories are guaranteed to end with the path separator character.

You could also use functions that are specific to Windows:

  (define windows?
    (string=? (path-volume "c:") "c:"))

Who can come up with other ways?  :-)

Marc




More information about the Gambit-list mailing list