Search code examples
lualua-table

How to parse the config file shown to create a lua table that is desired?


I want to parse a config file which has information like:

[MY_WINDOW_0]
Address = 0xA0B0C0D0
Size = 0x100
Type = cpu0

[MY_WINDOW_1]
Address = 0xB0C0D0A0
Size = 0x200
Type = cpu0

[MY_WINDOW_2]
Address = 0xC0D0A0B0
Size = 0x100
Type = cpu1

into a LUA table as follows

CPU_TRACE_WINDOWS = 
{
  ["cpu0"] = {{address = 0xA0B0C0D0, size = 0x100},{address = 0xB0C0D0A0, size = 0x200},}
  ["cpu1"] = {{address = 0xC0D0A0B0, size = 0x100},...}
}

I tried my best with some basic LUA string manipulation functions but couldn't get the output that I'm looking for due to repetition of strings in each sections like 'Address',' Size', 'Type' etc. Also my actual config file is huge with 20 such sections.

I got so far, this is basically one section of the code, rest would be just repetition of the logic.

OriginalConfigFile = "test.cfg"
os.execute("cls")

CPU_TRACE_WINDOWS = {}
local bus
for line in io.lines(OriginalConfigFile) do
  if string.find(line, "Type") ~= nil then
    bus = string.gsub(line, "%a=%a", "")    
    k,v = string.match(bus, "(%w+) = (%w+)")    
    table.insert(CPU_TRACE_WINDOWS, v)     
  end    
end

Basically I'm having trouble with coming up with the FINAL TABLE STRUCTURE that I need. v here is the different rvalues of the string "Type". I'm having issues with arranging it in the table. I'm currently working to find a solution but I thought I could ask for help meanwhile.


Solution

  • This should work for you. Just change the filename to wherever you have your config file stored.

    f, Address, Size, Type = io.input("configfile"), "", "", ""
    CPU_TRACE_WINDOWS = {}
    
    for line in f:lines() do
       if line:find("MY_WINDOW") then
            Type = ""
            Address = ""
            Size = ""
        elseif line:find("=") then
            _G[line:match("^%a+")] = line:match("[%d%a]+$")
    
            if line:match("Type") then
                if not CPU_TRACE_WINDOWS[Type] then
                    CPU_TRACE_WINDOWS[Type] = {}
                end
                    table.insert(CPU_TRACE_WINDOWS[Type], {address = Address, size = Size})
                end
            end
        end
    end
    

    It searches for the MY_WINDOW phrase and resets the variable. If the table exists within CPU_TRACE_WINDOWS, then it just appends a new table value, otherwise it just creates it. Note that this is dependent upon Type always being the last entry. If it switches up anywhere, then it will not have all the required information. There may be a cleaner way to do it, but this works (tested on my end).

    Edit: Whoops, forgot to change the variables in the middle there if MY_WINDOW matched. That needed to be corrected.

    Edit 2: Cleaned up the redundancy with table.insert. Only need it once, just need to make sure the table is created first.