os.walkDir is available at compile time

This commit is contained in:
Araq 2015-11-10 15:29:53 +01:00
commit 2aff716134
4 changed files with 67 additions and 42 deletions

View file

@ -1604,7 +1604,8 @@ proc matches(s: PSym; x: string): bool =
var s = s var s = s
var L = y.len-1 var L = y.len-1
while L >= 0: while L >= 0:
if s == nil or y[L].cmpIgnoreStyle(s.name.s) != 0: return false if s == nil or (y[L].cmpIgnoreStyle(s.name.s) != 0 and y[L] != "*"):
return false
s = s.owner s = s.owner
dec L dec L
result = true result = true
@ -1613,7 +1614,8 @@ proc matches(s: PSym; y: varargs[string]): bool =
var s = s var s = s
var L = y.len-1 var L = y.len-1
while L >= 0: while L >= 0:
if s == nil or y[L].cmpIgnoreStyle(s.name.s) != 0: return false if s == nil or (y[L].cmpIgnoreStyle(s.name.s) != 0 and y[L] != "*"):
return false
s = if sfFromGeneric in s.flags: s.owner.owner else: s.owner s = if sfFromGeneric in s.flags: s.owner.owner else: s.owner
dec L dec L
result = true result = true

View file

@ -55,9 +55,16 @@ template getX(k, field) {.immediate, dirty.} =
result = s[i+a.rb+1].field result = s[i+a.rb+1].field
proc getInt*(a: VmArgs; i: Natural): BiggestInt = getX(rkInt, intVal) proc getInt*(a: VmArgs; i: Natural): BiggestInt = getX(rkInt, intVal)
proc getBool*(a: VmArgs; i: Natural): bool = getInt(a, i) != 0
proc getFloat*(a: VmArgs; i: Natural): BiggestFloat = getX(rkFloat, floatVal) proc getFloat*(a: VmArgs; i: Natural): BiggestFloat = getX(rkFloat, floatVal)
proc getString*(a: VmArgs; i: Natural): string = proc getString*(a: VmArgs; i: Natural): string =
doAssert i < a.rc-1 doAssert i < a.rc-1
let s = cast[seq[TFullReg]](a.slots) let s = cast[seq[TFullReg]](a.slots)
doAssert s[i+a.rb+1].kind == rkNode doAssert s[i+a.rb+1].kind == rkNode
result = s[i+a.rb+1].node.strVal result = s[i+a.rb+1].node.strVal
proc getNode*(a: VmArgs; i: Natural): PNode =
doAssert i < a.rc-1
let s = cast[seq[TFullReg]](a.slots)
doAssert s[i+a.rb+1].kind == rkNode
result = s[i+a.rb+1].node

View file

@ -13,7 +13,7 @@ from math import sqrt, ln, log10, log2, exp, round, arccos, arcsin,
arctan, arctan2, cos, cosh, hypot, sinh, sin, tan, tanh, pow, trunc, arctan, arctan2, cos, cosh, hypot, sinh, sin, tan, tanh, pow, trunc,
floor, ceil, fmod floor, ceil, fmod
from os import getEnv, existsEnv, dirExists, fileExists from os import getEnv, existsEnv, dirExists, fileExists, walkDir
template mathop(op) {.immediate, dirty.} = template mathop(op) {.immediate, dirty.} =
registerCallback(c, "stdlib.math." & astToStr(op), `op Wrapper`) registerCallback(c, "stdlib.math." & astToStr(op), `op Wrapper`)
@ -48,6 +48,12 @@ proc getCurrentExceptionMsgWrapper(a: VmArgs) {.nimcall.} =
setResult(a, if a.currentException.isNil: "" setResult(a, if a.currentException.isNil: ""
else: a.currentException.sons[3].skipColon.strVal) else: a.currentException.sons[3].skipColon.strVal)
proc staticWalkDirImpl(path: string, relative: bool): PNode =
result = newNode(nkBracket)
for k, f in walkDir(path, relative):
result.add newTree(nkPar, newIntNode(nkIntLit, k.ord),
newStrNode(nkStrLit, f))
proc registerAdditionalOps*(c: PCtx) = proc registerAdditionalOps*(c: PCtx) =
wrap1f(sqrt) wrap1f(sqrt)
wrap1f(ln) wrap1f(ln)
@ -78,3 +84,5 @@ proc registerAdditionalOps*(c: PCtx) =
wrap1s(fileExists) wrap1s(fileExists)
wrap2svoid(writeFile) wrap2svoid(writeFile)
systemop getCurrentExceptionMsg systemop getCurrentExceptionMsg
registerCallback c, "stdlib.*.staticWalkDir", proc (a: VmArgs) {.nimcall.} =
setResult(a, staticWalkDirImpl(getString(a, 0), getBool(a, 1)))

