keith_k

NSA function to convert config to nested table

Discussion created by keith_k on Aug 18, 2009
I think I have been spoiled by the Perl SDK, particularly when dealing with probe config files.  The SDK converts the config into a nested hash, which I find really easy to process.  The NSA converts a config file to a table but it is not nested for nested config sections.  For example, take this config:
<setup>
   <section1>
      setting1 = 1
      setting2 = two
   </section1>
   <section2>
      setting1 = one
      setting2 = 2
   </section2>
</setup>
That results in the following table when you use the probe.config() function:
{
    /setup = {}
    /setup/section1 = {
        setting1 = 1
        setting2 = two
    }
    /setup/section2 = {
        setting1 = one
        setting2 = 2
    }
}
While nice and convenient for processing in some ways, I found this to be difficult in certain cases and wanted something more like Perl.  I created the following function:
function probe.nested_config (config_file)

    -- Define local function to add keys to table recursively
    local function add_keys (parent_table, key_list)

        -- Reached end of recursion; no more keys left to add
        if key_list == nil or #key_list == 0 then
            -- Return inner-most table
            return parent_table
        end

        -- Use (and remove) first entry in key list
        local new_key = table.remove(key_list, 1)

        -- Create a table within the table using key
        -- (unless there is already a value at that table key)
        if parent_table == nil then
            parent_table = {}
        end

        -- Continue with remaining key list, using nested table as new parent
        return add_keys(parent_table, key_list)
    end

    -- Use built-in probe.config() function to read config into flat table
    local proc_config = probe.config(config_file)

    -- Make sure config was processed
    if proc_config == nil then return nil end

    -- New empty table for nested config
    local config = {}

    -- Sort keys so that parents are processed before children
    local sorted_keys = sortkeys(proc_config)
    local i, key
    for i,key in ipairs(sorted_keys) do

        -- Break key into individual parts (initially separated by slashes)
        local key_list = {}
        local part
        for part in key:sub(2):gmatch("+") do
            key_list = part
        end

        -- Create or find inner table specified by key list
        local new_table = add_keys(config, key_list)

        -- Make sure there are values in this config section
        if proc_config ~= nil then

            -- Copy all key/value pairs into inner table
            local k, v
            for k,v in pairs(proc_config) do
                new_table = v
            end
        end
    end

    -- Return nested table
    return config
end
This function depends on a sortkeys() function I wrote as well:
function sortkeys (t)
   local s = {}
   for k in pairs(t) do
      s = k
   end
   table.sort(s)
   return s
end
It has been working well for me so far.  Enjoy!

-Keith

Outcomes