diff options
author | Ronan Collobert <ronan@collobert.com> | 2014-02-13 20:35:03 +0400 |
---|---|---|
committer | Ronan Collobert <ronan@collobert.com> | 2014-02-13 20:35:03 +0400 |
commit | 20c30ff4e815f1d9feb1a4a25e7f4f0460b99380 (patch) | |
tree | 90c60040d2373734a64b25b71db926fcea3514b2 | |
parent | a8708bf380c939335717537c2156e570d52c7dea (diff) |
dok -> md
-rw-r--r-- | README.md (renamed from dok/index.dok) | 419 |
1 files changed, 210 insertions, 209 deletions
diff --git a/dok/index.dok b/README.md index 715e7d2..70eb511 100644 --- a/dok/index.dok +++ b/README.md @@ -1,23 +1,23 @@ -====== Wrap package ====== +# Wrap package # -The **wrap** package helps you to automate the generation of Lua/C wrappers +The __wrap__ package helps you to automate the generation of Lua/C wrappers around existing C functions, such that these functions would be callable -from Lua. This package is used by the **torch** package, but does not depend on +from Lua. This package is used by the __torch__ package, but does not depend on anything, and could be used by anyone using Lua. -**DISCLAIMER** Before going any further, we assume the reader has a good +__DISCLAIMER__ Before going any further, we assume the reader has a good knowledge of how to interface C functions with Lua. A good start would be -the [[http://www.lua.org/manual/5.1|Lua reference manual]], or the book -[[http://www.inf.puc-rio.br/~roberto/pil2|Programming in Lua]]. +the [Lua reference manual](http://www.lua.org/manual/5.1), or the book +[Programming in Lua](http://www.inf.puc-rio.br/~roberto/pil2). As an example is often better than lengthy explanations, let's consider the case of a function -<file c> +```c int numel(THDoubleTensor *t); -</file> -which returns the number of elements of ''t''. +``` +which returns the number of elements of `t`. Writing a complete wrapper of this function would look like: -<file c> +```c static int wrapper_numel(lua_State *L) { THDoubleTensor *t; @@ -37,22 +37,22 @@ static int wrapper_numel(lua_State *L) /* the number of returned variables */ return 1; } -</file> +``` For anybody familiar with the Lua C API, this should look very simple (and -//it is simple//, Lua has been designed for that!). Nevertheless, the +_it is simple_, Lua has been designed for that!). Nevertheless, the wrapper contains about 7 lines of C code, for a quite simple function. Writing wrappers for C functions with multiple arguments, where some of them might be optional, can become very quickly a tedious task. The -**wrap** package is here to help the process. Remember however that even -though you might be able to treat most complex cases with **wrap**, +__wrap__ package is here to help the process. Remember however that even +though you might be able to treat most complex cases with __wrap__, sometimes it is also good to do everything by hand yourself! -===== High Level Interface ===== +## High Level Interface ## -**wrap** provides only one class: ''CInterface''. Considering our easy example, a typical usage +__wrap__ provides only one class: `CInterface`. Considering our easy example, a typical usage would be: -<file lua> +```lua require 'wrap' interface = wrap.CInterface.new() @@ -69,12 +69,12 @@ interface:wrap( ) print(interface:tostring()) -</file> -''CInterface'' contains only few methods. [[#CInterface.wrap|wrap()]] is -the most important one. [[#CInterface.tostring|tostring()]] returns a +``` +`CInterface` contains only few methods. [wrap()](#CInterface.wrap) is +the most important one. [tostring()](#CInterface.tostring) returns a string containing all the code produced until now. The wrapper generated -by **wrap** is quite similar to what one would write by hand: -<file c> +by __wrap__ is quite similar to what one would write by hand: +```c static int wrapper_numel(lua_State *L) { int narg = lua_gettop(L); @@ -91,88 +91,88 @@ static int wrapper_numel(lua_State *L) lua_pushnumber(L, (lua_Number)arg2); return 1; } -</file> +``` -We know describe the methods provided by ''CInterface''. +We know describe the methods provided by `CInterface`. -==== new() ==== -{{anchor:CInterface.new}} +<a name="CInterface.new"/> +### new() ### -Returns a new ''CInterface''. +Returns a new `CInterface`. -==== wrap(luaname, cfunction, arguments, ...) ==== -{{anchor:CInterface.wrap}} +<a name="CInterface.wrap"/> +### wrap(luaname, cfunction, arguments, ...) ### -Tells the ''CInterface'' to generate a wrapper around the C function -''cfunction''. The function will be called from Lua under the name -''luaname''. The Lua //list// ''arguments'' must also be provided. It -describes //all// the arguments of the C function ''cfunction''. +Tells the `CInterface` to generate a wrapper around the C function +`cfunction`. The function will be called from Lua under the name +`luaname`. The Lua _list_ `arguments` must also be provided. It +describes _all_ the arguments of the C function `cfunction`. Optionally, if the C function returns a value and one would like to return it in Lua, this additional value can be also described in the argument list. -<file lua> +```lua { {name="DoubleTensor"}, {name="int", creturned=true} -- this one is returned by the C function } -</file> +``` Each argument is described also as a list. The list must at least contain -the field ''name'', which tells to ''CInterface'' what type of argument you +the field `name`, which tells to `CInterface` what type of argument you want to define. In the above example, -<file lua> +```lua {name="DoubleTensor"} -</file> -indicates to ''CInterface'' that the first argument of ''numel()'' is of type ''DoubleTensor''. +``` +indicates to `CInterface` that the first argument of `numel()` is of type `DoubleTensor`. -Arguments are defined into a table ''CInterface.argtypes'', defined at the -creation of the interface. Given a ''typename'', the corresponding field -in ''interface.argtypes[typename]'' must exist, such that ''CInterface'' +Arguments are defined into a table `CInterface.argtypes`, defined at the +creation of the interface. Given a `typename`, the corresponding field +in `interface.argtypes[typename]` must exist, such that `CInterface` knows how to handle the specified argument. A lot of types are already created by default, but the user can define more if needed, by filling -properly the ''argtypes'' table. See the section [[#CInterface.argtypes]] +properly the `argtypes` table. See the section [[#CInterface.argtypes]] for more details about defined types, and -[[#CInterface.userargtypes|how to define additional ones]]. +[how to define additional ones](#CInterface.userargtypes). -=== Argument fields === +#### Argument fields #### -Apart the field ''name'', each list describing an argument can contain several optional fields: +Apart the field `name`, each list describing an argument can contain several optional fields: -''default'': this means the argument will optional in Lua, and the argument will be initialized -with the given default value if not present in the Lua function call. The ''default'' value might +`default`: this means the argument will optional in Lua, and the argument will be initialized +with the given default value if not present in the Lua function call. The `default` value might have different meanings, depending on the argument type (see [[#CInterface.argtypes]] for more details). -''invisible'': the argument will invisible //from Lua//. This special option requires ''default'' to be set, -such that ''CInterface'' knows by what initialize this invisible argument. +`invisible`: the argument will invisible _from Lua_. This special option requires `default` to be set, +such that `CInterface` knows by what initialize this invisible argument. -''returned'': if set to ''true'', the argument will be returned by the Lua function. Note that several +`returned`: if set to `true`, the argument will be returned by the Lua function. Note that several values might be returned at the same time in Lua. -''creturned'': if ''true'', tells to ''CInterface'' that this 'argument' is +`creturned`: if `true`, tells to `CInterface` that this 'argument' is in fact the value returned by the C function. This 'argument' cannot have -a ''default'' value. Also, as in C one can return only one value, only one -'argument' can contain this field! Mixing arguments which are ''returned'' -and arguments which are ''creturned'' with ''CInterface'' is not +a `default` value. Also, as in C one can return only one value, only one +'argument' can contain this field! Mixing arguments which are `returned` +and arguments which are `creturned` with `CInterface` is not recommended: use with care. While these optional fields are generic to any argument types, some types might define additional optional fields. Again, see [[#CInterface.argtypes]] for more details. -=== Handling multiple variants of arguments === +#### Handling multiple variants of arguments #### Sometimes, one cannot describe fully the behavior one wants with only a set of possible arguments. -Take the example of the ''cos()'' function: we might want to apply it to a number, if the given argument +Take the example of the `cos()` function: we might want to apply it to a number, if the given argument is a number, or to a Tensor, if the given argument is a Tensor. -''wrap()'' can be called with extra pairs of ''cname, args'' if needed. (There are no limitations on the number extra paris). +`wrap()` can be called with extra pairs of `cname, args` if needed. (There are no limitations on the number extra paris). For example, if you need to handle three cases, it might be -<file lua> +```lua interface:wrap(luaname, cname1, args1, cname2, args2, cname3, args3) -</file> -For each given C function name ''cname'', the corresponding argument list ''args'' should match. -As a more concrete example, here is a way to generate a wrapper for ''cos()'', which would handle both numbers +``` +For each given C function name `cname`, the corresponding argument list `args` should match. +As a more concrete example, here is a way to generate a wrapper for `cos()`, which would handle both numbers and DoubleTensors. -<file lua> +```lua interface:wrap("cos", -- the Lua function name "THDoubleTensor_cos", { -- C function called for DoubleTensor @@ -185,182 +185,182 @@ interface:wrap("cos", -- the Lua function name {name="double"} -- input value } ) -</file> +``` -==== print(str) ==== -{{anchor:CInterface.print}} +<a name="CInterface.print"/> +### print(str) ### Add some hand-crafted code to the existing generated code. You might want to do that if your wrapper -requires manual tweaks. For e.g., in the example above, the "id" related to ''torch.DoubleTensor'' +requires manual tweaks. For e.g., in the example above, the "id" related to `torch.DoubleTensor` needs to be defined beforehand: -<file lua> +```lua interface:print([[ const void* torch_DoubleTensor_id; ]]) -</file> +``` -==== luaname2wrapname(name) ==== -{{anchor:CInterface.luaname2wrapname}} +<a name="CInterface.luaname2wrapname"/> +### luaname2wrapname(name) ### This method defines the name of each generated wrapping function (like -''wrapper_numel'' in the example above), given the Lua name of a function -(say ''numel''). In general, this has little importance, as the wrapper is +`wrapper_numel` in the example above), given the Lua name of a function +(say `numel`). In general, this has little importance, as the wrapper is a static function which is not going to be called outside the scope of the wrap file. However, if you generate some complex wrappers, you might want to have a control on this to avoid name clashes. The default is -<file lua> +```lua function CInterface:luaname2wrapname(name) return string.format("wrapper_%s", name) end -</file> +``` Changing it to something else can be easily done with (still following the example above) -<file lua> +```lua function interface:luaname2wrapname(name) return string.format("my_own_naming_%s", name) end -</file> +``` -==== register(name) ==== +### register(name) ### Produces C code defining a -[[http://www.lua.org/manual/5.1/manual.html#luaL_Reg|luaL_Reg]] structure -(which will have the given ''name''). In the above example, calling -<file lua> +[luaL_Reg](http://www.lua.org/manual/5.1/manual.html#luaL_Reg) structure +(which will have the given `name`). In the above example, calling +```lua interface:register('myfuncs') -</file> +``` will generate the following additional code: -<file c> +```c static const struct luaL_Reg myfuncs [] = { {"numel", wrapper_numel}, {NULL, NULL} }; -</file> +``` This structure is meant to be passed as argument to -[[http://www.lua.org/manual/5.1/manual.html#luaL_register|luaL_register]], +[luaL_register](http://www.lua.org/manual/5.1/manual.html#luaL_register), such that Lua will be aware of your new functions. For e.g., the following -would declare ''mylib.numel'' in Lua: -<file lua> +would declare `mylib.numel` in Lua: +```lua interface:print([[ luaL_register(L, "mylib", myfuncs); ]]) -</file> +``` -==== tostring() ==== -{{anchor:CInterface.tostring}} +<a name="CInterface.tostring"/> +### tostring() ### -Returns a string containing all the code generated by the ''CInterface'' +Returns a string containing all the code generated by the `CInterface` until now. Note that the history is not erased. -==== tofile(filename) ==== -{{anchor:CInterface.tofile}} +<a name="CInterface.tofile"/> +### tofile(filename) ### -Write in the file (named after ''filename'') all the code generated by the -''CInterface'' until now. Note that the history is not erased. +Write in the file (named after `filename`) all the code generated by the +`CInterface` until now. Note that the history is not erased. -==== clearhistory() ==== -{{anchor:CInterface.clearhhistory}} +<a name="CInterface.clearhhistory"/> +### clearhistory() ### -Forget about all the code generated by the ''CInterface'' until now. +Forget about all the code generated by the `CInterface` until now. -===== Argument Types ===== -{{anchor:CInterface.argtypes}} +<a name="CInterface.argtypes"/> +## Argument Types ## -Any ''CInterface'' is initialized with a default ''argtypes'' list, at -creation. This list tells to ''CInterface'' how to handle type names given -to the [[#CInterface.wrap|wrap()]] method. The user can add more types to -this list, if wanted (see [[#CInterface.userargtypes|the next section]]). +Any `CInterface` is initialized with a default `argtypes` list, at +creation. This list tells to `CInterface` how to handle type names given +to the [wrap()](#CInterface.wrap) method. The user can add more types to +this list, if wanted (see [the next section](#CInterface.userargtypes)). -==== Standard C types ==== -Standard type names include ''unsigned char'', ''char'', ''short'', -''int'', ''long'', ''float'' and ''double''. They define the corresponding +### Standard C types ### +Standard type names include `unsigned char`, `char`, `short`, +`int`, `long`, `float` and `double`. They define the corresponding C types, which are converted to/from -[[http://www.lua.org/manual/5.1/manual.html#lua_Number|lua_Number]]. +[lua_Number](http://www.lua.org/manual/5.1/manual.html#lua_Number). -Additionaly, ''byte'' is an equivalent naming for ''unsigned char'', and -''boolean'' is interpreted as a boolean in Lua, and an int in C. +Additionaly, `byte` is an equivalent naming for `unsigned char`, and +`boolean` is interpreted as a boolean in Lua, and an int in C. -''real'' will also be converted to/from a ''lua_Number'', while assuming that -it is defined in C as ''float'' or ''double''. +`real` will also be converted to/from a `lua_Number`, while assuming that +it is defined in C as `float` or `double`. -Finally, ''index'' defines a long C value, which is going to be +Finally, `index` defines a long C value, which is going to be automatically incremented by 1 when going from C to Lua, and decremented by 1, when going from Lua to C. This matches Lua policy of having table indices starting at 1, and C array indices starting at 0. -For all these number values, the ''default'' field (when defining the -argument in [[#CInterface.wrap|wrap()]]) can take two types: either a +For all these number values, the `default` field (when defining the +argument in [wrap()](#CInterface.wrap)) can take two types: either a number or a function (taking the argument table as argument, and returning a string). -Note that in case of an ''index'' type, the given default value (or result +Note that in case of an `index` type, the given default value (or result given by the default initialization function) will be decremented by 1 when -initializing the corresponging C ''long'' variable. +initializing the corresponging C `long` variable. Here is an example of defining arguments with a default value: -<file lua> +```lua {name="int", default=0} -</file> -defines an optional argument which will of type ''int'' in C (lua_Number in Lua), and will take -the value ''0'' if it is not present when calling the Lua function. A more complicated (but typical) example +``` +defines an optional argument which will of type `int` in C (lua_Number in Lua), and will take +the value `0` if it is not present when calling the Lua function. A more complicated (but typical) example would be: -<file lua> +```lua {name="int", default=function(arg) return string.format("%s", arg.args[1]:carg()) end} -</file> +``` In this case, the argument will be set to the value of the first argument in the Lua function call, if not present at call time. -==== Torch Tensor types ==== +### Torch Tensor types ### -''CInterface'' also defines **Torch** tensor types: ''ByteTensor'', -''CharTensor'', ''ShortTensor'', ''IntTensor'', ''LongTensor'', -''FloatTensor'' and ''DoubleTensor'', which corresponds to their -''THByteTensor'', etc... counterparts. All of them assume that the -[[..:luaT|luaT]] Tensor id (here for ByteTensor) -<file> +`CInterface` also defines __Torch__ tensor types: `ByteTensor`, +`CharTensor`, `ShortTensor`, `IntTensor`, `LongTensor`, +`FloatTensor` and `DoubleTensor`, which corresponds to their +`THByteTensor`, etc... counterparts. All of them assume that the +[luaT](..:luaT) Tensor id (here for ByteTensor) +``` const void *torch_ByteTensor_id; -</file> +``` is defined beforehand, and properly initialized. Additionally, if you use C-templating style which is present in the TH library, you might want -to use the ''Tensor'' typename, which assumes that ''THTensor'' is properly defined, as well as -the macro ''THTensor_()'' and ''torch_()'' (see the TH library for more details). +to use the `Tensor` typename, which assumes that `THTensor` is properly defined, as well as +the macro `THTensor_()` and `torch_()` (see the TH library for more details). -Another extra typename of interest is ''IndexTensor'', which corresponds to a ''THLongTensor'' in C. Values in this +Another extra typename of interest is `IndexTensor`, which corresponds to a `THLongTensor` in C. Values in this LongTensor will be incremented/decremented when going from/to C/Lua to/from Lua/C. -Tensor typenames ''default'' value in [[#CInterface.wrap|wrap()]] can take take two types: - * A boolean. If ''true'', the tensor will be initialized as empty, if not present at the Lua function call - * A number (index). If not present at the Lua function call, the tensor will be initialized as //pointing// to the argument at the given index (which must be a tensor of same type!). +Tensor typenames `default` value in [wrap()](#CInterface.wrap) can take take two types: + * A boolean. If `true`, the tensor will be initialized as empty, if not present at the Lua function call + * A number (index). If not present at the Lua function call, the tensor will be initialized as _pointing_ to the argument at the given index (which must be a tensor of same type!). For e.g, the list of arguments: -<file lua> +```lua { {name=DoubleTensor, default=3}, {name=double, default=1.0}, {name=DoubleTensor} } -</file> +``` The first two arguments are optional. The first one is a DoubleTensor which will point on the last (3rd) argument if not given. The second argument -will be initialized to ''1.0'' if not provided. +will be initialized to `1.0` if not provided. -Tensor typenames can also take an additional field ''dim'' (a number) which will force a dimension +Tensor typenames can also take an additional field `dim` (a number) which will force a dimension check. E.g., -<file lua> +```lua {name=DoubleTensor, dim=2} -</file> +``` expect a matrix of doubles. -===== User Types ===== -{{anchor:CInterface.userargtypes}} +<a name="CInterface.userargtypes"/> +## User Types ## -Types available by default in ''CInterface'' might not be enough for your needs. Also, sometimes you might +Types available by default in `CInterface` might not be enough for your needs. Also, sometimes you might need to change sliglty the behavior of existing types. In that sort of cases, you will need to know more about what is going on under the hood. -When you do a call to [[#CInterface.wrap|wrap()]], -<file lua> +When you do a call to [wrap()](#CInterface.wrap), +```lua interface:wrap( "numel", -- the Lua name "numel", -- the C function name, here the same @@ -371,102 +371,102 @@ interface:wrap( {name="int", creturned=true} -- this one is returned by the C function } ) -</file> +``` the method will examine each argument you provide. For example, let's consider: -<file lua> +```lua {name="int", creturned=true} -</file> -Considering the argument field ''name'', **wrap** will check if the field -''interface.argtypes['int']'' exists or not. If it does not exist, an error will be raised. +``` +Considering the argument field `name`, __wrap__ will check if the field +`interface.argtypes['int']` exists or not. If it does not exist, an error will be raised. In order to describe what happens next, we will now denote -<file lua> +```lua arg = {name="int", creturned=true} -</file> -First thing which is done is assigning ''interface.argtypes['int']'' as a metatable to ''arg'': -<file lua> +``` +First thing which is done is assigning `interface.argtypes['int']` as a metatable to `arg`: +```lua setmetatable(arg, interface.argtypes[arg.name]) -</file> -Then, a number of fields are populated in ''arg'' by **wrap**: -<file lua> +``` +Then, a number of fields are populated in `arg` by __wrap__: +```lua arg.i = 2 -- argument index (in the argument list) in the wrap() call arg.__metatable = interface.argtypes[arg.name] arg.args = ... -- the full list of arguments given in the wrap() call -</file> +``` -[[#CInterface.wrap|wrap()]] will then call a several methods which are -assumed to be present in ''arg'' (see below for the list). Obviously, in -most cases, methods will be found in the metatable of ''arg'', that is in -''interface.argtypes[arg.name]''. However, if you need to override a method +[wrap()](#CInterface.wrap) will then call a several methods which are +assumed to be present in `arg` (see below for the list). Obviously, in +most cases, methods will be found in the metatable of `arg`, that is in +`interface.argtypes[arg.name]`. However, if you need to override a method behavior for one particular argument, this method could be defined in the -table describing the argument, when calling [[#CInterface.wrap|wrap()]]. +table describing the argument, when calling [wrap()](#CInterface.wrap). -The extra fields mentionned above (populated by **wrap**) can be used in the argument +The extra fields mentionned above (populated by __wrap__) can be used in the argument methods to suit your needs (they are enough to handle most complex cases). We will now describe methods which must be defined for each type. We will -take as example ''boolean'', to make things more clear. If you want to see -more complex examples, you can have a look into the ''types.lua'' file, -provided by the **wrap** package. +take as example `boolean`, to make things more clear. If you want to see +more complex examples, you can have a look into the `types.lua` file, +provided by the __wrap__ package. -==== helpname(arg) ==== +### helpname(arg) ### Returns a string describing (in a human readable fashion) the name of the given arg. Example: -<file lua> +```lua function helpname(arg) return "boolean" end -</file> +``` -==== declare(arg) ==== +### declare(arg) ### Returns a C code string declaring the given arg. Example: -<file lua> +```lua function declare(arg) return string.format("int arg%d = 0;", arg.i) end -</file> +``` -==== check(arg, idx) ==== +### check(arg, idx) ### -Returns a C code string checking if the value at index ''idx'' on the Lua stack -corresponds to the argument type. The string will appended in a ''if()'', so it should -not contain a final '';''. +Returns a C code string checking if the value at index `idx` on the Lua stack +corresponds to the argument type. The string will appended in a `if()`, so it should +not contain a final `;`. Example: -<file lua> +```lua function check(arg, idx) return string.format("lua_isboolean(L, %d)", idx) end -</file> +``` -==== read(arg, idx) ==== +### read(arg, idx) ### -Returns a C code string converting the value a index ''idx'' on the Lua stack, into -the desired argument. This method will be called **only if** the C check given by -[[#CInterface.arg.check|check()]] succeeded. +Returns a C code string converting the value a index `idx` on the Lua stack, into +the desired argument. This method will be called __only if__ the C check given by +[check()](#CInterface.arg.check) succeeded. Example: -<file lua> +```lua function read(arg, idx) return string.format("arg%d = lua_toboolean(L, %d);", arg.i, idx) end -</file> +``` -==== init(arg) ==== +### init(arg) ### Returns a C code string initializing the argument by its default -value. This method will be called **only if** (1) ''arg'' has a ''default'' -field and (2) the C check given by [[#CInterface.arg.check|check()]] -failed (so the C code in [[#CInterface.arg.read|read()]] was not called). +value. This method will be called __only if__ (1) `arg` has a `default` +field and (2) the C check given by [check()](#CInterface.arg.check) +failed (so the C code in [read()](#CInterface.arg.read) was not called). Example: -<file lua> +```lua function init(arg) local default if arg.default then @@ -476,24 +476,24 @@ function init(arg) end return string.format("arg%d = %s;", arg.i, default) end -</file> +``` -==== carg(arg) ==== +### carg(arg) ### Returns a C code string describing how to pass -the given ''arg'' as argument when calling the C function. +the given `arg` as argument when calling the C function. In general, it is just the C arg name itself (except if you need to pass the argument "by address", for example). Example: -<file lua> +```lua function carg(arg) return string.format('arg%d', arg.i) end -</file> +``` -==== creturn(arg) ==== +### creturn(arg) ### Returns a C code string describing how get the argument if it is returned from the C function. @@ -501,37 +501,38 @@ is returned from the C function. In general, it is just the C arg name itself (except if you need to assign a pointer value, for example). -<file lua> +```lua function creturn(arg) return string.format('arg%d', arg.i) end -</file> +``` -==== precall(arg) ==== +### precall(arg) ### Returns a C code string if you need to execute specific code related to -''arg'', before calling the C function. +`arg`, before calling the C function. For e.g., if you created an object in the calls before, you might want to put it on the Lua stack here, such that it is garbage collected by Lua, in case the C function call fails. -<file lua> +```lua function precall(arg) -- nothing to do here, for boolean end -</file> +``` -==== postcall(arg) ==== +### postcall(arg) ### Returns a C code string if you need to execute specific code related to -''arg'', after calling the C function. You can for e.g. push the argument +`arg`, after calling the C function. You can for e.g. push the argument on the stack, if needed. -<file lua> +```lua function postcall(arg) if arg.creturned or arg.returned then return string.format('lua_pushboolean(L, arg%d);', arg.i) end end -</file> +``` + |