haskell / c2hs

c2hs is a pre-processor for Haskell FFI bindings to C libraries
http://hackage.haskell.org/package/c2hs
Other
198 stars 50 forks source link

Illegal type: boolean in curses.h #125

Closed marceloslacerda closed 9 years ago

marceloslacerda commented 9 years ago

When installing ncurses using cabal c2hs is called and returns an error when processing the curses.h from ncursesw:

$ cabal install --enable-benchmarks ncurses Resolving dependencies... Configuring ncurses-0.2.11... Building ncurses-0.2.11... Preprocessing library ncurses-0.2.11... c2hs: Errors during expansion of binding hooks:

/usr/include/ncursesw/curses.h:405: (column 2) [ERROR] >>> Illegal type! The type specifiers of this declaration do not form a legal ANSI C(89) type.

cabal: Error: some packages failed to install: ncurses-0.2.11 failed during the building phase. The exception was: ExitFailure 1

The illegal type in this error message is a bool used in a variable declaration:

bool    _notimeout; /* no time out on function-key entry? */

However bool is defined in this header(line 178):

undef TRUE

define TRUE 1

undef FALSE

define FALSE 0

typedef unsigned char NCURSES_BOOL;

if defined(cplusplus) /* cplusplus, etc. */

/* use the C++ compiler's bool type */

define NCURSES_BOOL bool

else /* c89, c99, etc. */

if NCURSES_ENABLE_STDBOOL_H

include

/* use whatever the C compiler decides bool really is */

define NCURSES_BOOL bool

else

/* there is no predefined bool - use our own */

undef bool

define bool NCURSES_BOOL

endif

endif /* !__cplusplus, etc. */

Complete header: http://paste.debian.net/159435/

ian-ross commented 9 years ago

Hmmm. Quite possibly something I broke recently. I'll take a look.

ian-ross commented 9 years ago

@marceloslacerda I've just committed a change that appears to fix this. I've also added the ncurses package to the Travis regression suite for C2HS so any future problems should be picked up right away.

cocreature commented 9 years ago

reintroduced in 34b90cc

ian-ross commented 9 years ago

@cocreature I've sent a patch to the maintainer of ncurses to fix this. The original change I made was a mistake. Try building ncurses from https://github.com/ian-ross/haskell-ncurses, which is a repo with the patch applied.

cocreature commented 9 years ago

@ian-ross I actually don't use haskell-ncurses but instead want to write bindings for another C library and it fails on a bool there aswell so I thought it is the same issue (this is one of the lines it fails on https://github.com/Cloudef/wlc/blob/master/include/wlc.h#L108). Could you point me to the diff that actually fixed that problem in ncurses?

ian-ross commented 9 years ago

@cocreature OK, I see. The patch is attached in line at the bottom and can be applied on top of ncurses-0.2.11 (ncurses isn't on GitHub, so I can't easily point you at a diff). The main thing was just to make sure that the shim header file used in ncurses to define some preprocessor constants for Haskell use was included everywhere before including ncurses headers. The ncurses headers have some stuff in them to help with dealing with bool -- basically distinguishing between C++, C on systems with stdbool.h and others. You might want to adapt some of that stuff for your situation.

From d42c9858a2a9c69db536f8b511d964222fd5249c Mon Sep 17 00:00:00 2001
From: Ian Ross <ian@skybluetrades.net>
Date: Sun, 8 Mar 2015 09:34:58 +0100
Subject: [PATCH] Include file fixups

Persuade C2HS to parse header files by making sure the shim header is
used to set up preprocessor defines in all cases.
---
 lib/UI/NCurses.chs       | 15 ---------------
 lib/UI/NCurses/Enums.chs | 11 +----------
 lib/UI/NCurses/Panel.chs |  2 +-
 3 files changed, 2 insertions(+), 26 deletions(-)

diff --git a/lib/UI/NCurses.chs b/lib/UI/NCurses.chs
index 0d071a7..0919a24 100644
--- a/lib/UI/NCurses.chs
+++ b/lib/UI/NCurses.chs
@@ -151,21 +151,6 @@ import           UI.NCurses.Compat
 import           UI.NCurses.Types

 #include "cbits/mavericks-c2hs-workaround.h"
