1local filter_array = require("lib.lousy.util").table.filter_array
2local lua_escape = require("lib.lousy.util").lua_escape
3
4local luakit_files
5
6local function get_luakit_files ()
7    if not luakit_files then
8        luakit_files = {}
9        local f = io.popen("find . -type f | grep -v '\\./\\.' | sed 's#^\\./##'")
10        for line in f:lines() do
11            -- Check file against filters derived from .gitignore
12            local ok = true
13            ok = ok and not line:match("^doc/apidocs/")
14            ok = ok and not line:match("^doc/html/")
15            ok = ok and not line:match("%.o$")
16            ok = ok and not line:match("%.1$")
17            ok = ok and not line:match("%.swp$")
18            ok = ok and not line:match("~$")
19            ok = ok and not line:match("^common/tokenize.[ch]$")
20            ok = ok and not ({
21                ["luakit"] = true, ["luakit.so"] = true, ["luakit.1.gz"] = true,
22                ["tests/util.so"] = true, ["buildopts.h"] = true, ["tags"] = true,
23            })[line]
24            if ok then table.insert(luakit_files, line) end
25        end
26        f:close()
27    end
28
29    return luakit_files
30end
31
32local function path_is_in_directory(path, dir)
33    if path == "." then return true end
34    return string.find(path, "^"..lua_escape(dir))
35end
36
37local function find_files(dirs, patterns, excludes)
38    assert(dirs ~= ".", "Bad pattern '.'; use empty string instead")
39    assert(type(dirs) == "string" or type(dirs) == "table",
40        "Bad search location: expected string or table")
41    assert(type(patterns) == "string" or type(patterns) == "table",
42        "Bad patterns: expected string or table")
43    assert(excludes == nil or type(excludes) == "table",
44        "Bad exclusion list: expected nil or table")
45
46    if type(dirs) == "string" then dirs = { dirs } end
47    if type(patterns) == "string" then patterns = { patterns } end
48    if excludes == nil then excludes = {} end
49
50    for _, dir in ipairs(dirs) do
51        assert(type(dir) == "string", "Each search location must be a string")
52    end
53    for _, pattern in ipairs(patterns) do
54        assert(type(pattern) == "string", "Each pattern must be a string")
55    end
56    for _, exclude in ipairs(excludes) do
57        assert(type(exclude) == "string", "Each exclude must be a string")
58    end
59
60    -- Get list of files tracked by luakit
61    get_luakit_files()
62
63    -- Filter to those inside the given directories
64    local file_list = {}
65    for _, file in ipairs(luakit_files) do
66        local dir_match = false
67        for _, dir in ipairs(dirs) do
68            dir_match = dir_match or path_is_in_directory(file, dir)
69        end
70        local pat_match = false
71        for _, pattern in ipairs(patterns) do
72            pat_match = pat_match or string.find(file, pattern)
73        end
74        if dir_match and pat_match then
75            table.insert(file_list, file)
76        end
77    end
78
79    -- Remove all files in excludes
80    if excludes then
81        file_list = filter_array(file_list, function (_, file)
82            for _, exclude_pat in ipairs(excludes) do
83                if string.find(file, exclude_pat) then return false end
84            end
85            return true
86        end)
87    end
88
89    -- Return filtered list
90    return file_list
91end
92
93return {
94    get_luakit_files = get_luakit_files,
95    find_files = find_files,
96}
97
98-- vim: et:sw=4:ts=8:sts=4:tw=80
99