View file

@ -810,6 +810,10 @@ type
{.deprecated: [TPathComponent: PathComponent].} {.deprecated: [TPathComponent: PathComponent].}
proc staticWalkDir(dir: string; relative: bool): seq[
tuple[kind: PathComponent, path: string]] =
discard
iterator walkDir*(dir: string; relative=false): tuple[kind: PathComponent, path: string] {. iterator walkDir*(dir: string; relative=false): tuple[kind: PathComponent, path: string] {.
tags: [ReadDirEffect].} = tags: [ReadDirEffect].} =
## walks over the directory `dir` and yields for each directory or file in ## walks over the directory `dir` and yields for each directory or file in
@ -833,49 +837,53 @@ iterator walkDir*(dir: string; relative=false): tuple[kind: PathComponent, path:
## dirA/dirC ## dirA/dirC
## dirA/fileA1.txt ## dirA/fileA1.txt
## dirA/fileA2.txt ## dirA/fileA2.txt
when defined(windows): when nimvm:
var f: WIN32_FIND_DATA for k, v in items(staticWalkDir(dir, relative)):
var h = findFirstFile(dir / "*", f) yield (k, v)
if h != -1:
while true:
var k = pcFile
if not skipFindData(f):
if (f.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) != 0'i32:
k = pcDir
if (f.dwFileAttributes and FILE_ATTRIBUTE_REPARSE_POINT) != 0'i32:
k = succ(k)
let xx = if relative: extractFilename(getFilename(f))
else: dir / extractFilename(getFilename(f))
yield (k, xx)
if findNextFile(h, f) == 0'i32: break
findClose(h)
else: else:
var d = opendir(dir) when defined(windows):
if d != nil: var f: WIN32_FIND_DATA
while true: var h = findFirstFile(dir / "*", f)
var x = readdir(d) if h != -1:
if x == nil: break while true:
var y = $x.d_name
if y != "." and y != "..":
var s: Stat
if not relative:
y = dir / y
var k = pcFile var k = pcFile
if not skipFindData(f):
if (f.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) != 0'i32:
k = pcDir
if (f.dwFileAttributes and FILE_ATTRIBUTE_REPARSE_POINT) != 0'i32:
k = succ(k)
let xx = if relative: extractFilename(getFilename(f))
else: dir / extractFilename(getFilename(f))
yield (k, xx)
if findNextFile(h, f) == 0'i32: break
findClose(h)
else:
var d = opendir(dir)
if d != nil:
while true:
var x = readdir(d)
if x == nil: break
var y = $x.d_name
if y != "." and y != "..":
var s: Stat
if not relative:
y = dir / y
var k = pcFile
when defined(linux) or defined(macosx) or defined(bsd): when defined(linux) or defined(macosx) or defined(bsd):
if x.d_type != DT_UNKNOWN: if x.d_type != DT_UNKNOWN:
if x.d_type == DT_DIR: k = pcDir if x.d_type == DT_DIR: k = pcDir
if x.d_type == DT_LNK: if x.d_type == DT_LNK:
if dirExists(y): k = pcLinkToDir if dirExists(y): k = pcLinkToDir
else: k = succ(k) else: k = succ(k)
yield (k, y) yield (k, y)
continue continue
if lstat(y, s) < 0'i32: break if lstat(y, s) < 0'i32: break
if S_ISDIR(s.st_mode): k = pcDir if S_ISDIR(s.st_mode): k = pcDir
if S_ISLNK(s.st_mode): k = succ(k) if S_ISLNK(s.st_mode): k = succ(k)
yield (k, y) yield (k, y)
discard closedir(d) discard closedir(d)
iterator walkDirRec*(dir: string, filter={pcFile, pcDir}): string {. iterator walkDirRec*(dir: string, filter={pcFile, pcDir}): string {.
tags: [ReadDirEffect].} = tags: [ReadDirEffect].} =