Software /
code /
prosody
Comparison
core/configmanager.lua @ 3923:f95375aceed0
configmanager: Support for wildcards in Include directives
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Mon, 20 Dec 2010 14:06:32 +0000 |
parent | 3898:b1140808598b |
child | 3929:7cb03d67101b |
comparison
equal
deleted
inserted
replaced
3922:b77bafa4c502 | 3923:f95375aceed0 |
---|---|
5 -- This project is MIT/X11 licensed. Please see the | 5 -- This project is MIT/X11 licensed. Please see the |
6 -- COPYING file in the source package for more information. | 6 -- COPYING file in the source package for more information. |
7 -- | 7 -- |
8 | 8 |
9 local _G = _G; | 9 local _G = _G; |
10 local setmetatable, loadfile, pcall, rawget, rawset, io, error, dofile, type, pairs, table, format = | 10 local setmetatable, loadfile, pcall, rawget, rawset, io, error, dofile, type, pairs, table = |
11 setmetatable, loadfile, pcall, rawget, rawset, io, error, dofile, type, pairs, table, string.format; | 11 setmetatable, loadfile, pcall, rawget, rawset, io, error, dofile, type, pairs, table; |
12 | 12 local format, math_max = string.format, math.max; |
13 | 13 |
14 local fire_event = prosody and prosody.events.fire_event or function () end; | 14 local fire_event = prosody and prosody.events.fire_event or function () end; |
15 | 15 |
16 local lfs = require "lfs"; | |
16 local path_sep = package.config:sub(1,1); | 17 local path_sep = package.config:sub(1,1); |
17 | 18 |
18 module "configmanager" | 19 module "configmanager" |
19 | 20 |
20 local parsers = {}; | 21 local parsers = {}; |
69 -- Helper function to resolve relative paths (needed by config) | 70 -- Helper function to resolve relative paths (needed by config) |
70 do | 71 do |
71 local rel_path_start = ".."..path_sep; | 72 local rel_path_start = ".."..path_sep; |
72 function resolve_relative_path(parent_path, path) | 73 function resolve_relative_path(parent_path, path) |
73 if path then | 74 if path then |
75 -- Some normalization | |
76 parent_path = parent_path:gsub("%"..path_sep.."+$", ""); | |
77 path = path:gsub("^%.%"..path_sep.."+", ""); | |
78 | |
74 local is_relative; | 79 local is_relative; |
75 if path_sep == "/" and path:sub(1,1) ~= "/" then | 80 if path_sep == "/" and path:sub(1,1) ~= "/" then |
76 is_relative = true; | 81 is_relative = true; |
77 elseif path_sep == "\\" and (path:sub(1,1) ~= "/" and path:sub(2,3) ~= ":\\") then | 82 elseif path_sep == "\\" and (path:sub(1,1) ~= "/" and path:sub(2,3) ~= ":\\") then |
78 is_relative = true; | 83 is_relative = true; |
81 return parent_path..path_sep..path; | 86 return parent_path..path_sep..path; |
82 end | 87 end |
83 end | 88 end |
84 return path; | 89 return path; |
85 end | 90 end |
91 end | |
92 | |
93 -- Helper function to convert a glob to a Lua pattern | |
94 local function glob_to_pattern(glob) | |
95 return "^"..glob:gsub("[%p*?]", function (c) | |
96 if c == "*" then | |
97 return ".*"; | |
98 elseif c == "?" then | |
99 return "."; | |
100 else | |
101 return "%"..c; | |
102 end | |
103 end).."$"; | |
86 end | 104 end |
87 | 105 |
88 function load(filename, format) | 106 function load(filename, format) |
89 format = format or filename:match("%w+$"); | 107 format = format or filename:match("%w+$"); |
90 | 108 |
135 -- Built-in Lua parser | 153 -- Built-in Lua parser |
136 do | 154 do |
137 local loadstring, pcall, setmetatable = _G.loadstring, _G.pcall, _G.setmetatable; | 155 local loadstring, pcall, setmetatable = _G.loadstring, _G.pcall, _G.setmetatable; |
138 local setfenv, rawget, tostring = _G.setfenv, _G.rawget, _G.tostring; | 156 local setfenv, rawget, tostring = _G.setfenv, _G.rawget, _G.tostring; |
139 parsers.lua = {}; | 157 parsers.lua = {}; |
140 function parsers.lua.load(data, filename, config) | 158 function parsers.lua.load(data, config_file, config) |
141 local env; | 159 local env; |
142 -- The ' = true' are needed so as not to set off __newindex when we assign the functions below | 160 -- The ' = true' are needed so as not to set off __newindex when we assign the functions below |
143 env = setmetatable({ | 161 env = setmetatable({ |
144 Host = true, host = true, VirtualHost = true, | 162 Host = true, host = true, VirtualHost = true, |
145 Component = true, component = true, | 163 Component = true, component = true, |
197 return handle_config_options(module); | 215 return handle_config_options(module); |
198 end | 216 end |
199 end | 217 end |
200 env.component = env.Component; | 218 env.component = env.Component; |
201 | 219 |
202 function env.Include(file) | 220 function env.Include(file, wildcard) |
203 local f, err = io.open(file); | 221 if file:match("[*?]") then |
204 if f then | 222 local path_pos, glob = file:match("()([^"..path_sep.."]+)$"); |
205 local data = f:read("*a"); | 223 local path = file:sub(1, math_max(path_pos-2,0)); |
206 local file = resolve_relative_path(filename:gsub("[^"..path_sep.."]+$", ""), file); | 224 if #path > 0 then |
207 local ret, err = parsers.lua.load(data, file, config); | 225 path = resolve_relative_path(config_file:gsub("[^"..path_sep.."]+$", ""), path); |
208 if not ret then error(err:gsub("%[string.-%]", file), 0); end | 226 else |
209 end | 227 path = "."; |
210 if not f then error("Error loading included "..file..": "..err, 0); end | 228 end |
211 return f, err; | 229 local patt = glob_to_pattern(glob); |
230 for f in lfs.dir(path) do | |
231 if f:sub(1,1) ~= "." and f:match(patt) then | |
232 env.Include(path..path_sep..f); | |
233 end | |
234 end | |
235 else | |
236 local f, err = io.open(file); | |
237 if f then | |
238 local data = f:read("*a"); | |
239 local file = resolve_relative_path(config_file:gsub("[^"..path_sep.."]+$", ""), file); | |
240 local ret, err = parsers.lua.load(data, file, config); | |
241 if not ret then error(err:gsub("%[string.-%]", file), 0); end | |
242 end | |
243 if not f then error("Error loading included "..file..": "..err, 0); end | |
244 return f, err; | |
245 end | |
212 end | 246 end |
213 env.include = env.Include; | 247 env.include = env.Include; |
214 | 248 |
215 function env.RunScript(file) | 249 function env.RunScript(file) |
216 return dofile(resolve_relative_path(filename:gsub("[^"..path_sep.."]+$", ""), file)); | 250 return dofile(resolve_relative_path(config_file:gsub("[^"..path_sep.."]+$", ""), file)); |
217 end | 251 end |
218 | 252 |
219 local chunk, err = loadstring(data, "@"..filename); | 253 local chunk, err = loadstring(data, "@"..config_file); |
220 | 254 |
221 if not chunk then | 255 if not chunk then |
222 return nil, err; | 256 return nil, err; |
223 end | 257 end |
224 | 258 |