The general syntax for invoking Green Card is:
green-card [options] [filename]
Green Card reads from standard input if no filename is given. The options can be any of those:
--version
Print the version number, then exit successfully.
-h, --help
Print a usage message listing all available options, then exit successfully.
-v, --verbose
Print more information while processing the input.
-d, --debug
Output extra debug information.
-i, --include-dir <directories>
Search the directories named in the colon (:
) separated list for
imported files. The directories will be searched in a left to right order.
-t<target>, --target <target>
Generate Haskell code for a particular system. Targets currently supported: ghc, hugs, nhc and ffi.
--safe-code
Generates code that can use callbacks to Haskell (GHC only.) This makes the generated code slower (but safer!). See Section sec:body for more details.
--no-inline
Put C code in a separate file (GHC target only.)
--haskell1.4
Generate Haskell 1.4 compatible instead of Haskell 98.
--name-mangling-scheme={std,classic}
Control how you mangle external names into Haskell ones. The
default is std
mangling, which will just change the casing
of the first character:
A_STD_EXAMPLE
==> a_STD_EXAMPLE (variable case)
==> A_STD_EXAMPLE (datacon case)
The classic
name mangling scheme removes underscores and
upper-cases each word, i.e.,:
A_CLASSIC_EXAMPLE
==> aClassicExample (variable case)
==> AClassicExample (datacon case)
Green Card will create one or more output files when running. The following options control where the output goes:
-o file
where to put generated Haskell file.
-oc file
where to put generated C file (if any header files are generated, they'll go in (dropSuffix file ++ ".h").
--output-prefix pre -opre pre
Use <prefix> as stem when generating output filenames that haven't been specificed directly, i.e.,
pre.c and pre.hs
will be the names for the Haskell and C files.
If none of the above output options are used, the name of the output
files are constructed from the name of the input file. The filename
suffix is dropped and the appropriate suffix is appended, e.g.,
running Green Card on foo.gc
will create a Haskell file called
foo.hs
.
(ToDo: add more debugging tips here.)
When working with GHC, a commonly occurring problem for Green Card
generated code is that of functions being called unsafely when they
should have been called safely. The manifestation of this is as an
almighty crash. To help debug this, Green Card supports the option
--stub-debug
which will emit debug code into the generated
code. For instance, for the following procedure specification:
%fun Foo :: Int -> IO Int
%code Foo(arg1)
It will generate something like this:
foo :: Int -> IO Int
foo arg1 =
_casm_ ``do {int arg1;int res1;
arg1 = %0;
__current_fun__ = "foo";
do { Foo(arg1);
%r = (int)(res1);} while(0);} while(0);'' arg1
>>= \ res1 ->
(return (res1))
On top of the normal boilerplate gubbins, the variable
__current_fun__
is assigned (Green Card doesn't
define this variable, so you'll have to define it yourself.)
Using __current_fun__
, it is possible to catch unsafe
calls that really should have been safe. Here's how a Win32
library catches this condition in the (C wrapper) for its
Haskell callback:
char* __current_fun__ = NULL;
...
#if defined(DEBUG)
extern int inCCallGC;
if (inCCallGC == 0) {
fprintf(stderr, "Warning: unsafe ccall %s invokes Haskell callback\n",__current_fun__);
}
#endif
The variable inCCallGC
is defined by the GHC RTS, and its
value is equal to the number of safe calls currently executing.
(PS: The above code doesn't catch all erroneous cases.)