lua-users home
lua-l archive

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

On Sat, Nov 27, 2010 at 14:26, Drake Wilson <> wrote:
> Quoth Francesco Abbate <>, on 2010-11-27 21:49:11 +0100:
>> So, if I know that the stack was not alterated I can omit to use both
>> lua_settop and lua_gettop and just using lauL_optint & co like Julien
>> is suggesting ?
>> If I understood correctly, when the function is called I can assume
>> that all the acceptable indexes beyond the top contain either none or
>> nil so I can safely access them and test their values. I just need to
>> make sure that I didn't push any new values on the stack by myself.
> Yes, if you unbox all the arguments into C values at the beginning and
> they fit into the types conveniently handled by opt* then that's
> likely the way to go.
>   ---> Drake Wilson

I really like it when functions consider a trailing nil argument to be
the same as a missing argument, since this is consistent with how Lua
functions work.

A lot of these suggestions are also failing to account for the case
(which, if I read correctly, is the OP's case) of optional arguments
other than at the end. e.g. consider a function "f(a, [b], c)" (i.e. b
is optional). If I write f(1, 2) that should mean a=1, b=0, c=2, but
if you just do b=luaL_optint(L, 2, 0) and c=luaL_checkint(L, 3), b
would be set to 2 and then it would fail because no third argument is
present - only f(1, nil, 2) will work.

What I usually do is:
int arg=1, a, b=0, c;
a = luaL_checkint(L, arg++);
if(lua_isnumber(L, arg)) b = lua_toninteger(L, arg++);
else if(!lua_isnoneornil(L, arg++)) return luaL_argerror(L, arg-1,
"(detail here)");
c = luaL_checkint(L, arg++);

This correctly* handles cases:
f(1, 3) --a=1, c=3
f(1, 3, nil) --a=1, c=3
f(1, 3, {}) --bad argument #3
f(1, 2, 3) --a=1, b=2, c=3
f(1, nil, 3) --a=1, c=3
f(1, {}, 3) --bad argument #2

(*if I've retyped it correctly from memory.)
This stuff can then be macro-ized to reduce repetition.

Sent from my toaster.