lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]




What i usually do is something like:

---------
function read_settings(filename)
    local f=loadfile(filename)
    local t={}
setfenv(f,t)
    f()
    return t
end

local settings=read_settings(filename)
--------


Nice.

I was trying to elaborate on this a little bit to see if I could make sort of a mini DSL for
configuration of a syslogd replacement i am working on.

It should give me the possibility of defining a number of records with settable defaults.

I ended up with a config file like syntax like

#config

defaults [[ rotlog = 5 ]]

config [[
   name = "online.log"
   programs = { "pppd", "chat" }
]]

defaults [[ level = "error" ]]

config [[
   name    = "fatal"
   size    = 200 * k
   pattern = { "^[Ff]atal", "%W[Ff]atal" }
]]


config[[ ]] -- Catch all


The first shot was with table constructors as argument to "defaults" and "config", but inspired by this thread I thought i'd try and make the argument an ordinary lua chunk. The experience was a little mind boggling, trying to figure out how to keep everything in working order along with the required setfenv's. Anyway here is what i came up with, in case it is of use to anyone.

-- Define the default defaults, the resulting table & the sandbox
local logconfigs = {}
local cfg = {
  log_defaults = {
     dir        = "/var/log";
     name       = "messages";
     action     = { file=1 };
     size       = 100 * 1024;
     rotlog     = 1;
     level      = "info";
     facilities = "*";
     pattern    = {};
     programs   = {};
     shortfmt   = 1;
     dobreak    = 0;
  };
  k = 1024;
  m = 1024 * 1024;
  --
  logconfigs = logconfigs;
  loadstring = loadstring;
  setmetatable = setmetatable;
  setfenv = setfenv;
  table_insert = table.insert;
}

-- Cater for the defaults[[...]] section in the config file
function cfg.defaults(s)
  conf_defaults = {k = k, m = m}
  setmetatable(conf_defaults, {__index = log_defaults}) -- Route through
  local chunk = loadstring(s)
  setfenv(chunk, conf_defaults)
  chunk()
  defmeta = { __index = conf_defaults }
end
setfenv(cfg.defaults, cfg)
cfg.defaults'' -- Default is straight through to log_defaults

-- Cater for the config[[...]] sections in the config file
function cfg.config(s)
  local v = {}
  setmetatable(v, defmeta)
  local chunk = loadstring(s)
  setfenv(chunk, v)
  chunk()
  table_insert(logconfigs, v)
end
setfenv(cfg.config, cfg)

-- The sandboxed loader
function cfg.loadconfig(chunk)
  setfenv(chunk, cfg)
  chunk()
end


-- Load config file
cfg.loadconfig(assert(loadfile("/etc/syslogl.conf")))