util.pluginloader: Return full file path from internal file loader on success, not...
[prosody.git] / util / pluginloader.lua
1 -- Prosody IM
2 -- Copyright (C) 2008-2010 Matthew Wild
3 -- Copyright (C) 2008-2010 Waqas Hussain
4 -- 
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
7 --
8
9 local dir_sep, path_sep = package.config:match("^(%S+)%s(%S+)");
10 local plugin_dir = {};
11 for path in (CFG_PLUGINDIR or "./plugins/"):gsub("[/\\]", dir_sep):gmatch("[^"..path_sep.."]+") do
12         path = path..dir_sep; -- add path separator to path end
13         path = path:gsub(dir_sep..dir_sep.."+", dir_sep); -- coalesce multiple separaters
14         plugin_dir[#plugin_dir + 1] = path;
15 end
16
17 local io_open, os_time = io.open, os.time;
18 local loadstring, pairs = loadstring, pairs;
19
20 module "pluginloader"
21
22 local function load_file(name)
23         local file, err, path;
24         for i=1,#plugin_dir do
25                 path = plugin_dir[i]..name;
26                 file, err = io_open(path);
27                 if file then break; end
28         end
29         if not file then return file, err; end
30         local content = file:read("*a");
31         file:close();
32         return content, path;
33 end
34
35 function load_resource(plugin, resource, loader)
36         local path, name = plugin:match("([^/]*)/?(.*)");
37         if name == "" then
38                 if not resource then
39                         resource = "mod_"..plugin..".lua";
40                 end
41                 loader = loader or load_file;
42
43                 local content, err = loader(plugin.."/"..resource);
44                 if not content then content, err = loader(resource); end
45                 -- TODO add support for packed plugins
46                 
47                 return content, err;
48         else
49                 if not resource then
50                         resource = "mod_"..name..".lua";
51                 end
52                 loader = loader or load_file;
53
54                 local content, err = loader(plugin.."/"..resource);
55                 if not content then content, err = loader(path.."/"..resource); end
56                 -- TODO add support for packed plugins
57                 
58                 return content, err;
59         end
60 end
61
62 function load_code(plugin, resource)
63         local content, err = load_resource(plugin, resource);
64         if not content then return content, err; end
65         return loadstring(content, "@"..err);
66 end
67
68 return _M;