Setting globals in the C API

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Setting globals in the C API

Marc Balmer
I am refactoring an existing template engine.  The basic idea is to convert a template
into Lua code using a luaL_reader C function that reads template code, converts it to
Lua source code and hands it to the Lua loader function.  This way, templates become
Lua chunks which are run to render the template.  A bit like PHP and Django, but
using Lua.

In a previous version, I used a separate Lua state to run the template code and a proxy
module to populate the render state with the variables I want the templates to have access
to.  That works nicely.

Now I want to do it a single state and hand a table to the rendering function, with the
idea that the functions called have only access to the variable in the table, as if they
were globals:

local ctx = template.context()
local data = {}

data.value = 42;
data.title = 'Hello, world!'

ctx:render('sample.lt', data)

So far I did not succeed.  I assume that I have to set _ENV for each chunk that possibly
runs during template rendering (it can be many, and the idea is to call them repeatedly using
different data tables).  So this would mean to fixup _ENV for each chunk everytime the
render() function is called?  Or can I temporarily swap globals?

For now I think I will have to hand the data table when I create the context, so each time
a chunk is loaded, I already have a handle to it and can assign it as _ENV for each chunk
I load:

local data = {}
local ctx = template.context(data)

data.value = 42;
data.title = 'Hello, world!'

ctx:render('sample.lt')

Ideas or comments appreciated!

Thnks, Marc



Reply | Threaded
Open this post in threaded view
|

Re: Setting globals in the C API

Luiz Henrique de Figueiredo
> I assume that I have to set _ENV for each chunk that possibly runs
> during template rendering (it can be many, and the idea is to call
> them repeatedly using different data tables). So this would mean to
> fixup _ENV for each chunk everytime the render() function is called?

When you convert templates to Lua code, add this line at the top of each script:
        local _ENV = ...

(That's three dots as in varargs.)
Then you can run each script passing a suitable table as its env at run time.

Reply | Threaded
Open this post in threaded view
|

Re: Setting globals in the C API

Marc Balmer

> Am 02.08.2016 um 20:37 schrieb Luiz Henrique de Figueiredo <[hidden email]>:
>
>> I assume that I have to set _ENV for each chunk that possibly runs
>> during template rendering (it can be many, and the idea is to call
>> them repeatedly using different data tables). So this would mean to
>> fixup _ENV for each chunk everytime the render() function is called?
>
> When you convert templates to Lua code, add this line at the top of each script:
> local _ENV = ...
>
> (That's three dots as in varargs.)
> Then you can run each script passing a suitable table as its env at run time.
>

I will try that.  It has been proposed to me in private mail as well.

Thanks!
Reply | Threaded
Open this post in threaded view
|

Re: Setting globals in the C API

Patrick Donnelly
On Tue, Aug 2, 2016 at 3:12 PM, Marc Balmer <[hidden email]> wrote:

>> Am 02.08.2016 um 20:37 schrieb Luiz Henrique de Figueiredo <[hidden email]>:
>>
>>> I assume that I have to set _ENV for each chunk that possibly runs
>>> during template rendering (it can be many, and the idea is to call
>>> them repeatedly using different data tables). So this would mean to
>>> fixup _ENV for each chunk everytime the render() function is called?
>>
>> When you convert templates to Lua code, add this line at the top of each script:
>>       local _ENV = ...
>>
>> (That's three dots as in varargs.)
>> Then you can run each script passing a suitable table as its env at run time.
>>
>
> I will try that.  It has been proposed to me in private mail as well.

You might also look at this custom loader used in the Nmap Scripting
Engine that allows repeatedly executing a chunk with a new environment
each time:

https://github.com/nmap/nmap/blob/master/nse_main.lua#L242-L256

--
Patrick Donnelly

Reply | Threaded
Open this post in threaded view
|

Re: Setting globals in the C API

Marc Balmer
In reply to this post by Marc Balmer
Thanks for all the comment, public or private, I now got it properly working.

Passing _ENV as the first paramters works nicely and as expected.  Now the
codes needs a it cleaning and then I will put it on github.

- mb