Add walkPattern to return both files and directories

Also added `walkDirs` to walk only directories based on the pattern
specified.
This commit is contained in:
Joey Payne 2016-06-17 08:35:59 -06:00
commit 02895ba934

View file

@ -778,12 +778,26 @@ iterator envPairs*(): tuple[key, value: TaintedString] {.tags: [ReadEnvEffect].}
yield (TaintedString(substr(environment[i], 0, p-1)), yield (TaintedString(substr(environment[i], 0, p-1)),
TaintedString(substr(environment[i], p+1))) TaintedString(substr(environment[i], p+1)))
iterator walkFiles*(pattern: string): string {.tags: [ReadDirEffect].} = # Templates for filtering directories and files
## Iterate over all the files that match the `pattern`. On POSIX this uses when defined(windows):
## the `glob`:idx: call. template isDir(f: WIN32_FIND_DATA): bool =
## (f.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) != 0'i32
## `pattern` is OS dependent, but at least the "\*.ext" template isFile(f: WIN32_FIND_DATA): bool =
## notation is supported. not isDir(f)
else:
template isDir(f: string): bool =
dirExists(f)
template isFile(f: string): bool =
fileExists(f)
template defaultWalkFilter(item): bool =
## Walk filter used to return true on both
## files and directories
true
template walkCommon(pattern: string, filter) =
## Common code for getting the files and directories with the
## specified `pattern`
when defined(windows): when defined(windows):
var var
f: WIN32_FIND_DATA f: WIN32_FIND_DATA
@ -792,8 +806,7 @@ iterator walkFiles*(pattern: string): string {.tags: [ReadDirEffect].} =
if res != -1: if res != -1:
defer: findClose(res) defer: findClose(res)
while true: while true:
if not skipFindData(f) and if not skipFindData(f) and filter(f):
(f.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) == 0'i32:
# Windows bug/gotcha: 't*.nim' matches 'tfoo.nims' -.- so we check # Windows bug/gotcha: 't*.nim' matches 'tfoo.nims' -.- so we check
# that the file extensions have the same length ... # that the file extensions have the same length ...
let ff = getFilename(f) let ff = getFilename(f)
@ -816,10 +829,33 @@ iterator walkFiles*(pattern: string): string {.tags: [ReadDirEffect].} =
for i in 0.. f.gl_pathc - 1: for i in 0.. f.gl_pathc - 1:
assert(f.gl_pathv[i] != nil) assert(f.gl_pathv[i] != nil)
let path = $f.gl_pathv[i] let path = $f.gl_pathv[i]
# Make sure it's a file and not a directory if filter(path):
if fileExists(path):
yield path yield path
iterator walkPattern*(pattern: string): string {.tags: [ReadDirEffect].} =
## Iterate over all the files and directories that match the `pattern`.
## On POSIX this uses the `glob`:idx: call.
##
## `pattern` is OS dependent, but at least the "\*.ext"
## notation is supported.
walkCommon(pattern, defaultWalkFilter)
iterator walkFiles*(pattern: string): string {.tags: [ReadDirEffect].} =
## Iterate over all the files that match the `pattern`. On POSIX this uses
## the `glob`:idx: call.
##
## `pattern` is OS dependent, but at least the "\*.ext"
## notation is supported.
walkCommon(pattern, isFile)
iterator walkDirs*(pattern: string): string {.tags: [ReadDirEffect].} =
## Iterate over all the directories that match the `pattern`.
## On POSIX this uses the `glob`:idx: call.
##
## `pattern` is OS dependent, but at least the "\*.ext"
## notation is supported.
walkCommon(pattern, isDir)
type type
PathComponent* = enum ## Enumeration specifying a path component. PathComponent* = enum ## Enumeration specifying a path component.
pcFile, ## path refers to a file pcFile, ## path refers to a file