From ab770255162a998c0953ce6f06d10238b715b786 Mon Sep 17 00:00:00 2001 From: Nathan DECHER Date: Sun, 13 Sep 2020 13:07:10 +0200 Subject: [PATCH] rewrite wildcard, fix #1 --- fsutil.moon | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++ util.moon | 41 ++----------------------- 2 files changed, 91 insertions(+), 38 deletions(-) create mode 100644 fsutil.moon diff --git a/fsutil.moon b/fsutil.moon new file mode 100644 index 0000000..de42388 --- /dev/null +++ b/fsutil.moon @@ -0,0 +1,88 @@ +import dir, attributes from require 'lfs' + +import gmatch, match, gsub, sub from string +import insert, concat from table + +ls = (d) -> + [f for f in dir d when f!='.' and f!='..'] + +lswithpath = (d) -> + if d=='' + return ls '.' + [d..'/'..f for f in dir d when f!='.' and f!='..'] + +exists = (f) -> + (attributes f) != nil + +isdir = (f) -> + a = attributes f + a and a.mode == 'directory' or false + +mtime = (f) -> + a = attributes f + a and a.modification + +matchglob = (str, glob) -> + patt = '^'..(gsub (gsub glob, '%*%*', '.*'), '%*', '[^/]*')..'$' + rst = if (type str)=='table' + results, i = {}, 1 + for s in *str + rst = (match s, patt) and s + results[i], i = rst, i+1 if rst + results + else + (match str, patt) and str + rst + +wildcard = (glob) -> + parts = [part for part in gmatch glob, '[^/]+'] + absolute = (sub glob, 1, 1)=='/' + + for i, part in ipairs parts + prevpath = (absolute and '/' or '') .. concat parts, '/', 1, i-1 + currpath = prevpath .. '/' .. part + + if match part, '%*%*.*%*%*' + error "Two '**' in the same path component in a wildcard" + + if match part, '%*%*' + prefix = match currpath, '^(.*)%*%*' + suffix = (match part, '%*%*(.*)$') .. (i==#parts and '' or ('/'..concat parts, '/', i+1, #parts)) + files = lswithpath prevpath + + results = {} + for file in *files + if matchglob file, currpath + if i==#parts + insert results, file + elseif isdir file + for result in *wildcard file .. '/' .. concat parts, '/', i+1, #parts + insert results, result + if (matchglob file, prefix..'**') and isdir file + for result in *wildcard file .. '/**' .. suffix + insert results, result + return results + + if match part, '%*' + files = lswithpath prevpath + + if i==#parts + return matchglob files, glob + + results = {} + for file in *files + if (matchglob file, currpath) and isdir file + for result in *wildcard file .. '/' .. concat parts, '/', i+1, #parts + insert results, result + return results + + if exists glob + return {glob} + else + return {} + +{ + :wildcard + :exists, :isdir + :mtime +} diff --git a/util.moon b/util.moon index d9ab3d7..d897884 100644 --- a/util.moon +++ b/util.moon @@ -1,4 +1,4 @@ -import attributes, dir from require 'lfs' +import wildcard, exists, isdir, mtime from require 'fsutil' import insert, concat, sort from table unpack or=table.unpack @@ -49,13 +49,6 @@ flatten= (tab) -> insert out, e out --- file functions -mtime= (f) -> - a=attributes f - a and a.modification -exists= (f) -> - (attributes f)!=nil - -- command functions escapecmdpart= (p) -> if (type p)=='table' @@ -91,35 +84,6 @@ findclib= (name, mode='all') -> insert args, '--libs' if mode=='all' or mode=='ld' [arg for arg in (popen 'pkg-config', args)\read('*a')\gmatch '%S+'] --- file matcher -wildcard= (pattern) -> - prefix, suffix=pattern\match '^(.*)%*%*(.*)$' - if prefix - fd=popen 'find', {(raw: '*'), '-name', "*#{suffix}"} - found={} - for line in fd\lines! - insert found, line if (line\sub 1, #prefix)==prefix - fd\close! - return found - - directory, prefix, suffix=pattern\match '^(.*)/(.*)%*(.*)$' - if directory - found={} - for file in dir directory - if (file\sub 1, #prefix)==prefix and (file\sub -#suffix)==suffix - insert found, "#{directory}/#{file}" - return found - - prefix, suffix=pattern\match '^(.*)%*(.*)$' - if prefix - found={} - for file in dir '.' - if (file\sub 1, #prefix)==prefix and (file\sub -#suffix)==suffix - insert found, file - return found - - error "Invalid wildcard pattern: #{pattern}" - -- string pattern patsubst= (str, pattern, replacement) -> return [patsubst s, pattern, replacement for s in *str] if (type str)=='table' @@ -171,7 +135,8 @@ sortedpairs= (table, cmp) -> -- file functions :wildcard - :mtime, :exists + :mtime + :exists, :isdir -- command functions :run, :popen