Question

I'm running into problems with this sequence of commands:

wget http://hackage.haskell.org/package/github-0.7.1/github-0.7.1.tar.gz
tar zxf github-0.7.1.tar.gz
cd github-0.7.1
ghci samples/Users/ShowUser.hs

The error I am getting is:

Github/Private.hs:142:0:
     error: missing binary operator before token "("

Github/Private.hs:148:0:
     error: missing binary operator before token "("
phase `C pre-processor' failed (exitcode = 1)

and that's because the module Github/Private.hs uses cpp directives in two places:

#if MIN_VERSION_http_conduit(1, 9, 0)
    successOrMissing s@(Status sci _) hs cookiejar
#else
    successOrMissing s@(Status sci _) hs
#endif
      | (200 <= sci && sci < 300) || sci == 404 = Nothing
#if MIN_VERSION_http_conduit(1, 9, 0)
      | otherwise = Just $ E.toException $ StatusCodeException s hs cookiejar
#else
      | otherwise = Just $ E.toException $ StatusCodeException s hs
#endif

It appears that ghci is choking on these CPP directives. However, cabal install successfully compiles and installs the package. Using ghci -XCPP doesn't help.

My question is: how can I run a sample program (i.e. like one in the samples directory) with ghci using the library code that's in the Github directory of this package?

I'd like to experiment with tweaking both the sample programs and the library code, so I'd like to run everything in ghci.

One thing that does work is:

cabal install
cd samples
ghci Users/ShowUser.hs

but, again, I'd rather not have to install the library code just to test it out.

Was it helpful?

Solution 2

The problem is not the C preprocessor per se, but that MIN_VERSION_* macros are generated by cabal at build time, and so you don't get them in GHCi. If you just want to play with the library without installing it, the path of least resistance would be commenting out the macros, as well as the branches of the CPP conditionals which do not match the version of http-conduit you currently have (if in doubt, check with ghc-pkg list).


A marginally more principled hack would be using CPP to check whether you are installing with cabal. Assuming http_conduit >= 1.9.0 it might look like this:

#ifdef CABAL
#  if MIN_VERSION_http_conduit(1, 9, 0)
    successOrMissing s@(Status sci _) hs cookiejar
#  else
    successOrMissing s@(Status sci _) hs
#  endif
      | (200 <= sci && sci < 300) || sci == 404 = Nothing
#  if MIN_VERSION_http_conduit(1, 9, 0)
      | otherwise = Just $ E.toException $ StatusCodeException s hs cookiejar
#  else
      | otherwise = Just $ E.toException $ StatusCodeException s hs
#  endif
#else
    successOrMissing s@(Status sci _) hs cookiejar
      | (200 <= sci && sci < 300) || sci == 404 = Nothing
      | otherwise = Just $ E.toException $ StatusCodeException s hs cookiejar
#endif

Given your use case, though, I don't think that extra step is worth the trouble.


For the sake of completeness: this answer explains how to use cabal macros in GHCi. Doing that, however, requires running cabal build at least once.

OTHER TIPS

The following command works:

ghci -optP-include -optPdist/build/autogen/cabal_macros.h samples/Users/ShowUser.hs

It tells the C preprocessor to read the file dist/build/autogen/cabal_macros.h. This file is generated by cabal build, but you can abort it after the preprocessing step:

Resolving dependencies...
Configuring github-0.7.1...
Building github-0.7.1...
Preprocessing library github-0.7.1...
[ 1 of 24] Compiling Github.Data.Definitions ( Github/Data/Definitions.hs,    dist/build/Github/Data/Definitions.o )
^C

If you want those options to be set automatically when you launch ghci in that directory, create a .ghci file with this content:

:set -optP-include -optPdist/build/autogen/cabal_macros.h
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top