Skip to content

Commit

Permalink
Add checkError parameter to os.walkPattern, os.walkFiles and os.os.wa…
Browse files Browse the repository at this point in the history
…lkDirs
  • Loading branch information
demotomohiro committed Jan 10, 2020
1 parent ce562c6 commit f8772ab
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 10 deletions.
5 changes: 3 additions & 2 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@
and `typetraits.get` to get the ith element of a type tuple.
- Added `typetraits.genericParams` to return a tuple of generic params from a generic instantiation

- Added `checkError` parameter to `os.walkDir` and `os.walkDirRec`.
If it is true, raises `OSError` when `dir` cannot be open.
- Added `checkError` parameter to `os.walkPattern`, `os.walkFiles`,
`os.walkDirs`, `os.walkDir` and `os.walkDirRec`. If it is true, raises
`OSError` in case of an error.

## Library changes

Expand Down
32 changes: 24 additions & 8 deletions lib/pure/os.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1800,7 +1800,7 @@ template defaultWalkFilter(item): bool =
## files and directories
true

template walkCommon(pattern: string, filter) =
template walkCommon(pattern: string, filter: typed, checkError: bool) =
## Common code for getting the files and directories with the
## specified `pattern`
when defined(windows):
Expand All @@ -1824,63 +1824,79 @@ template walkCommon(pattern: string, filter) =
let errCode = getLastError()
if errCode == ERROR_NO_MORE_FILES: break
else: raiseOSError(errCode.OSErrorCode)
elif checkError:
raiseOSError(osLastError(), pattern)
else: # here we use glob
var
f: Glob
res: int
f.gl_offs = 0
f.gl_pathc = 0
f.gl_pathv = nil
res = glob(pattern, 0, nil, addr(f))
res = glob(pattern, if checkError: GLOB_ERR else: 0, nil, addr(f))
defer: globfree(addr(f))
if res == 0:
for i in 0.. f.gl_pathc - 1:
assert(f.gl_pathv[i] != nil)
let path = $f.gl_pathv[i]
if filter(path):
yield path
elif checkError:
raiseOSError(osLastError(), pattern)

iterator walkPattern*(pattern: string): string {.tags: [ReadDirEffect], noNimScript.} =
iterator walkPattern*(pattern: string; checkError = false): string {.
tags: [ReadDirEffect], noNimScript.} =
## 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.
##
## In case of an error, raises `OSError` if `checkError` is true,
## otherwise the error is ignored and yields nothing.
##
## See also:
## * `walkFiles iterator <#walkFiles.i,string>`_
## * `walkDirs iterator <#walkDirs.i,string>`_
## * `walkDir iterator <#walkDir.i,string>`_
## * `walkDirRec iterator <#walkDirRec.i,string>`_
walkCommon(pattern, defaultWalkFilter)
walkCommon(pattern, defaultWalkFilter, checkError)

iterator walkFiles*(pattern: string): string {.tags: [ReadDirEffect], noNimScript.} =
iterator walkFiles*(pattern: string; checkError = false): string {.
tags: [ReadDirEffect], noNimScript.} =
## 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.
##
## In case of an error, raises `OSError` if `checkError` is true,
## otherwise the error is ignored and yields nothing.
##
## See also:
## * `walkPattern iterator <#walkPattern.i,string>`_
## * `walkDirs iterator <#walkDirs.i,string>`_
## * `walkDir iterator <#walkDir.i,string>`_
## * `walkDirRec iterator <#walkDirRec.i,string>`_
walkCommon(pattern, isFile)
walkCommon(pattern, isFile, checkError)

iterator walkDirs*(pattern: string): string {.tags: [ReadDirEffect], noNimScript.} =
iterator walkDirs*(pattern: string; checkError = false): string {.
tags: [ReadDirEffect], noNimScript.} =
## 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.
##
## In case of an error, raises `OSError` if `checkError` is true,
## otherwise the error is ignored and yields nothing.
##
## See also:
## * `walkPattern iterator <#walkPattern.i,string>`_
## * `walkFiles iterator <#walkFiles.i,string>`_
## * `walkDir iterator <#walkDir.i,string>`_
## * `walkDirRec iterator <#walkDirRec.i,string>`_
walkCommon(pattern, isDir)
walkCommon(pattern, isDir, checkError)

proc expandFilename*(filename: string): string {.rtl, extern: "nos$1",
tags: [ReadDirEffect], noNimScript.} =
Expand Down

0 comments on commit f8772ab

Please sign in to comment.