cpphs (was Re: Haskell on Red Hat Enterprise...)

Malcolm Wallace Malcolm.Wallace at cs.york.ac.uk
Fri Mar 18 06:45:01 EST 2005


Andy Moran <moran at galois.com> writes:

> -- hackery to convice cpp to splice GHC_PKG_VERSION into a string
> version :: String
> version = tail "\
>     \ GHC_PKG_VERSION"

OK, it turns out that this is pretty tricky to do in cpp, even with
full scope of -ansi or -traditional behaviour.  In fact, the hack
shown is the only way to achieve it (demonstrated below), and the
hack fails with cpphs /because/ of the string gap!  By contrast,
"cpphs --text" makes the original task very straightforward.
(The option turns off source-code lexing of the file as Haskell,
so that macros can be expanded within quotes.)

Here are a variety of ways you might attempt stringification:

    #define GHC_PKG_VERSION 6.2.2
    -- hackery to convice cpp to splice GHC_PKG_VERSION into a string
    version :: String
    version = tail "\ 
        \ GHC_PKG_VERSION"

    version2 = "GHC_PKG_VERSION"

    #define v3 "GHC_PKG_VERSION"
    version3 = v3

    #define stringify(s) #s
    version4 = stringify(GHC_PKG_VERSION)

    #define stringify2(s) "s"
    version5 = stringify2(GHC_PKG_VERSION)

And here are the results:

cpp -ansi
    version = tail "    \ GHC_PKG_VERSION"
    version2 = "GHC_PKG_VERSION"
    version3 = "GHC_PKG_VERSION"
    version4 = "GHC_PKG_VERSION"
    version5 = "s"

cpp -traditional
    version = tail "\
        \ 6.2.2"
    version2 = "GHC_PKG_VERSION"
    version3 = "GHC_PKG_VERSION"
    version4 = #6.2.2
    version5 = "GHC_PKG_VERSION"

cpphs
    version = tail "\
        \ GHC_PKG_VERSION"
    version2 = "GHC_PKG_VERSION"
    version3 = "GHC_PKG_VERSION"
    version4 = #6.2.2
    version5 = "GHC_PKG_VERSION"

cpphs --hashes
    version = tail "\
        \ GHC_PKG_VERSION"
    version2 = "GHC_PKG_VERSION"
    version3 = "GHC_PKG_VERSION"
    version4 = "GHC_PKG_VERSION"
    version5 = "GHC_PKG_VERSION"

cpphs --text
    version = tail "\
        \ 6.2.2"
    version2 = "6.2.2"
    version3 = "6.2.2"
    version4 = #6.2.2
    version5 = "6.2.2"

cpphs --text --hashes
    version = tail "\
        \ 6.2.2"
    version2 = "6.2.2"
    version3 = "6.2.2"
    version4 = "6.2.2"
    version5 = "6.2.2"


> HEAD uses a Makefile-generated Version.hs instead. Simon M.: are all 
> instances of the above trick replaced by analogues of this much neater 
> mechanism?

I agree that, ultimately, generating the source code directly is
better than using cpp-ish stuff.

> So, cpphs' version of traditional is truer to tradition than gcc's, it 
> seems.

Well, no not really: cpphs is pretty close to cpp -traditional, and cpphs
--hashes is pretty close to cpp -ansi, with the treatment of string gaps
causing the only slight differences.

> "gcc -E -traditional -x c" doesn't expand within quotes, which is 
> why hacks like the above were introduced.

Whilst there /is/ a visible difference between cpp and cpphs for
expansion within quotes, where the quotes are located within the
definition of the macro (see version5), it isn't relevant here.

Your highlighted problem was to do with expansion of macros inside
quotes within the main body of the file.  Ordinary cpp has no ability
to do this whatsoever - the file is always lexed for strings and
comments - whilst cpphs is more flexible.

Regards,
    Malcolm



More information about the Glasgow-haskell-users mailing list