diff options
-rw-r--r-- | compiler/vmgen.nim | 6 | ||||
-rw-r--r-- | compiler/vmhooks.nim | 7 | ||||
-rw-r--r-- | compiler/vmops.nim | 10 | ||||
-rw-r--r-- | lib/pure/os.nim | 90 |
4 files changed, 69 insertions, 44 deletions
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 97c6a5580..2a16406e7 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -1604,7 +1604,8 @@ proc matches(s: PSym; x: string): bool = var s = s var L = y.len-1 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 dec L result = true @@ -1613,7 +1614,8 @@ proc matches(s: PSym; y: varargs[string]): bool = var s = s var L = y.len-1 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 dec L result = true diff --git a/compiler/vmhooks.nim b/compiler/vmhooks.nim index 576b0565f..3456e893b 100644 --- a/compiler/vmhooks.nim +++ b/compiler/vmhooks.nim @@ -55,9 +55,16 @@ template getX(k, field) {.immediate, dirty.} = result = s[i+a.rb+1].field 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 getString*(a: VmArgs; i: Natural): string = 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.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 diff --git a/compiler/vmops.nim b/compiler/vmops.nim index e1a0dfef8..e40e05eff 100644 --- a/compiler/vmops.nim +++ b/compiler/vmops.nim @@ -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, floor, ceil, fmod -from os import getEnv, existsEnv, dirExists, fileExists +from os import getEnv, existsEnv, dirExists, fileExists, walkDir template mathop(op) {.immediate, dirty.} = registerCallback(c, "stdlib.math." & astToStr(op), `op Wrapper`) @@ -48,6 +48,12 @@ proc getCurrentExceptionMsgWrapper(a: VmArgs) {.nimcall.} = setResult(a, if a.currentException.isNil: "" 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) = wrap1f(sqrt) wrap1f(ln) @@ -78,3 +84,5 @@ proc registerAdditionalOps*(c: PCtx) = wrap1s(fileExists) wrap2svoid(writeFile) systemop getCurrentExceptionMsg + registerCallback c, "stdlib.*.staticWalkDir", proc (a: VmArgs) {.nimcall.} = + setResult(a, staticWalkDirImpl(getString(a, 0), getBool(a, 1))) diff --git a/lib/pure/os.nim b/lib/pure/os.nim index c01228563..7c14c46cf 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -810,6 +810,10 @@ type {.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] {. tags: [ReadDirEffect].} = ## 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/fileA1.txt ## dirA/fileA2.txt - when defined(windows): - var f: WIN32_FIND_DATA - var h = findFirstFile(dir / "*", f) - 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) + when nimvm: + for k, v in items(staticWalkDir(dir, relative)): + yield (k, v) 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 + when defined(windows): + var f: WIN32_FIND_DATA + var h = findFirstFile(dir / "*", f) + if h != -1: + while true: var k = pcFile - - when defined(linux) or defined(macosx) or defined(bsd): - if x.d_type != DT_UNKNOWN: - if x.d_type == DT_DIR: k = pcDir - if x.d_type == DT_LNK: - if dirExists(y): k = pcLinkToDir - else: k = succ(k) - yield (k, y) - continue - - if lstat(y, s) < 0'i32: break - if S_ISDIR(s.st_mode): k = pcDir - if S_ISLNK(s.st_mode): k = succ(k) - yield (k, y) - discard closedir(d) + 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): + if x.d_type != DT_UNKNOWN: + if x.d_type == DT_DIR: k = pcDir + if x.d_type == DT_LNK: + if dirExists(y): k = pcLinkToDir + else: k = succ(k) + yield (k, y) + continue + + if lstat(y, s) < 0'i32: break + if S_ISDIR(s.st_mode): k = pcDir + if S_ISLNK(s.st_mode): k = succ(k) + yield (k, y) + discard closedir(d) iterator walkDirRec*(dir: string, filter={pcFile, pcDir}): string {. tags: [ReadDirEffect].} = |