GithubHelp home page GithubHelp logo

haskell / c2hs Goto Github PK

View Code? Open in Web Editor NEW
197.0 17.0 49.0 4.62 MB

c2hs is a pre-processor for Haskell FFI bindings to C libraries

Home Page: http://hackage.haskell.org/package/c2hs

License: Other

Haskell 80.97% Makefile 0.45% C 17.50% Objective-C 0.96% Shell 0.12%

c2hs's Introduction

Build Status

c2hs is a interfacing tool that eases Haskell access to C libraries. The tool gets information about the C data type definitions and function signatures by analysing the C header files of the library. It uses this information to compute the missing details in the template of a Haskell module — called the binding file — that implements a Haskell binding to the C library. Hooks embedded in the binding file signal where, which, and how C objects are accessed from Haskell. The Haskell code in the binding file determines Haskell types signatures and marshaling details.

Further information is on the wiki. Also see the user guide (also available in the doc directory of the repository).

Installing

To install c2hs from Hackage:

cabal install c2hs

If you like to build from the GitHub repository, see the file INSTALL. See the REGRESSION-SUITE file for a description of how to run the regression suite for checking C2HS performance against existing Haskell packages that use it.

License

All code generated by c2hs is under a BSD licence. Hence, c2hs is useful for both open and closed source projects.

The tool itself is released under the GPLv2. This is the same situation as for the GNU C Compiler. For details, see the file COPYING.

c2hs's People

Contributors

acowley avatar adept avatar andreasabel avatar andrep avatar anton-dessiatov avatar bgamari avatar dcoutts avatar deech avatar felixonmars avatar ian-ross avatar int-e avatar int-index avatar j-keck avatar jelmer avatar johnlato avatar joshtriplett avatar kaiha avatar kolmodin avatar mchakravarty avatar merijn avatar mikesteele81 avatar morabbin avatar nganhkhoa avatar philonous avatar sivertb avatar tangboyun avatar traviswhitaker avatar visq avatar vmchale avatar watashi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

c2hs's Issues

