cpphs calls error when it finds an #error declaration

Hi, after some debugging of a higher-level tool I found out that when I use cpphs as a library and the `runCpphs` function that is to produce the preprocessed output, when it comes across the #error directive it will terminate my program. This is because handling #error is implemented with Haskell's `error`. I find that slightly unfortunate since it means I cannot distinguish betwen an #error written in the input file and a programming error inside cpphs. @Malcolm, would you mind a change towards throwing an exception that is different from error so that it can be easily caught, or even better, a change from runCpphs :: ... -> IO String to runCpphs :: ... -> IO (Either String String) or similar? If an exception based interface is kept, it would be nice to add some haddock to `runCpphs`; not knowing about the existence of #error, it is easy to assume that the IO is only used for accessing the FilePath passed in.

On 27 Aug 2013, at 08:33, Niklas Hambüchen wrote:
@Malcolm, would you mind a change towards throwing an exception that is different from error so that it can be easily caught, or even better, a change from
runCpphs :: ... -> IO String
to
runCpphs :: ... -> IO (Either String String)
or similar?
Have you tried simply wrapping the call to runCpphs in a "catch"? Something like safeRunCpphs :: ... -> IO (Either String String) safeRunCpphs foo = fmap Right (runCpphs foo) `catch` (\(UserError s)-> Left s
If an exception based interface is kept, it would be nice to add some haddock to `runCpphs`; not knowing about the existence of #error, it is easy to assume that the IO is only used for accessing the FilePath passed in.
The IO is used also for reading #include'd files, of course. I'd be happy to add some extra documentation making the behaviour on #error clearer, if you can suggest some text that would have helped you. Regards, Malcolm

On 29/08/13 00:43, Malcolm Wallace wrote:
Have you tried simply wrapping the call to runCpphs in a "catch"? Something like
safeRunCpphs :: ... -> IO (Either String String) safeRunCpphs foo = fmap Right (runCpphs foo) `catch` (\(UserError s)-> Left s
Yes, that is what I'm doing at the moment. The problem with this is that it does not allow me to distinguish between a programmer error (error) on the caller or implementation side, and an #error in the input file.
participants (2)
-
Malcolm Wallace
-
Niklas Hambüchen