[erlang-questions] EFFI: The 80% solution to Erlang FFI woes
Joel Reymont
joelr1@REDACTED
Fri Dec 7 14:48:44 CET 2007
I will admit from the start that I'm a staunch hater of the current
Erlang Foreign Function Interface (FFI, aka linked-in driver
mechanism). If there's something preventing application of Erlang to a
wider range of tasks then this must be it!
I'm familiar with the FFI in Haskell, Lisp and OCaml. The current
linked-in driver mechanism may be no less functional but it beats all
others in ugliness and complexity... with a VERY LARGE wooden hammer!!!
While the recently mentioned FFI enhancement proposal is being
considered, I would like to propose EFFI as the 80% solution. I just
started implementing this API and library for a chapter of my upcoming
"Hardcore Erlang" book.
Please feel free to ask questions as well as poke holes in the code
below. The intent is to wrap the POSIX Regex API in /usr/include/
regex.h.
Once regex_effi:generate/0 is called you should end up with the files
cflags.erl, eflags.erl and reg_error.erl with the enumeration handling
code, as well as regex.erl and regex_driver.c with the rest of the
wrapper code.
The focus is on using Erlang in a declarative fashion instead of
typing up lots of XML like EDTK requires.
Without further ado...
-module(regex_effi).
-compile([export_all]).
-include("regex.hrl").
generate() ->
effi:start(regex),
effi:struct(regmatch_t, [int64, int64]), % structure with 2 fields
%% regcomp() flags
effi:enum(cflags, int,
[{reg_basic, 8#0000},
{reg_extended, 8#0001},
{reg_icase, 8#0002},
{reg_nosub, 8#0004},
{reg_newline, 8#0010},
{reg_nospec, 8#0020},
{reg_pend, 8#0040},
{reg_dump, 8#0200}]),
%% regexec() flags
effi:enum(eflags, int,
[{reg_notbol, 8#00001},
{reg_noteol, 8#00002},
{reg_startend, 8#00004},
{reg_trace, 8#00400}, % tracing of execution
{reg_large, 8#01000}, % force large representation
{reg_backr, 8#02000}]), % force use of backref code
%% regerror() flags
effi:enum(reg_error, int,
[{reg_enosys, -1}, % reserved
{reg_nomatch, 1},
{reg_badpat, 2},
{reg_ecollate, 3},
{reg_ectype, 4},
{reg_eescape, 5},
{reg_esubreg, 6},
{reg_ebrack, 7},
{reg_eparen, 8},
{reg_ebrace, 9},
{reg_badbr, 10},
{reg_erange, 11},
{reg_espace, 12},
{reg_badrpt, 13},
{reg_empty, 14},
{reg_assert, 15},
{reg_invarg, 16},
{reg_illseq, 17}]),
effi:function("regcomp", regerror, % regerror is the return type
[{"preg", out, regex_t}, % output argument
{"pattern", ptr, char}, % ptr = pointer
{"cflags", cflags}]),
effi:function("regexec", regerror,
[{"preg", out, regex_t},
{"string", ptr, char},
{"nmatch", int},
{"pmatch", regmatch_t, array}, % array of structs
must be given
{"eflags", eflags}]),
effi:function("regerror", int,
[{"errcode", int},
{"preg", ptr, regex_t},
{"errbuf", ptr, char},
{"errbuf_size", int}]),
effi:function("regfree", void,
[{ptr, regex_t}]),
effi:generate(regex),
effi:stop(regex).
--
http://wagerlabs.com
More information about the erlang-questions
mailing list