Please indent all output lines from a {# fun ... #} to match the input indentation, to allow it in a where clause

Bug imported from C2HS Trac

Trac ticket created: 2012-07-04T10:27:06-0700


I tried to declare a {# fun ... #} in a where clause, but only the first line had the proper indentation, causing GHC to complain that "The type signature for `foo' lacks an accompanying binding" (because only the type signature appeared within the where clause). Please consider indenting all lines of a {# fun ... #} to match the input indentation, so that this works.

error while compiling C2HS with GHC 6.12.1

Bug imported from C2HS Trac

Trac ticket created: 2010-01-26T14:38:11-0800; last modified: 2010-04-23T10:00:40-0700


Priority: blocker


`
[24 of 26] Compiling C2HS.C.Info ( src/C2HS/C/Info.hs, dist/build/c2hs/c2hs-tmp/C2HS/C/Info.o )

src/C2HS/C/Info.hs:117:53:
Not in scope: type constructor or class `CLDouble'

src/C2HS/C/Info.hs:142:70:
Not in scope: type constructor or class CLDouble' cabal: Error: some packages failed to install: c2hs-0.16.0 failed during the building phase. The exception was: ExitFailure 1

Build errors

Bug imported from C2HS Trac

Trac ticket created: 2012-03-01T14:13:03-0800


A suitable c2hs version is available on Hackage, but Cabal doesn't see it when it tries to install CV.

$ cabal install CV
...
cabal: The program c2hs version >=0.16.0 is required but it could not be found.

Even after manually installing c2hs version 0.16.3, CV still doesn't see it.

$ cabal install c2hs
$ cabal install CV
...
cabal: The program c2hs version >=0.16.0 is required but it could not be found.

Specs:

Mac OS X 10.7.3

$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.0.3
$ cabal --version
cabal-install version 0.10.2
using version 1.10.1.0 of the Cabal library

Add COrOp and CAndOp to applyBin

Bug imported from C2HS Trac

Trac ticket created: 2009-01-24T13:49:16-0800; last modified: 2009-01-27T13:56:16-0800


diff -rN old-c2hs/src/C2HS/Gen/Bind.hs new-c2hs/src/C2HS/Gen/Bind.hs
112a113

import Data.Bits ((.|.), (.&.))
2031a2033,2036
applyBin _ COrOp (IntResult x)
(IntResult y) = return $ IntResult (x .|. y)
applyBin _ CAndOp (IntResult x)
(IntResult y) = return $ IntResult (x .&. y)

-- ksf

Include directive on first line produces invalid Haskell source

Bug imported from C2HS Trac

Trac ticket created: 2009-03-14T17:47:58-0700


Example:

Foo.chs (exactly one newline in the file, at the end):

#include "foo.h"

foo.h is empty. Run "c2hs Foo.chs". Foo.hs will contain this as the last line:

{-# LINE 1 "Foo.chs" #-}#include "foo.h"

Upon compilation, ghc chokes with:

Foo.chs" #-}#include "foo.h:0:30: lexical error at character '\n'

Problem is fixed by adding one extra newline before the include, or moving the include to some other place than at the very beginning of the file. Unexpected behavior anyway. c2hs version 0.16.0 on x86 Linux. I think it was present in older versions also, though.

c2hs: fails reading its own intermediate representation (.chi)

Bug imported from C2HS Trac

Trac ticket created: 2011-12-18T06:00:54-0800


This bug was reported against the Debian package of c2hs, at http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=652507

c2hs uses shown Language.C data structures as an intermediate
representation (the .chi files), and has its own code for parsing
them. It seems that Language.C has changed its Show instance for
lexemes, and c2hs can no longer parse its own .chi files.

The symptom for me is that "cabal build" fails with the following
error message:

c2hs: Prelude.read: no parse

Patch attached.

(Patch at http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=5;filename=c2hs.diff;att=1;bug=652507)

Greetings,
Joachim

Map the `size_t' C type to Foreign.C.CSize

Bug imported from C2HS Trac

Trac ticket created: 2009-07-04T21:27:02-0700; last modified: 2009-09-30T21:18:58-0700


Currently, size_t is mapped to either CUInt or CULong, depending on the native integer size. This means that type signatures will not be portable between 32- and 64-bit installations.

c2hs assumes ccall when it should automagically support stdcall for ffi imports

Bug imported from C2HS Trac

Trac ticket created: 2009-04-01T15:37:50-0700; last modified: 2011-10-04T07:52:24-0700


context:

`

15:20 mae_work dcoutts: any plans to support stdcall in c2hs ?
15:20 mae_work it assumes ccall right now
15:20 mae_work trying to build some windows libs..
15:20 mae_work for work
15:20 dcoutts mae_work: oh, I wasn't really aware of that issue
15:21 dcoutts mae_work: please file a ticket
15:21 dcoutts http://hackage.haskell.org/trac/c2hs/
15:22 dcoutts mae_work: it'd have to be an extension to the call/fun syntax
15:22 dcoutts hmm
15:22 dcoutts unless it's visible in the header declaration
15:22 dcoutts in which case it could be automatic
15:23 dcoutts how are stdcall functions defined in Windows header files?
15:23 dcoutts I presume these are mingw's headers, not MS headers
15:23 mae_work yah
15:23 mae_work 1 sec
15:23 mae_work i think they are identifiable because of @
15:23 dcoutts since c2hs can only parse GNU C not MS C
15:24 dcoutts mae_work: we don't know about the link level stuff, only the header declarations
15:24 dcoutts is it not a declaration attribute?
15:25 *** seafood quit ()
15:25 mae_work BOOL WINAPI EnumProcesses(DWORD ,DWORD,DWORD *);
15:25 mae_work perhaps WINAPI means stdcall?
15:25 mae_work also, another request I have is to make the parms optional for #fun
15:26 mae_work right now i am putting #call in a module export
15:26 *
* seafood joined #happs
15:26 mae_work example: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=3196#a3196
15:26 mae_work althought i actually think this syntax isn't half bad :)
15:27 mae_work if you want to purely let c2hs handle the type safety
15:27 mae_work and then do the rest in haskell
15:27 dcoutts hrm, that means c2hs has to parse Haskell
15:28 dcoutts to see if it's used in an export context
15:28 mae_work ok forget it then :)
15:28 dcoutts but not having to specify function args would be handy
15:28 mae_work dcoutts: um, i don't know quite what you mean, but if c2hs parsed for WINAPI, isn't this just parsing C?
15:29 mae_work and then it changes ccall to stdcall
15:29 dcoutts mae_work: WINAPI gets expanded by cpp
15:29 dcoutts the question is what it expands into at the level of raw C syntax
15:29 mae_work ic
15:29 *** dancor quit (Read error: 113 (No route to host))
15:30 dcoutts http://gcc.gnu.org/onlinedocs/gcc-4.3.3/gcc/Function-Attributes.html#Function-Attributes
15:30 dcoutts there's a stdcall attribute
15:31 mae_work expanded
15:31 mae_work BOOL attribute((stdcall)) EnumProcesses(DWORD *,DWORD,DWORD *);
15:31 dcoutts right
15:31 dcoutts ok, so that's doable
15:31 mae_work great :)
15:31 dcoutts the C parser already parses attributes, but ignores them
15:31 dcoutts they're not added into the AST
15:31 dcoutts so that'd need work
15:31 mae_work so all u have to do is change ccall to stdcall
15:32 dcoutts then c2hs would have to look for that attribute in the AST
15:32 mae_work dcoutts: great, well for the time being i was almost going to use hsc, but figured that this is worth spending the time to communicate :)
15:32 dcoutts mae_work: so when you file the ticket in the c2hs trac, ping the maintainer of the Language.C library
15:32 mae_work manual FFI types is something id on't wanna deal with
15:32 dcoutts mae_work: hsc2hs doesn't help here
15:32 dcoutts hsc2hs doesn't really help at all with function imports
15:33 mae_work i know it doesnt
15:33 mae_work the point is that this lib i am making doesn't work without stdcall
15:33 dcoutts yep
15:33 mae_work and short of doing sed s/ccall/stdcall i didn't know what to do
15:33 mae_work and that felt too hacky
15:33 mae_work : )
`

C function definitions in the generated .h file...

Bug imported from C2HS Trac

Trac ticket created: 2006-05-27T11:59:25-0700; last modified: 2007-11-23T08:40:09-0800


Priority: blocker


I'm using GHC with the --make switch.

The .h file generated by c2hs contains C declarations as well was definitions. It looks like GHC expects only definitions to be there.

The .h file is used by GHC only when compiling with optimization. When not optimising, this means that you have to copy/rename the .h file to *.c, and add it to GHC's command line, in order for the functinons defined there to be included.

When optimising, however, you get linker errors because of double definitions. You must not add the renamed .h file to GHC's command line in this case.

The obvious fix would be to have separate .h and .c files generated. In this case, the .c files would always have to be included explicitly.

This applies to versions 0.14.3 and 0.14.5

Allow prefixes to be replaced, not just removed

Bug imported from C2HS Trac

Trac ticket created: 2009-06-26T19:43:28-0700


Given an enumeration such as:

enum {
ENUMPFXSYS_NOTHING,
ENUMPFXSYS_FOO,
ENUMPFXSYS_BAR
} WeirdEnum;

The weird prefix makes typing the Haskell type constructors a pain. It's currently possible to remove the prefix entirely. However, this can cause conflicts with existing Haskell types (such as the "nothing" case above). It would be nice if the prefix could be replaced, not just removed.

Something like:

{#enum WeirdEnum as Weird with prefix = ENUMPFXSYS_ add prefix = Weird #}

which would generate the following Haskell code:

data Weird = WeirdNothing | WeirdFoo | WeirdBar

The symbol `*' does not fit here

