rewrite wildcard, fix #1

alfons-task
Nathan DECHER 4 years ago
parent f91877089b
commit ab77025516
  1. 88
      fsutil.moon
  2. 41
      util.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
}

@ -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

Loading…
Cancel
Save