-
--- Note: c2hs has a hard time with the ncurses macros, and will choke on
--- waddwstr() if NCURSES_NOMACROS is not defined prior to including
--- ncurses.h in this file.
---
--- Transitive includes from hsncurses-shim.h are not sufficient.
-#define NCURSES_ENABLE_STDBOOL_H 0
-#define _XOPEN_SOURCE_EXTENDED
-#define NCURSES_NOMACROS
-#ifdef HSNCURSES_NARROW_HEADER
-#include <ncurses.h>
-#else
-#include <ncursesw/ncurses.h>
-#endif
-
 #include "cbits/hsncurses-shim.h"

 -- Starting with version 0.18.1, c2hs changed the handling of get/set hooks
diff --git a/lib/UI/NCurses/Enums.chs b/lib/UI/NCurses/Enums.chs
index 82b90bd..d2de890 100644
--- a/lib/UI/NCurses/Enums.chs
+++ b/lib/UI/NCurses/Enums.chs
@@ -21,16 +21,7 @@ module UI.NCurses.Enums where
 import           Prelude (Integer, error, show, (++), compare, Ordering(..))

 #include "cbits/mavericks-c2hs-workaround.h"
-
-#define NCURSES_ENABLE_STDBOOL_H 0
-#define _XOPEN_SOURCE_EXTENDED
-#define NCURSES_NOMACROS
-
-#ifdef HSNCURSES_NARROW_HEADER
-#include <ncurses.h>
-#else
-#include <ncursesw/ncurses.h>
-#endif
+#include "cbits/hsncurses-shim.h"

 class Enum a where
    toEnum :: Integer -> a
diff --git a/lib/UI/NCurses/Panel.chs b/lib/UI/NCurses/Panel.chs
index 7ee4292..9082d3f 100644
--- a/lib/UI/NCurses/Panel.chs
+++ b/lib/UI/NCurses/Panel.chs
@@ -41,7 +41,7 @@ import           UI.NCurses (render) -- for haddock
 import           UI.NCurses.Types

 #include "cbits/mavericks-c2hs-workaround.h"
-
+#include "cbits/hsncurses-shim.h"
 #ifdef HSNCURSES_NARROW_HEADER
 #include <panel.h>
 #else
-- 
2.3.0
cocreature commented 9 years ago

That looks like you are just disabling stdbool use completely #define NCURSES_ENABLE_STDBOOL_H 0 instead of making stdbool work with c2hs.

ian-ross commented 9 years ago

That's pretty much it, yes. C2HS has never really dealt with C bool. The ncurses C library does some preprocessor stuff to make bool act as unsigned char. It's not pretty, but it works. I can think about adding better bool support to C2HS, but it's probably not going to happen before next week.

cocreature commented 9 years ago

Fair enough, thanks for your help.

ian-ross commented 9 years ago

@cocreature I've been thinking about this a bit more. It's would definitely be possible for C2HS to support marshalling of C bool argument and result types, but I think that it would require a layer of wrapping around the C functions -- as indicated by the absence of a CBool type in Foreign.C.Types, the Haskell FFI doesn't define any marshalling of bool arguments or return values. That means that C2HS would have to marshall, e.g. a Haskell Bool value to a C int, then a wrapper function would convert that int back to a C bool to call the original function. And the same sort of thing for dealing with C functions returning bool values.

I can't think of another safe and correct way to do this, which is a shame, since the language-c parser deals with bool arguments no problem -- it's just a question of the Haskell FFI side of things.

What do you think?

cocreature commented 9 years ago

@ian-ross Yeah I came up with the same idea. I don't see a better way to deal with this.

ian-ross commented 9 years ago

OK, I'll do it that way. I don't know exactly when it will get done, but I've just added code to C2HS to generate C wrapper functions for another use, so I can add this boolean marshalling to that, and I should have a PR in for Cabal sometime in the next couple of weeks to make it transparently work with these wrappers. It's a little messy, but it does seem like the only way to do it.