3

In lua, is there any way to read an interface file to extract name/methods/args?

I have an .idl file like this:

interface
{
    name = myInterface,
    methods = {
        testing = {
            resulttype = "double",
            args = {{direction = "in",
            type = "double"},
        }
    }
}

This is equal to the code bellow (easier to read):

interface myInterface {
  double testing (in double a);
};

I can read file, load as string and parse with gmatch for example to extract information, but is there any easy mode to parse this info?

At the end i want something (a table for example) with the interface name, their methods, result types and args. Just to know the interface that i`m working.

hjpotter92
  • 78,589
  • 36
  • 144
  • 183
briba
  • 2,857
  • 2
  • 31
  • 59
  • [An example](http://msdn.microsoft.com/en-us/library/windows/desktop/aa378710%28v=vs.85%29.aspx) of IDL-file from microsoft site looks quite different. – Egor Skriptunoff Apr 18 '13 at 14:17
  • Is that double `{{` supposed to be a single `{`? In that case you could just insert an `=` between `interface` and the opening `{` and load the file as lua code and simply run it. That would give you a table (called `interface`) with all the data you need, wouldn't it? – Martin Ender Apr 18 '13 at 14:20
  • Egor, looks different. But i think lua can understant this code (i think xD hahaha). If not, i can create an interface file like you sayd on link. But i must know how to parse interface – briba Apr 18 '13 at 14:45
  • buettner, this double is not a single parameter (was that your question? I dont know if i understood). Actually the interface can have multiple parameters. And i don't know how to load this an extract this information – briba Apr 18 '13 at 14:46
  • And one file only carry one interface. In this case, i should write interface = {interface code} and lua will understant? – briba Apr 18 '13 at 14:49
  • 2
    @BrenoRiba what I was saying was that your braces are mismatched. you have 5 opening `{` and only 4 closing `}`. i guess you are missing a closing brace then. there are certainly more elegant ways to do it, but if you wrote `interface = { ... }` and fixed that brace-mismatch, this would be perfectly valid Lua code, so you could then do `interface.name` or `interface.methods.testing.args[0].type` or whatever you want. – Martin Ender Apr 18 '13 at 16:52
  • guess i forgot the last braces xD... How can i load this lua file then? And what would be the more elegant way to do it? thank you buettner!! – briba Apr 18 '13 at 17:16

1 Answers1

2

Lua has several facilities to interpret chunks of code. Namely, dofile, loadfile and loadstring. Luckily, your input file is almost valid Lua code (assuming those braces were matched). The only thing that is problematic is interface {.

All of the above functions effectively create a function object with a file's or a string's contents as their code. dofile immediately executes that function, while the others return a function, which you can invoke whenever you like. Therefore, if you're free to change the files, replace interface in the first line with return. Then you can do:

local interface = dofile("input.idl")

And interface will be a nice table, just as you have specified it in the file. If you cannot change those files to your liking, you will have to load the file into the string, perform some string manipulation (specifically, replace the first interface with return) and then use loadstring instead:

io.input("input.idl")
local input = io.read("*all")
input = string.gsub(input, "^interface", "return") -- ^ marks beginning of string
local f = loadstring(input)
local interface = f()

In both cases this is what you will get:

> require"pl.pretty".dump(interface)
{
  name = "myInterface",
  methods = {
    testing = {
      args = {
        {
          type = "double",
          direction = "in"
        }
      },
      resulttype = "double"
    }
  }
}    

> print(interface.methods.testing.args[1].type)
double

EDIT:

I just realised, in your example input myInterface is not enclosed in " and therefore not a proper string. Is that also a mistake in your input file or is that what your files actually look like? In the latter case, you would need to change that as well. Lua is not going to complain if it's a name it doesn't know, but you also won't get the field in that case.

Martin Ender
  • 43,427
  • 11
  • 90
  • 130
  • Thank you very much for your answer! Guess it's more clear for me now! I tryed to make this example using loadstring (as you showed above) and i put myInterface enclosed in quotes to. Now im stucked at the line "local interface = f()" ...it returns me a nil reference. – briba Apr 18 '13 at 19:25
  • What is require"pl.pretty".dump(interface) for? I didnt understand this line =/ – briba Apr 18 '13 at 19:25
  • @BrenoRiba that is just a neat way to output an entire nested table in nice formatting. Does your input file still contain `interface` in the first line? If not, change `"^interface"` to `"^"`. – Martin Ender Apr 18 '13 at 19:33
  • WOOOOOOOOOOOWWWWWWWWWWWW!!!!!!!!!!!!!!!!!!!!!!!!! buettner i dont know how to say thanks for this! Totally works!!! *happy* Thank you very very much dude, helped me a lot!!! – briba Apr 18 '13 at 19:40
  • 1
    @BrenoRiba you're welcome. in fact, using `gsub` in that case might be a bit overkill. `input = "return " .. input` would do the trick, as well ;). Or, if you're free to write the files in any way you want, just include the `return` in the file right away. Saves lines of code and execution time. – Martin Ender Apr 18 '13 at 19:42
  • Very nice tips! I will change my ".idl" file so in this case i won't need gsub anymore! \o/ Thanks again dude! – briba Apr 18 '13 at 19:55
  • Sorry bothering you again buettner, but is there a way to get the function names? In this case, a way to get "testing"? interface.methods[1] does not work =/ – briba Apr 19 '13 at 03:16
  • 2
    @BrenoRiba `for key, value in pairs(interface.methods) do ...` will iterate over all key-value pairs in the table, so in each iteration of the loop `key` will be the method name and `value` the method's table – Martin Ender Apr 19 '13 at 07:26
  • Dude... you`re the best! xD – briba Apr 19 '13 at 13:33