epics-modules / lua

Lua Scripting Record for EPICS
https://epics-modules.github.io/lua/
7 stars 4 forks source link

setting #ENABLE_HASH_COMMENTS in C code #21

Closed bfrk closed 3 years ago

bfrk commented 3 years ago

I have just started to investigate using luaShell for our IOCs. The first problem I have encountered is that we use a 'shebang' line at the top of our st.cmd files, e.g.

#!./SIOC99C

Setting #ENABLE_HASH_COMMENTS after that is too late, doing it before that is also not possible because shebang is only recognized in the first line of the file. So I would like to be able to set this from the C code side.

keenanlang commented 3 years ago

With commit 86873c6185f3bb8cd382eaff22ff831491da953f, I've made the switch for allowing hash-comments a global variable rather than being stored in the special registry table. This means that it can be set when the lua shell is invoked.

If using c++, the luash function is overloaded and can be called

luash(state, file_path, macros)

state being a lua_State* that has been previously created, or NULL for a brand new state.
file_path being the path to the file being loaded, or NULL for an interactive console.
and macros would have "LEPICS_HASH_COMMENTS=YES" to set the switch used.

If solely in C, this is split out into luashLoad command

luashLoad(file_path, macros)
bfrk commented 3 years ago

Thanks, this is great! I'll try it out today.

bfrk commented 3 years ago

Sorry for the delay. Works for me, thanks!

BTW, I am stumbling over another problem now, which is related because it is also concerned with replacing iocsh with luash: we are using macro replacements in commands e.g.

${IOC}_registerRecordDeviceDriver(pdbbase)

Is there a way to accommodate this sort of thing in luash? I am not suggesting you should go out of your way to support that, it's more a question if there is some sort of trick to make this work.

keenanlang commented 3 years ago

Nothing is particularly elegant, but you can either query the global environment table or load a string as lua bytecode and run it.

_ENV[IOC .. "_registerRecordDeviceDriver"](pdbbase)  

or

load(IOC .. "_registerRecordDeviceDriver(pdbbase)")()

EDIT: Missed the underscore in the examples

bfrk commented 3 years ago

Ah, very nice, I forgot that lua has first class procedures. Thanks for the reminder. So _ENV is a global table that stores the environment. Is that specific to this module or a general lua feature?

keenanlang commented 3 years ago

It's a general lua feature. Technically, _G is the global table that stores the global environment for all the code within a given lua_State, and then _ENV is the current code chunk's environment. For basic execution, it's not a distinction that would matter much, but the two might be different if there's sandboxing going on or if you're doing partial function evaluation.

bfrk commented 3 years ago

Okay, thanks. I am studying the lua manual now, so hopefully I won't bother you with questions about lua in general anymore ;-)