Bug imported from C2HS Trac

Trac ticket created: 2010-09-15T16:27:49-0700; last modified: 2010-09-18T06:07:34-0700


c2hs: C header contains errors:

/usr/include/cddb/cddb_cmd.h:79: (column 27) [ERROR] >>> Syntax error !
The symbol `*' does not fit here.

support for enum define hooks

Bug imported from C2HS Trac

Trac ticket created: 2008-02-29T01:52:25-0800; last modified: 2012-10-07T16:34:49-0700


Hi!

Any chance for "enum define" hooks to be implemented and/or how you suggest to do it now when one has library with lot of #define's ?

Sincerely,
Gour

Please support anonymous enums

Bug imported from C2HS Trac

Trac ticket created: 2012-07-03T22:07:06-0700; last modified: 2012-07-04T10:19:57-0700


c2hs doesn't currently support anonymous enums. Please consider supporting them. Ideally, a single name from the enum should suffice to identify it, and the enum declaration could supply a Haskell name for the enum.

haskell keywords should be treated as identifiers in `apath'

Bug imported from C2HS Trac

Trac ticket created: 2008-07-30T17:55:51-0700


c2hs fails to parse paths of get and set hooks when some of the identifiers in the path are haskell keywords.

-- ty.h
struct s { int type; };
-- Ty.chs
module Main
test = const ({# get  s.type #}) 0
-- c2hs ty.h Ty.chs
Ty.chs:2: (column 23) [ERROR] 
  >>> Syntax error!
  The phrase `type' is not allowed here.

The problem is that the lexer does not distinguish haskell-mode and c-mode.
I've attached a fix, which converts keywords back to plain identifiers within 'parsePath'.

benedikt


Original Trac ticket had attachments:

compile gtk2hs failed under locale zh_CN.utf8

Bug imported from C2HS Trac

Trac ticket created: 2008-06-19T14:16:39-0700; last modified: 2013-02-08T19:41:17-0800


Bug previously reported in the [http://hackage.haskell.org/trac/ghc/ticket/2384 ghc trac]


when compile gtk2hs under locale zh_CN.utf8, I got:

c2hsLocal: Error in C header file. <built-in>:1: (column 0) [FATAL]
    Lexical error!
    The character '#' does not fit here.

when I compile it using locale POSIX, it succeed.

#get generated code doesn't work on bitfields

Bug imported from C2HS Trac

Trac ticket created: 2010-08-25T15:35:49-0700


Consider the following source files:

/* bitfield.c */
#include "bitfield.h"

static testStruct makeItFrom;

testStruct* makeIt() {
    makeItFrom.a = 0;
    makeItFrom.b = 1;
    return &makeItFrom;
}
/* bitfield.h */
typedef struct testStruct_ testStruct;
struct testStruct_
{
    unsigned       a : 31;
    unsigned       b :  1;
};
testStruct* makeIt();
{-# LANGUAGE ForeignFunctionInterface #-}

#include "bitfield.h"

import C2HS

{#pointer *testStruct as TestStructPtr #}

main = do
    x <- {#call makeIt #}
    print =<< ({#get testStruct->b #} x)

Compile as follows:

ezyang@javelin:~/Dev/haskell/c2hs-bitfield$ gcc -c -o bitfield.o bitfield.c
ezyang@javelin:~/Dev/haskell/c2hs-bitfield$ c2hs Bitfield.chs 
ezyang@javelin:~/Dev/haskell/c2hs-bitfield$ ghc --make Bitfield.hs bitfield.o
[2 of 2] Compiling Main             ( Bitfield.hs, Bitfield.o )
Linking Bitfield ...

When you run the resulting executable, the expected output is 1, but the actual output is 0.

Looking at the generated HS:

main = do
    x <- makeIt
{-# LINE 10 "Bitfield.chs" #-}
    print =<< ((\ptr -> do {val <- peekByteOff ptr 4 ::IO CUInt{-:1-}; return $ (val `shiftL` (32 - 1)) `shiftR` (32 - 1)}) x)

The byte offset is obviously bogus (the important information must be in offsets 0, 1, 2 or 3). Less obvious is what the correct behavior in all cases is: the bitfield arrangement appears to be compiler dependent. Maybe C2HS should just bug out and say that bitfields are not supported.

Run return value marshaller before output parameter marshallers

Bug imported from C2HS Trac

Trac ticket created: 2012-10-07T19:23:33-0700; last modified: 2013-02-08T19:35:44-0800


Many C functions provide an error code as a return value, and have output parameters that they do not set unless the return value indicates success. Handling such functions requires checking the return value before running any output marshallers. The reverse situation (an error code as an output parameter that needs checking before the return value) almost never occurs. Thus, run the return value marshaller before the output parameter marshallers, so that the return value marshaller can generate an exception that will prevent the output marshallers from running.

`
diff -rN -u old-c2hs/src/C2HS/Gen/Bind.hs new-c2hs/src/C2HS/Gen/Bind.hs
--- old-c2hs/src/C2HS/Gen/Bind.hs 2012-10-07 19:22:14.515183247 -0700
+++ new-c2hs/src/C2HS/Gen/Bind.hs 2012-10-07 19:22:14.515183247 -0700
@@ -894,8 +894,8 @@
funBody = joinLines marshIns ++
mkMarsh2 ++
call ++

  •              joinLines marshOuts ++
               marshRes            ++
    
  •              joinLines marshOuts ++
               "  " ++
               (if isImpure || not isPure then "return " else "") ++ ret
    
    return $ sig ++ funHead ++ funBody
    `

Cabal needs to tell c2hs to use gcc -E and where to find gcc

Bug imported from C2HS Trac

Trac ticket created: 2009-04-02T10:17:24-0700; last modified: 2009-04-02T15:24:33-0700


`
10:14 dcoutts mae_work: oh, hmm. Perhaps Cabal needs to tell c2hs to use gcc -E and where to find gcc.
10:14 *** zerny quit (Read error: 110 (Connection timed out))
10:15 mae_work dcoutts: yeah... and also, even when i do gcc -E the include paths aren't passed (although i guess this would happen by default if i use no opts i guess right?)
10:15 lilac @type (>>= uncurry (map . (,)))
10:15 lambdabot forall a a1. [(a1, [a])] -> [(a1, a)]
10:15 *** aik joined #haskell
10:15 BMeph kadaver: Does it have to be State, or are you just throwing random names out now? :)
10:15 jakeluck i had switcded to intmap, there is overhead in conversion hence looking for something more elegant
10:15 lilac @type group . sort . (>>= uncurry (map . flip (,)))
10:15 lambdabot forall a a1. (Ord a1, Ord a) => [(a1, [a])] -> [[(a, a1)]]
10:16 dcoutts mae_work: that's because gcc -E doesn't have any extra include paths. ghc -E looks them up in the ghc-pkg db. That's what Cabal does too for hsc2hs, but not yet for c2hs.
10:16 dcoutts mae_work: a ticket will stop me forgetting about this :-)

