Permalink
Fetching contributors…
Cannot retrieve contributors at this time
290 lines (218 sloc) 12.3 KB
-*-text-*-
C2HS TODO
=========
Next: - enum hooks should define cFromEnum/cToEnum as the default marshallers
(see comment at GenBind.lookupDftMarshIn).
- Especially with function hooks, it is not sufficient to emit line
pragmas whenever a new CHS fragment starts. As some hooks expand to
multiple lines of Haskell code, we need to reemit the line number of
the hook once for each line of Haskell generated from it.
- Points raised by PeteG:
* The initial comment put by c2hs shouldn't be put in the first line,
as this makes it difficult to add {-# OPTIONS #-} pragma to the .chs
file, as this pragma must be in the first line.
The only sensible solution seems to be to copy the first line of the
.chs file on top if it starts with the string "{-# OPTIONS".
- Ian requests {#const SYM#} where SYM is a pre-preprocessor symbol to
evaluate to the C value of SYM. Main problem is that the value might
be of various C types.
- Tutorial
- GenBind.setGet: How is it justified that `bitsPerField' is
fixed to the size of `CInt'? Does the C def guarantee
that bitfields types are of the same size?
Next Major feature to be added: structure marshalling.
- the `hsverb' should be normalised with respect to white space and
parenthesis
- have an option to compute .chi dependencies; do this on a
module-by-module basis generating many small depend files rather than
one big one
- Pending suggestions from Axel Simon:
+ succ/pred definitions for enum hooks
- marshalling of structs
- We need to handle the time stamps of .chi files more carefully;
otherwise, we often get lots of unnecessary re-runs of c2hs.
- Conceptual problem with import hooks: Currently, everything imported
from a .chi file by a binding module is also dumped into its own .chi
file. Is is not generally correct, but it would also not be correct
to omit everything that has been imported. The conceptually correct
solution would be to dump an entry for a type into a .chi file if the
corresponding Haskell type is exported by the binding module. To
achieve this, we would also need an export hook. Moreover, we may
import the same object from different modules, due to an implicit
reexport at the moment. Either eliminate those reexports, or we have
the same problems as in Haskell to determine object identity.
- c2hs has to properly process GNU C "aligned" attributes. Otherwise,
it's routine to calculate structure layout may deviate from that of
the C compiler, which may lead to nasty bugs in bindings.
- the use of get/set hooks with `class'ed newtypes is complicated, as
the type doesn't match `Ptr a'; see, eg, `GtkCList.cListGetNoOfRows'
- class methods should be able to get user-defined names (needed for
GtkData.chs)
- GenBind.mergePtrMap could be improved (see the comment)
- {#enum ...#} should create an instance of Storable as follows:
instance Storable MyEnum where
sizeOf _ = sizeOf (undefined :: CInt)
alignment _ = alignment (undefined :: CInt)
peek p = liftM cToEnum $ peek (castPtr p :: Ptr CInt)
poke p v = poke (castPtr p :: Ptr CInt) (cFromEnum v)
- `GenBind.setGet' needs to take `C2HSConfig.bitfieldDirection' into
account; otherwise, setting and getting of bitfields won't work on
architectures where bitfields start at the MSB (rather than the LSB)
- Vorschlag von Axel Krauth <krauth@infosun.fmi.uni-passau.de>:
An option with which c2hs prints a list of all functions that have not
been bound in a header file. The Position info schould be sufficient
to determine this. Maybe also add {#ignore foo#}, which makes it not
list a given identifier (for private functions listed in the header).
- In `GdkGL.chs', the prefix is not properly removed from the
constructors of `GdkGL.Configs'; same problem with
`GdkEvents.EventType'
- install the executable (c2hs and c2hs-config) with a version number
suffix and make a symbolic link for the name without version number
(makes installing multiple versions easier)
- #define enum's (see below)
- intro a safe flag (as opposite to unsafe, but make safe the default)
- overload stdAddr etc for ForeignObj (stable ptr & cast)
- C2HSMarsh: from qrczak@knm.org.pl (Marcin 'Qrczak' Kowalczyk)
mallocForeignObj:: Int -> IO ForeignObj -- malloc + freeing finalizer
- C2HSMarsh:
(!!!) :: FromAddr a => Ptr a -> Int -> IO a
p !!! i = do
v <- fixIO $ deref (p `plusAddr` sizeof v * i)
return v
(Use in GdkColor, then)
Part of New FFI, so use that in GdkColor!
- C2HSMarhs:
for compound structures it is inconvenient that in a pointer-based
out, an initial value is needed; thus
out :: (Storable a, FromAddr a) => a -> Marsh a Addr
out x = malloc x :> addrStd
and this is also convenient
inp :: ToAddr a => a -> Marsh () Addr
inp x = stdAddr x :> free
Axel also proposes this
byValue :: b -> Marsh () b
byValue x = use x :> forget
- Axel suggests,
2b. Automatisches Marshalling von Strukturen.
Eigentlich müßte es doch möglich sein, automatisch Instanzen von
Storable für Strukturen zu erstellen. Falls man mal einen generische
Pointer hat, kann man ja mit der ... as ... Methode eigene
Marshalling Funktionen zur Verfügung stellen. Oder habe ich da etwas
grundsätzliches übersehen?
Short term
~~~~~~~~~~
* cpp directives on the very first line of the .chs file are ignored
because the lexer looks for \n# This is very confusing to users.
* The C99 spec says (sec. 6.7.2.1):
[#4] Each enumerated type shall be compatible with an
integer type. The choice of type is
implementation-defined but shall be capable of
representing the values of all the members of the
enumeration. [...]
Hence, c2hs has to be a bit more clever about determining the integral type
used to represent an enum.
* The definition of `GenBind.HsObjectMap' doesn't take into account that in
Haskell a single name can be used for both a type and a class.
* See FIXME at `GenBind.mergeMaps'.
* Explain the grabbing of cpp -I options from -cppopts= (aka -C) values better
in the docu and add something like:
I prefer that to giving an option to c2hs and passing it to
cpp, because - as you say - you usually already have a
variable with the cpp options in your makefile and this way
you can easily reuse it.
* #define enums in C: siehe unten - scheinen aber wichtig
* In pointer hooks after a `->', we currently allow only type identifiers;
other forms of Haskell types would be nice, too (especially, `()').
* A function prototype that uses a defined type on its left hand side may
declare a function, while that is not obvious from the declaration itself
(without also considering the `typedef'). This is not understood by
`GenBind' so far.
* Why is a stable name an `unsigned long' in C land? How about a `void *' and
being able to get the `Addr' also in Haskell land?
* if in a binding file erroneously `t->m' is used instead of `t.m' and `t' is
the tag of a struct, the error message just complains that there is no type
object for called `t'; it would be more user friendly to report in addition
that the tag `t' exists, but cannot be used in this expression
* Should it be possible to specify a calling convention in context hook?
Isn't it a mitake to have explicit calling convention in the FFI? Shouldn't
that be adapted automatically depending on the target architecture?
* Sven: How about exporting Haskell functions (also dynamic export)?
- callback registration function that explicitly have the type of the
callback function (from which we might want to generate a foreign export
dynamic).
* `mapM raise errs' in `lexC' increases the heap usage by a factor of _8_ when
running the lexer alone on `gtkext.h' - probably because the whole analysis
has to be completed before we can be sure to have no error (and this kills
an interlocked produced/consumer scheme for the lexer and whatever function
is consuming the tokens).
* sizeof and type hooks do only allow defined, but not basic types as
arguments. This is not a real problem as C2HS provides all the needed
information to circumvent such usage, but it would still be more elegant to
support basic types as arguments, too.
Middle term
~~~~~~~~~~~
* A hook {#const <C expr>#} would be nice (as in hsc2hs). Unfortunately, it
is not that easy to realise. We need to parse the <C expr> in the binding
module. Moreover, the main value of this would be when the <C expr> is
put into the C field together with `enum define' stuff, so that all
pre-processor symbols in it are resolved. However, this can easily give us
C compiler errors. A cheap way out would be {#const "C expr"#} to avoid
parsing the C expression, but then we can get even more errors during
compiling the C.
* C->HS might get a lot easier to use by providing as optional marshalling
libraries modules that handle often occurring standard stuff like converting
`time_t' to `CalendarTime' or handle sockets etc. We would, then, probably
like to have a matching Posix or so library.
------------ Pre-1.0 rewrite ---------------
Problems:
* There are some implicit requirements on the position of binding hooks, which
the tool doesn't really enforce: context must be first, context and enum may
only occur where a toplevel definition is allowed. (This should be checked
before `GenBind' is used.) We can not really check that a hook is in a
position where a toplevel definition is allowed (without analysing
significant parts of the Haskell code), but we can at least guarantee that
these hooks occur in column position 0.
* Sven: #define enums in C: Introduce (#enum define SomeEnum {...}#) hooks
that collect `#define' symbols into an enumeration type; see also
+haskell/4025. One probem: If identifiers with the same lexeme as
`SomeEnum' or the enum members are already defined in the C header, we might
get conflicts.
The problem of this approach is that if the macro expands to something that
is not a constant expression C, we will get error messages from the
preprocessor, which are strange to the user.
Further idea, Michael's: extensible enums
There are, however, a number of interesting options supported by gcc -E that
might make alternative solutions to the problem feasible.
END of ----- Pre-1.0 rewrite ---------------
* Do we like direct support for mapping complete structs (if they are
sufficiently wellbehaved?) into Haskell data structures - both by generating
the Haskell data type definitions and by generating a `cFrom<Struct>' and a
`cTo<Struct>' routine. The latter would be generated as a cascade of field
hooks. H/Direct's formal definition of structure marshalling might be
helpful here.
* Support for evaluating constants is not complete yet. In this context, it
should probably also be checked, when there are two overlapping tags in an
enum (this is allowed in C, but is problematic for marshaling).
* How about Hugs support? Is it already possible with current Hugs?
Release Checklist
~~~~~~~~~~~~~~~~~
(1) In root of working directory,
% make tar-c2hs
(2) Compile the resulting source distribution with latest ghc stable release:
% tar xzf c2hs-x.y.z.tar.gz
% cd c2hs-x.y.z
% ./configure
% make
(3) Install and regression testing:
- Installation procedure
% make install
- Tests in build/ghc?/c2hs/tests/ directory
(4) Check documentation and add release notes
(5) Extended build test: build with older stable release of ghc and with the
cvs version
(6) Register CVS tags for CTK and C->HS (syntax: Release-c2hs_x_y_z)
(7) Make newest `tar' and build rpm
(8) Put tar.gz and rpm sources and binaries up on Web page
(9) Optionally also release the current version of CTK
(10) Update the documentation under the Web page's docu/ directory
(11) Announce: haskell@haskell.org, freshmeat.net