--- Reads configuration files into a Lua table.
-- Understands INI files, classic Unix config files, and simple -- delimited columns of values.
--
-- # test.config
-- # Read timeout in seconds
-- read.timeout=10
-- # Write timeout in seconds
-- write.timeout=5
-- #acceptable ports
-- ports = 1002,1003,1004
--
-- -- readconfig.lua
-- require 'pl'
-- local t = config.read 'test.config'
-- print(pretty.write(t))
--
-- ### output #####
-- {
-- ports = {
-- 1002,
-- 1003,
-- 1004
-- },
-- write_timeout = 5,
-- read_timeout = 10
-- }
--
-- See the Guide for further discussion
-- @class module
-- @name pl.config
local type,tonumber,ipairs,io, table = _G.type,_G.tonumber,_G.ipairs,_G.io,_G.table
local function split(s,re)
local res = {}
local t_insert = table.insert
re = '[^'..re..']+'
for k in s:gmatch(re) do t_insert(res,k) end
return res
end
local function strip(s)
return s:gsub('^%s+',''):gsub('%s+$','')
end
local function strip_quotes (s)
return s:gsub("['\"](.*)['\"]",'%1')
end
local config = {}
--- like io.lines(), but allows for lines to be continued with '\'.
-- @param file a file-like object (anything where read() returns the next line) or a filename.
-- Defaults to stardard input.
-- @return an iterator over the lines, or nil
-- @return error 'not a file-like object' or 'file is nil'
function config.lines(file)
local f,openf,err
local line = ''
if type(file) == 'string' then
f,err = io.open(file,'r')
if not f then return nil,err end
openf = true
else
f = file or io.stdin
if not file.read then return nil, 'not a file-like object' end
end
if not f then return nil, 'file is nil' end
return function()
local l = f:read()
while l do
-- does the line end with '\'?
local i = l:find '\\%s*$'
if i then -- if so,
line = line..l:sub(1,i-1)
elseif line == '' then
return l
else
l = line..l
line = ''
return l
end
l = f:read()
end
if openf then f:close() end
end
end
--- read a configuration file into a table
-- @param file either a file-like object or a string, which must be a filename
-- @param cnfg a configuration table that may contain these fields:
--