`

Need to think how to bind C enums with aliases

Bug imported from C2HS Trac

Trac ticket created: 2011-08-26T02:01:18-0700


Consider this C enum:

typedef enum
{
  GTK_ANCHOR_CENTER,
  GTK_ANCHOR_NORTH,
  GTK_ANCHOR_NORTH_WEST,
  GTK_ANCHOR_NORTH_EAST,
  GTK_ANCHOR_SOUTH,
  GTK_ANCHOR_SOUTH_WEST,
  GTK_ANCHOR_SOUTH_EAST,
  GTK_ANCHOR_WEST,
  GTK_ANCHOR_EAST,
  GTK_ANCHOR_N          = GTK_ANCHOR_NORTH,
  GTK_ANCHOR_NW         = GTK_ANCHOR_NORTH_WEST,
  GTK_ANCHOR_NE         = GTK_ANCHOR_NORTH_EAST,
  GTK_ANCHOR_S          = GTK_ANCHOR_SOUTH,
  GTK_ANCHOR_SW         = GTK_ANCHOR_SOUTH_WEST,
  GTK_ANCHOR_SE         = GTK_ANCHOR_SOUTH_EAST,
  GTK_ANCHOR_W          = GTK_ANCHOR_WEST,
  GTK_ANCHOR_E          = GTK_ANCHOR_EAST
} GtkAnchorType;

Of course in C, enums are really ints, so it's ok to have aliases. It is the case that GTK_ANCHOR_E = GTK_ANCHOR_EAST since both enum names have the int value 9.

Currently c2hs binds this as:

data GtkAnchorType = GtkAnchorCenter
                   | GtkAnchorNorth
                   | GtkAnchorNorthWest
                   | GtkAnchorNorthEast
                   | GtkAnchorSouth
                   | GtkAnchorSouthWest
                   | GtkAnchorSouthEast
                   | GtkAnchorWest
                   | GtkAnchorEast
                   | GtkAnchorN
                   | GtkAnchorNw
                   | GtkAnchorNe
                   | GtkAnchorS
                   | GtkAnchorSw
                   | GtkAnchorSe
                   | GtkAnchorW
                   | GtkAnchorE
                   deriving (Eq,Show)

instance Enum GtkAnchorType where
  fromEnum GtkAnchorCenter = 0
  fromEnum GtkAnchorNorth = 1
  fromEnum GtkAnchorNorthWest = 2
  fromEnum GtkAnchorNorthEast = 3
  fromEnum GtkAnchorSouth = 4
  fromEnum GtkAnchorSouthWest = 5
  fromEnum GtkAnchorSouthEast = 6
  fromEnum GtkAnchorWest = 7
  fromEnum GtkAnchorEast = 8
  fromEnum GtkAnchorN = 1
  fromEnum GtkAnchorNw = 2
  fromEnum GtkAnchorNe = 3
  fromEnum GtkAnchorS = 4
  fromEnum GtkAnchorSw = 5
  fromEnum GtkAnchorSe = 6
  fromEnum GtkAnchorW = 7
  fromEnum GtkAnchorE = 8

  toEnum 0 = GtkAnchorCenter
  toEnum 1 = GtkAnchorNorth
  toEnum 2 = GtkAnchorNorthWest
  toEnum 3 = GtkAnchorNorthEast
  toEnum 4 = GtkAnchorSouth
  toEnum 5 = GtkAnchorSouthWest
  toEnum 6 = GtkAnchorSouthEast
  toEnum 7 = GtkAnchorWest
  toEnum 8 = GtkAnchorEast
  toEnum 1 = GtkAnchorN
  toEnum 2 = GtkAnchorNw
  toEnum 3 = GtkAnchorNe
  toEnum 4 = GtkAnchorS
  toEnum 5 = GtkAnchorSw
  toEnum 6 = GtkAnchorSe
  toEnum 7 = GtkAnchorW
  toEnum 8 = GtkAnchorE
  toEnum unmatched = error ("GtkAnchorType.toEnum: Cannot match " ++ show unmatched)

Note in particular that the toEnum has overlaps. It's also obviously not the case in Haskell that GtkAnchorE = GtkAnchorEast. Perhaps we should ignore aliases, that is pretend that the enum values GTK_ANCHOR_E etc are simply not present.

No way to create a foreign pointer for input and have it as an out parameter

Bug imported from C2HS Trac

Trac ticket created: 2012-07-04T10:45:25-0700


I have quite a few C functions like this:

... func(oid *, ...);

oid refers to a non-opaque C struct, and these functions treat it as an out parameter; a C caller would define an instance of the struct (knowing its size) and pass the address of that structure to have it filled in. I'd like to allocate memory for this struct using mallocForeignPtrBytes {# sizeof oid #}, pass the underlying Ptr to the function, and then return the foreign pointer wrapped in an opaque type (defined using {# pointer ... foreign newtype #}). Note that the documentation for mallocForeignPtrBytes specifically says that GHC implements it much more efficiently than a standard ForeignPtr with a finalizer of finalizerFree; otherwise, I could just use malloc and then wrap the pointer on the way out.

As far as I can tell, a {# fun ... #} wrapper cannot implement this pattern. Any output marshaller has to work using the same value passed to the function, which in this case would be a Ptr, not a ForeignPtr. Thus, I can't both create an OID in the input marshaller (using a - so the caller doesn't have to pass one) and return that OID from the function.

At the moment, I've come up with three workarounds, none of which work very well:

  • Write a {# fun ... #} wrapper using withOID* and write a Haskell wrapper function that calls newOID first, requiring an extra five lines for every function using an OID.
  • Give up on mallocForeignPtrBytes and use malloc on input and newForeignPtr on output, with resulting inefficiency (the library uses a lot of these structures).
  • Use alloca on input, and have the output marshaller use mallocForeignPtrBytes and make a copy. Efficient use of memory and efficient reclamation, but an extra copy per call.

Ideally, I'd prefer to have a way to declare this pattern directly in a marshaller. I'd suggest adding a new symbol to apply to the input marshaller, which allows it to provide an output directly.

Export C2HS.hs module from library part of the c2hs package

Bug imported from C2HS Trac

Trac ticket created: 2011-03-05T09:39:33-0800; last modified: 2011-04-17T16:36:13-0700


I see some packages (portaudio, alsa) at Hackage, that contain a plain copy of the C2HS module. Wouldn't it be better to add a library part to the c2hs package and export the C2HS module?

C header contains errors

Bug imported from C2HS Trac

Trac ticket created: 2010-09-17T17:35:18-0700; last modified: 2010-09-18T06:07:45-0700


Priority: blocker


c2hs: C header contains errors:

/usr/include/cdio/device.h:33: (column 20) [ERROR] >>> Syntax error !
The symbol `cdio_drive_read_cap_t' does not fit here.

