
Andy Moran
-- 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