lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Jan 7, 2008 12:36 PM, Vyacheslav Egorov <mraleph@gorodok.net> wrote:

> Panagiotis Vossos wrote:
> > Is there any easy way to make it available to lua as a normal function?
> >
> I think __call metamethod is what you are seeking.
>
> Some untested and dirty (requires closure per functor and copy
> constructor) code:
> [snipped]


Thanks a lot for the advice, it looks like something like that would
work. However..

The problem I originally had was binding a lot of very similar
functions from glib.
The wrapper code was very repetitive, the only thing that changed was a single
function invocation.  I wanted to avoid C macros, and experimented
with stl binders
+ unary functions.  Turns out this solution is much more compex than I hoped.

The way I finally solved the problem was by writing the wrapper code
as a cheetah
template (mixlua is also excellent). I paste some example code below.
[disclaimer: I have only used cheetah once in the past, to generate
delphi sources]

#set $unicharpreds = ['validate', 'isalnum', 'isalpha', 'iscntrl',
'isdefined', 'isdigit', 'isgraph', 'islower', 'ismark', 'isupper',
'isxdigit']

#for $fn in $unicharpreds:

static int
unichar_${fn}(lua_State *L)
{
    const gunichar ch = luaL_checkint(L, 1);
    const gboolean val = g_unichar_${fn}(ch);
    lua_pushboolean(L, val);
    return 1;
}

#end for

#set $convci = ['utf8_to_utf16', 'utf8_to_ucs4']
#set $convci_ch = ['gunichar2', 'gunichar']

#for $f in zip($convci, $convci_ch):
static int
${f[0]}(lua_State *L)
{
    size_t nb;
    glong nw;
    GError *err = NULL;
    const char *in = luaL_checklstring(L, 1, &nb);
    ${f[1]} *out = g_${f[0]}(in, nb, NULL, &nw, &err);
    if (!out) return gerror(L, err);
    luaZ_pushintegers(L, out, nw);
    g_free(out);
    return 1;
}
#end for

, and in the luaL_reg array:

#for $fn in $unicharpreds + $unichartos:
    { "unichar_${fn}",  unichar_${fn} },
#end for

At least to my eyes, the result is much easier to read, the code is
smaller and the syntax
of cheetah directives doesn't screw up indentation in emacs c++ mode.

any comments / advice welcome,
panagiotis.