c2hs doesn't understand enums on Mac OSX

Bug imported from C2HS Trac

Trac ticket created: 2009-02-16T15:23:33-0800


Mac OSX libraries are full of the following:

enum {
kClippingCreator = 'drag',
kClippingPictureType = 'clpp',
kClippingTextType = 'clpt',
kClippingSoundType = 'clps',
kClippingUnknownType = 'clpu'
};

c2hs has problems dealing with 'characters' in enum definition.

This problem prevents ApplicationServices from being parsed and this constitutes for the most of Mac OSX API

"offsetof" directive to obtain offset within struct to struct member

Bug imported from C2HS Trac

Trac ticket created: 2009-08-16T10:45:26-0700


I find it useful to be able to obtain the offset to a struct member within a struct, e.g. for constructing pointers to members. get and set implicitly do this when constructing their code.

I've implemented a working version of this in my local repository, and I was hoping it could be put in the upstream. The version I've implemented has similar syntax to get and set.

Consider:

typedef struct {
    int field;
} substruct_t;

typedef struct {
    char somefield[32];
    substruct_t substruct;
    substruct_t* substruct_p;
} struct_t; 

with my patch you can write:

ptrToMember :: Ptr Struct -> IO (Ptr SubStruct)
ptrToMember p = p `plusPtr` {#offsetof struct_t->substruct#}

compared to get/set this emits the byte offset as an int instead of emitting peekByteOff/pokeByteOff code, e.g.:

ptrToMember :: Ptr Struct -> IO (Ptr SubStruct)
ptrToMember p = p `plusPtr` (32)

The results are confusing (and so my patch errors) if you try to get the offset of an indirect member, e.g.

{#offsetof struct_t->substruct_ptr->field#}

is computable (it's 0), but probably not what you want, so my patch forces you to instead use:

{#offsetof substruct_t->field#}

Note this patch is against 0.16, but there is no 0.16 in the version dropdown for trac, so I set no version.


Original Trac ticket had attachments:

c2hs should derive and use default marshallers from enum and pointer hooks

Bug imported from C2HS Trac

Trac ticket created: 2010-05-27T17:26:12-0700


This is a FIXME in the source code, and I'm working on bindings that would really benefit from the DRY aspect of this feature.

Specifically, c2hs should derive the following in/out marshallers:

  • fromIntegral . fromEnum and toEnum . fromIntegral from an enum hook
  • id and id from both naked and newtype pointer hooks
  • withForeignPtr and newForeignPtr_ for foreign pointer hooks
  • withPointerType (the generated function) and PointerType . newForeignPtr_ for foreign newtype pointer hooks. The out marshaller is not great here, a !ForeignPtr with no finalizers is not terribly useful concealed inside the newtype. Perhaps foreign newtype should be left naked, or furnished with an 'in' default marshaller only.

Since I don't enjoy giving work to other people, I volunteer to add this functionality and submit a patch. This ticket is created for tracking purposes.

c2hs: Errors during expansion of binding hooks

Bug imported from C2HS Trac

Trac ticket created: 2010-09-26T22:09:16-0700


Running c2hs on

module CDIO.Device where

#include <cdio/cdio.h>

getHWInfo = {#call unsafe cdio_get_hwinfo#}

produces:

c2hs: Errors during expansion of binding hooks:

/usr/include/cdio/device.h:428: (column 3) [ERROR] >>> Illegal type!
The type specifiers of this declaration do not form a legal ANSI C(89) type.

The C function cdio_get_hwinfo returns bool, which is defined in cdio/types.h as

#define bool uint8_t

Interpreted an int64_t typedef as CInt

Bug imported from C2HS Trac

Trac ticket created: 2012-07-04T19:07:40-0700; last modified: 2012-07-05T00:16:38-0700


Priority: blocker


A library I'd like to write bindings to has a typedef of int64_t to a library-specific type name. c2hs seems to interpret that type as CInt, both in foreign import declarations and in {# type #} directives. It should interpret that type as a 64-bit integer type instead.

c2hs can't parse large .chs files without consuming too much RAM

Bug imported from C2HS Trac

Trac ticket created: 2010-01-26T16:39:56-0800


<dcoutts_> the parser for the .chs files is a bit older and less performance tuned

<dcoutts_> we usually have to deal with massive C headers, but small .chs files

<dcoutts_> so I advise splitting the module up

<dcoutts_> fixing the performance for large .chs files will involve rewriting the parser mostly from scratch (using a different parser lib)

steps to reproduce:

% cabal update && cabal unpack clutterhs-0.1 && cd clutterhs-0.1 && \
c2hs +RTS -hd -RTS --keep -d trace --include=dist/build \
--cppopts=-D__GLASGOW_HASKELL__=612 --cppopts=-I./csrc  \
--cppopts=-I/usr/include/glib-2.0 --cppopts=-I/usr/lib/glib-2.0/include \
--cppopts=-I/usr/include/clutter-1.0 --cppopts=-I/usr/include/cairo \
--cppopts=-I/usr/include/pango-1.0 --cppopts=-I/usr/include/gtk-2.0 \
--cppopts=-I/usr/include/pixman-1 --cppopts=-I/usr/include/freetype2 \
--cppopts=-I/usr/include/directfb --cppopts=-I/usr/include/libpng12 \
--cppopts=-D_REENTRANT --output-dir=dist/build --output=Graphics/UI/Clutter/Color.hs \
./Graphics/UI/Clutter/Color.chs

Attempting to read file `./Graphics/UI/Clutter/Color.chs'...
...parsing `./Graphics/UI/Clutter/Color'...

After that c2hs consumes up to 2 gigs of RAM and dies.

Size of the processed Color.chs is 6598 bytes.

C2HS chokes on Mac "^" block notation

Bug imported from C2HS Trac

Trac ticket created: 2010-03-18T07:36:03-0700; last modified: 2010-06-15T10:12:28-0700


on Snow Leopard, /usr/include/stdlib.h contains Apple's new blocks notation, which c2hs seems unhappy with, despite it being protected by an #ifdef.

lines 271 onwards:

ifdef BLOCKS

int atexit_b(void (^)(void));
void *bsearch_b(const void *, const void *, size_t,
size_t, int (^)(const void *, const void *));

endif /* BLOCKS */

� hubris-0.0.2 ./Setup build
Preprocessing library hubris-0.0.2...
c2hs: C header contains errors:

/usr/include/stdlib.h:272: (column 20) [ERROR] >>> error
Syntax error !
The symbol `^' does not fit here.

sizeof computation fails if small bitfields are present

Bug imported from C2HS Trac

Trac ticket created: 2008-08-01T13:41:03-0700; last modified: 2010-04-23T10:22:02-0700


sizeof seems to assume that e.g. <8-bit bitfields of type int32 only take 1 byte.

struct bfs {
  int x:1;
};
diff fail1_ctest.out fail1_test.out
1c1
< __tydef__bfs__: 4

---
> __tydef__bfs__: 1

Environment:

C->Haskell Compiler, version 0.15.2 Rainy Days, 31 Aug 2007
  build platform is "i386-darwin" <1, True, True, 1>
The Glorious Glasgow Haskell Compilation System, version 6.8.3
Darwin $host 9.4.0 Darwin Kernel Version 9.4.0: i386

Allow parametrized yet monomorphic data types in {#pointer ... #}

Bug imported from C2HS Trac

Trac ticket created: 2011-01-26T12:46:00-0800


Hello.

Currently pointer declaration could only use non-parametrized types. But sometimes it's too restrictive. I think examples below are self-explanatory:

This is OK but pointer is untyped

{#pointer *OKA__Hit as OKA_Hit #}

This doesn't work although it's perfectly sound. On syntactic level it may require addition of parenthesis.

{#pointer *OKA__Hit as OKA_Hit -> Hit Chan () #}

./Event.chs:23: (column 42) [ERROR]  >>> Syntax error!
  The phrase `Chan' is not allowed here.

There is workaround with type synonyms but it's not very elegant.

type Typedef = Hit Chan ()
{#pointer *OKA__Hit as OKA_Hit -> Typedef #}

Parenthesize marshallers, to preserve Haskell expressions

Bug imported from C2HS Trac

Trac ticket created: 2012-10-07T19:26:19-0700; last modified: 2013-02-08T19:35:33-0800


Marshallers can contain Haskell expressions; however, c2hs substitutes those expressions into Haskell code as function calls and adds arguments to the end, which limits these Haskell expressions to simple function calls with one or more arguments. Add parentheses to these expressions, allowing them to contain arbitrary Haskell expressions with lower precedence than function calls, such as operators.

`
diff -rN -u old-c2hs/src/C2HS/Gen/Bind.hs new-c2hs/src/C2HS/Gen/Bind.hs
--- old-c2hs/src/C2HS/Gen/Bind.hs 2012-10-07 19:24:21.493527302 -0700
+++ new-c2hs/src/C2HS/Gen/Bind.hs 2012-10-07 19:24:21.521526937 -0700
@@ -884,7 +884,7 @@
interr "GenBind.funDef: marshRes: no default?"

   marshBody (Left ide) = identToString ide
  •  marshBody (Right str) = str
    
  •  marshBody (Right str) = "(" ++ str ++ ")"
    

    retArgs' = case parm' of
    CHSParm _ _ _ (Just (_, CHSVoidArg)) _ -> retArgs
    @@ -962,7 +962,7 @@
    retArg = if omArgKind == CHSVoidArg || omArgKind == CHSIOVoidArg then "" else outBndr

     marshBody (Left ide) = identToString ide
    
  •    marshBody (Right str) = str
    
  •    marshBody (Right str) = "(" ++ str ++ ")"
    

    in
    (funArg, marshIn, callArgs, marshOut, retArg)
    marshArg _ _ = interr "GenBind.funDef: Missing default?"
    `

Allow forward definition of enums

Bug imported from C2HS Trac

Trac ticket created: 2009-09-22T12:35:40-0700


foo.h:

extern enum hello hello_fn(int);
$ c2hs foo.h foo.chs
c2hs: C header contains errors:

foo.h:1: (column 8) [ERROR]  >>> error
  Forward definition of enumeration!
  ANSI C does not permit foreward definitions of enumerations!

Strictly speaking this is true, in -pedantic mode gcc reports:

foo.h:1: warning: ISO C forbids forward references to �enum� types

However it's clearly not a very serious issue since the warning is only included in -pedantic and is accepted without warning even in -std=c99 -Wall mode. In particular this feature is used in the Linux kernel sometimes.

So the task is to work out what such forward uses mean and to adjust the C2HS.C.Trav module as appropriate.

call hook bug when C function starts with uppercase letter

Bug imported from C2HS Trac

Trac ticket created: 2008-08-16T03:19:40-0700; last modified: 2008-08-17T05:27:45-0700


Here's an example:

Header file:
void C();
chs file:
main = {# call C as c #}
expected
main = c foreign import ccall safe "capital.h C" c :: (IO ())
actual (invalid haskell)
main = C foreign import ccall safe "capital.h C" C :: (IO ())

benedikt

sizeof computation fails for nested derived types (pointer to array or array of pointers)

Bug imported from C2HS Trac

Trac ticket created: 2008-08-01T13:32:18-0700; last modified: 2011-01-19T16:39:31-0800


c2hs reports the wrong size of nested derived types.

struct pointer_to_array {
  int (*y)[4  ];
} PTA;
struct array_of_pointers {
  int* y[4];
} AOP;
diff fail2_via_c.out fail2_via_c2hs.out
1,2c1,2
< __tydef__array_of_pointers__: 16
< __tydef__pointer_to_array__: 4

---
> __tydef__array_of_pointers__: 4
> __tydef__pointer_to_array__: 16

The reason for this is that the analysis code assumes that pointer to T is represented as CPointerDeclr TDeclr, but it is actually parsed as TDeclr (...(CPointerDeclr)...).

When generating superclass instances, C2HS incorrect emits method names from the terminal class

Bug imported from C2HS Trac

Trac ticket created: 2009-08-09T17:23:53-0700; last modified: 2009-08-09T17:25:16-0700


When processing this kind of class hook (example from tests/system/Pointer.chs):

-- test classes
{#pointer *Point as APoint newtype#}
{#class APointClass APoint#}

{#pointer *ColourPoint as AColourPoint newtype#}
{#class APointClass => AColourPointClass AColourPoint#}

C2HS generates an incorrect superclass instance:

class APointClass p => AColourPointClass p where
aColourPoint :: p -> AColourPoint
fromAColourPoint :: AColourPoint -> p
instance APointClass AColourPoint where
aColourPoint (AColourPoint p) = AColourPoint (castPtr p)
fromAColourPoint (AColourPoint p) = AColourPoint (castPtr p)
instance AColourPointClass AColourPoint where
aColourPoint = id
fromAColourPoint = id

The instance of APointClass should have methods aPoint and fromAPoint, not aColourPoint and fromAColourPoint.

The bug is due to a typo in C2HS.Gen.Bind where typeIde is named but typeIde' should have been (see patch)

I tried doing darcs send but the message didn't appear on the mailing list, sorry for the doubling if it does show up.

This applies to version 0.16.0, which does not have an entry in the trac dropdown.


Original Trac ticket had attachments:

language-c-0.4.2.0 compatibility

Bug imported from C2HS Trac

Trac ticket created: 2011-09-10T06:32:25-0700; last modified: 2013-02-08T19:42:04-0800


Hi,

for Debian, I patched c2hs to build against the language-c in the latest version. The patch is purely type-driven, and not checked against possible changes in the semantics of language-c.

Thanks,
Joachim

--include flag cannot handle windows paths

Bug imported from C2HS Trac

Trac ticket created: 2010-05-03T10:48:19-0700


c2hs splits the string passed via the --include flag on the ':' character. On Unix, ':' is the search path separator character and the --include flag is intended to accept a whole search path in one go. On Windows, absolute paths look like c:\blah and these get broken if we split on ':' chars.

Also it gobbles spaces. That breaks windows paths that often use spaces.

Probably the solution is to use System.FilePath.splitSearchPath to split the search path. This uses ':' on Unix and ';' on Windows.

Should also double check the order/priority of multiple independent --include flags vs --include=first:second.

Use CPP line information when present

Bug imported from C2HS Trac

Trac ticket created: 2009-10-26T05:13:24-0700


fasta: if you want to do more patching it'd be possible to make the .chs parser recognise cpp line pragmas and to update the internal chs "current line" info appropriately
so c2hs would output {-# LINE pragmas, and not the cpp #1 ones, but properly pass the line/file info through
dcoutts: I'd love to fix all the tools, but other things need work too.
sure sure
fasta: if you've not got time, filing tickets is still useful so we do not forget
a general one about "it's hard to use cpp on .chs files" would be useful
I've never been completely convinced about c2hs's current semi-cpp system

Wrong path in generated .hs file

Bug imported from C2HS Trac

Trac ticket created: 2006-05-27T11:43:09-0700; last modified: 2010-04-23T11:06:44-0700


Priority: blocker


In the "foreign import ccall" declaration, in the generated .hs file, the path of the .h file is specified relative to the directory which c2hs has been called in. But GHC seems to interpret it relative to the .hs file.

This error only occurs when GHC is used with a different build directory (I call GHC with "-hidir build -odir build -ibuild"), and with optimization turned on. GHC doesn't seem to use the .h file, when no optimisation is used.

This applies to version 0.14.3/0.14.5

Won't build on Mac OS X

Bug imported from C2HS Trac

Trac ticket created: 2006-06-29T12:25:10-0700; last modified: 2007-11-27T08:09:08-0800


Priority: trivial


Version 0.14.5 doesn't build on Mac OS X 10.4.6 using GHC 6.4.1 and Cabal 1.1.4.

The following error message is generated:

`
~/Temp/c2hs-0.14.5$ ./Setup.hs configure

./Setup.hs:11:57:
Couldn't match LocalBuildInfo' againstDistribution.PackageDescription.PackageDescription'
Expected type: Args
-> InstallFlags
-> Distribution.PackageDescription.PackageDescription
-> LocalBuildInfo
-> IO ExitCode
Inferred type: Args -> InstallFlags -> LocalBuildInfo -> IO ExitCode
In the postInst' field of a record In the record update: defaultUserHooks {postInst = addWrapperAndLib}

Steps to reproduce:

  1. Download the source tarball.
  2. Extract the source (tar zxvf c2hs-0.14.5.tar.gz)
  3. Move into the root directory (cd c2hs-0.14.5)
  4. Configure the build (./Setup.hs configure or runhaskell Setup.hs configure)
  5. Observe that the error message is generated.

Problem with c2hs on Mac OS Leopard

Bug imported from C2HS Trac

Trac ticket created: 2008-03-06T10:51:51-0800; last modified: 2010-04-23T10:53:22-0700


I'm trying to use c2hs, but it barfs when it tries to parse "available.h" (which is #included by "stdlib.h"). The error I get is

c2hs: Error in C header file.

/usr/include/available.h:85: (column 5) [FATAL]

Lexical error!
The character '#' does not fit here.

The offending portion of available.h is

ifndef __MAC_OS_X_VERSION_MIN_REQUIRED

#ifdef ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED
#define MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED
#else
#if ppc64 || i386 || x86_64
#define __MAC_OS_X_VERSION_MIN_REQUIRED __MAC_OS_X_VERSION_10_4
#else
#define __MAC_OS_X_VERSION_MIN_REQUIRED __MAC_OS_X_VERSION_10_1
#endif
#endif

endif

A simplified example which gives the same error is

ifndef A

#ifdef B
#define FOO 0
#endif

endif

I'm using Mac OS 10.5.2. The output from "c2hs --version" is
C->Haskell Compiler, version 0.15.1 Rainy Days, 31 Aug 2007
build platform is "i386-darwin" <1, True, True, 1>

Thanks in advance for any help with this.


Original Trac ticket had attachments:

Running an outmarshaller, but ignoring its return value.

Bug imported from C2HS Trac

Trac ticket created: 2007-11-27T09:18:55-0800; last modified: 2008-08-22T06:00:45-0700


With C functions that return an errorcode, it is useful to check the errorcode and raise an exception in the IO monad without returning the errorcode explicitly. In the example below, if the outmarshaller is not flagged with - then the return value for the generated function is IO ((), Rank) instead of the desired IO Rank. When it is flagged, it is missing in the generated code. Of course, this was an attempt to get around the fact that hE*- is not valid syntax. The desired effect is that the outmarshaller hE :: CInt -> IO () is run, but the resulting () is not included in the returned tuple of the function.

`
handleError :: ErrorCode -> IO ()
hE :: IO CInt -> IO ()
hE = handleError <=< fmap ErrorCode

{# fun unsafe Comm_rank as ^ { fromRep Comm' , alloca-Rank' peekRep* } -> ()' hE- #}

-- Generated code. commRank :: Comm -> IO (Rank) commRank a1 = let {a1' = fromRep a1} in alloca $ \a2' -> commRank'_ a1' a2' >>= \res -> peekRep a2'>>= \a2* -> return (a2*)

-- The desired code with hE :: CInt -> IO () commRank :: Comm -> IO (Rank) commRank a1 = let {a1' = fromRep a1} in alloca $ \a2' -> commRank'_ a1' a2' >>= \res -> hE res >> peekRep a2'>>= \a2* -> return (a2*)

Nonstandard binary installation directory

Bug imported from C2HS Trac

Trac ticket created: 2012-03-02T19:17:12-0800; last modified: 2013-02-08T19:39:23-0800


c2hs doesn't install in the proper directory (~/.cabal/bin). Instead, it installs in /Users/andrew/Library/Haskell/ghc-7.0.3/lib/c2hs-0.16.3/bin. This creates problems with subsequent packages which depend on c2hs's installation and inclusion in PATH.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.