123 lines
3.3 KiB
Lua
123 lines
3.3 KiB
Lua
-- glob.lua - Glob syntax elements for declarative tundra.lua usage
|
|
|
|
module(..., package.seeall)
|
|
|
|
local util = require "tundra.util"
|
|
local path = require "tundra.path"
|
|
local decl = require "tundra.decl"
|
|
local dirwalk = require "tundra.dirwalk"
|
|
|
|
local ignored_dirs = util.make_lookup_table { ".git", ".svn", "CVS" }
|
|
|
|
local function glob(directory, recursive, filter_fn)
|
|
local result = {}
|
|
|
|
local function dir_filter(dir_name)
|
|
if not recursive or ignored_dirs[dir_name] then
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
|
|
for _, path in ipairs(dirwalk.walk(directory, dir_filter)) do
|
|
if filter_fn(path) then
|
|
result[#result + 1] = path
|
|
end
|
|
end
|
|
return result
|
|
end
|
|
|
|
-- Glob syntax - Search for source files matching extension list
|
|
--
|
|
-- Synopsis:
|
|
-- Glob {
|
|
-- Dir = "...",
|
|
-- Extensions = { ".ext", ... },
|
|
-- [Recursive = false,]
|
|
-- }
|
|
--
|
|
-- Options:
|
|
-- Dir = "directory" (required)
|
|
-- - Base directory to search in
|
|
--
|
|
-- Extensions = { ".ext1", ".ext2" } (required)
|
|
-- - List of file extensions to include
|
|
--
|
|
-- Recursive = boolean (optional, default: true)
|
|
-- - Specified whether to recurse into subdirectories
|
|
function Glob(args)
|
|
local recursive = args.Recursive
|
|
if type(recursive) == "nil" then
|
|
recursive = true
|
|
end
|
|
if not args.Extensions then
|
|
croak("no 'Extensions' specified in Glob (Dir is '%s')", args.Dir)
|
|
end
|
|
local extensions = assert(args.Extensions)
|
|
local ext_lookup = util.make_lookup_table(extensions)
|
|
return glob(args.Dir, recursive, function (fn)
|
|
local ext = path.get_extension(fn)
|
|
return ext_lookup[ext]
|
|
end)
|
|
end
|
|
|
|
-- FGlob syntax - Search for source files matching extension list with
|
|
-- configuration filtering
|
|
--
|
|
-- Usage:
|
|
-- FGlob {
|
|
-- Dir = "...",
|
|
-- Extensions = { ".ext", .... },
|
|
-- Filters = {
|
|
-- { Pattern = "/[Ww]in32/", Config = "win32-*-*" },
|
|
-- { Pattern = "/[Dd]ebug/", Config = "*-*-debug" },
|
|
-- ...
|
|
-- },
|
|
-- [Recursive = false],
|
|
-- }
|
|
local function FGlob(args)
|
|
-- Use the regular glob to fetch the file list.
|
|
local files = Glob(args)
|
|
local pats = {}
|
|
local result = {}
|
|
|
|
-- Construct a mapping from { Pattern = ..., Config = ... }
|
|
-- to { Pattern = { Config = ... } } with new arrays per config that can be
|
|
-- embedded in the source result.
|
|
for _, fitem in ipairs(args.Filters) do
|
|
if not fitem.Config then
|
|
croak("no 'Config' specified in FGlob (Pattern is '%s')", fitem.Pattern)
|
|
end
|
|
local tab = { Config = assert(fitem.Config) }
|
|
pats[assert(fitem.Pattern)] = tab
|
|
result[#result + 1] = tab
|
|
end
|
|
|
|
-- Traverse all files and see if they match any configuration filters. If
|
|
-- they do, stick them in matching list. Otherwise, just keep them in the
|
|
-- main list. This has the effect of returning an array such as this:
|
|
-- {
|
|
-- { "foo.c"; Config = "abc-*-*" },
|
|
-- { "bar.c"; Config = "*-*-def" },
|
|
-- "baz.c", "qux.m"
|
|
-- }
|
|
for _, f in ipairs(files) do
|
|
local filtered = false
|
|
for filter, list in pairs(pats) do
|
|
if f:match(filter) then
|
|
filtered = true
|
|
list[#list + 1] = f
|
|
break
|
|
end
|
|
end
|
|
if not filtered then
|
|
result[#result + 1] = f
|
|
end
|
|
end
|
|
return result
|
|
end
|
|
|
|
decl.add_function("Glob", Glob)
|
|
decl.add_function("FGlob", FGlob)
|
|
|