mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-14 21:20:42 +00:00
Merge remote-tracking branch 'origin/devel' into pr_quote_do_r
This commit is contained in:
@@ -500,6 +500,21 @@ proc semAfterMacroCall(c: PContext, call, macroResult: PNode,
|
||||
dec(c.config.evalTemplateCounter)
|
||||
discard c.friendModules.pop()
|
||||
|
||||
proc getLineInfo(n: PNode): TLineInfo =
|
||||
case n.kind
|
||||
of nkPostfix:
|
||||
if len(n) > 1:
|
||||
result = getLineInfo(n[1])
|
||||
else:
|
||||
result = n.info
|
||||
of nkAccQuoted, nkPragmaExpr:
|
||||
if len(n) > 0:
|
||||
result = getLineInfo(n[0])
|
||||
else:
|
||||
result = n.info
|
||||
else:
|
||||
result = n.info
|
||||
|
||||
const
|
||||
errMissingGenericParamsForTemplate = "'$1' has unspecified generic parameters"
|
||||
|
||||
|
||||
@@ -492,19 +492,8 @@ proc semIdentDef(c: PContext, n: PNode, kind: TSymKind, reportToNimsuggest = tru
|
||||
incl(result.flags, sfGlobal)
|
||||
result.options = c.config.options
|
||||
|
||||
proc getLineInfo(n: PNode): TLineInfo =
|
||||
case n.kind
|
||||
of nkPostfix:
|
||||
if len(n) > 1:
|
||||
return getLineInfo(n[1])
|
||||
of nkAccQuoted, nkPragmaExpr:
|
||||
if len(n) > 0:
|
||||
return getLineInfo(n[0])
|
||||
else:
|
||||
discard
|
||||
result = n.info
|
||||
let info = getLineInfo(n)
|
||||
if reportToNimsuggest:
|
||||
let info = getLineInfo(n)
|
||||
suggestSym(c.graph, info, result, c.graph.usageSym)
|
||||
|
||||
proc checkNilable(c: PContext; v: PSym) =
|
||||
@@ -1787,6 +1776,17 @@ proc typeSectionFinalPass(c: PContext, n: PNode) =
|
||||
# check the style here after the pragmas have been processed:
|
||||
styleCheckDef(c, s)
|
||||
# compute the type's size and check for illegal recursions:
|
||||
if a[0].kind == nkPragmaExpr:
|
||||
let pragmas = a[0][1]
|
||||
for i in 0 ..< pragmas.len:
|
||||
if pragmas[i].kind == nkExprColonExpr and
|
||||
pragmas[i][0].kind == nkIdent and
|
||||
whichKeyword(pragmas[i][0].ident) == wSize:
|
||||
if s.typ.kind != tyEnum and sfImportc notin s.flags:
|
||||
# EventType* {.size: sizeof(uint32).} = enum
|
||||
# AtomicFlag* {.importc: "atomic_flag", header: "<stdatomic.h>", size: 1.} = object
|
||||
localError(c.config, pragmas[i].info, "size pragma only allowed for enum types and imported types")
|
||||
|
||||
if a[1].kind == nkEmpty:
|
||||
var x = a[2]
|
||||
if x.kind in nkCallKinds and nfSem in x.flags:
|
||||
@@ -2351,7 +2351,7 @@ proc semCppMember(c: PContext; s: PSym; n: PNode) =
|
||||
isInitializer = false
|
||||
break
|
||||
var j = 0
|
||||
while p[j].sym.kind == skParam:
|
||||
while p[j].kind == nkSym and p[j].sym.kind == skParam:
|
||||
initializerCall.add val
|
||||
inc j
|
||||
if isInitializer:
|
||||
|
||||
@@ -67,7 +67,12 @@ proc symChoice(c: PContext, n: PNode, s: PSym, r: TSymChoiceRule;
|
||||
# for instance 'nextTry' is both in tables.nim and astalgo.nim ...
|
||||
if not isField or sfGenSym notin s.flags:
|
||||
result = newSymNode(s, info)
|
||||
markUsed(c, info, s)
|
||||
if isField:
|
||||
# possibly not final field sym
|
||||
incl(s.flags, sfUsed)
|
||||
markOwnerModuleAsUsed(c, s)
|
||||
else:
|
||||
markUsed(c, info, s)
|
||||
onUse(info, s)
|
||||
else:
|
||||
result = n
|
||||
@@ -691,6 +696,9 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
|
||||
s = semIdentVis(c, skTemplate, n[namePos], {})
|
||||
assert s.kind == skTemplate
|
||||
|
||||
let info = getLineInfo(n[namePos])
|
||||
suggestSym(c.graph, info, s, c.graph.usageSym)
|
||||
|
||||
styleCheckDef(c, s)
|
||||
onDef(n[namePos].info, s)
|
||||
# check parameter list:
|
||||
|
||||
@@ -1671,6 +1671,11 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
|
||||
var err = "cannot instantiate "
|
||||
err.addTypeHeader(c.config, t)
|
||||
err.add "\ngot: <$1>\nbut expected: <$2>" % [describeArgs(c, n), describeArgs(c, t.n, 0)]
|
||||
if m.firstMismatch.kind == kTypeMismatch and m.firstMismatch.arg < n.len:
|
||||
let nArg = n[m.firstMismatch.arg]
|
||||
if nArg.kind in nkSymChoices:
|
||||
err.add "\n"
|
||||
err.add ambiguousIdentifierMsg(nArg)
|
||||
localError(c.config, n.info, errGenerated, err)
|
||||
return newOrPrevType(tyError, prev, c)
|
||||
|
||||
|
||||
@@ -263,7 +263,7 @@ proc registerAdditionalOps*(c: PCtx) =
|
||||
wrap2si(readLines, ioop)
|
||||
systemop getCurrentExceptionMsg
|
||||
systemop getCurrentException
|
||||
registerCallback c, "stdlib.osdirs.staticWalkDir", proc (a: VmArgs) {.nimcall.} =
|
||||
registerCallback c, "stdlib.staticos.staticWalkDir", proc (a: VmArgs) {.nimcall.} =
|
||||
setResult(a, staticWalkDirImpl(getString(a, 0), getBool(a, 1)))
|
||||
registerCallback c, "stdlib.staticos.staticDirExists", proc (a: VmArgs) {.nimcall.} =
|
||||
setResult(a, dirExists(getString(a, 0)))
|
||||
|
||||
@@ -30,28 +30,30 @@ a working NodeJS on `PATH`.
|
||||
Commands
|
||||
========
|
||||
|
||||
========================== ==========================
|
||||
p|pat|pattern <glob> run all the tests matching the given pattern
|
||||
all run all tests inside of category folders
|
||||
c|cat|category <category> run all the tests of a certain category
|
||||
r|run <test> run single test file
|
||||
html generate testresults.html from the database
|
||||
========================== ==========================
|
||||
|
||||
|
||||
Options
|
||||
=======
|
||||
|
||||
--print print results to the console
|
||||
--verbose print commands (compiling and running tests)
|
||||
--simulate see what tests would be run but don't run them (for debugging)
|
||||
--failing only show failing/ignored tests
|
||||
--targets:"c cpp js objc" run tests for specified targets (default: c)
|
||||
--nim:path use a particular nim executable (default: $PATH/nim)
|
||||
--directory:dir Change to directory dir before reading the tests or doing anything else.
|
||||
--colors:on|off Turn messages coloring on|off.
|
||||
--backendLogging:on|off Disable or enable backend logging. By default turned on.
|
||||
--megatest:on|off Enable or disable megatest. Default is on.
|
||||
--valgrind:on|off Enable or disable valgrind support. Default is on.
|
||||
--skipFrom:file Read tests to skip from `file` - one test per line, # comments ignored
|
||||
--print print results to the console
|
||||
--verbose print commands (compiling and running tests)
|
||||
--simulate see what tests would be run but don't run them (for debugging)
|
||||
--failing only show failing/ignored tests
|
||||
--targets:"c cpp js objc" run tests for specified targets (default: c)
|
||||
--nim:path use a particular nim executable (default: $PATH/nim)
|
||||
--directory:dir Change to directory dir before reading the tests or doing anything else.
|
||||
--colors:on|off Turn messages coloring on|off.
|
||||
--backendLogging:on|off Disable or enable backend logging. By default turned on.
|
||||
--megatest:on|off Enable or disable megatest. Default is on.
|
||||
--valgrind:on|off Enable or disable valgrind support. Default is on.
|
||||
--skipFrom:file Read tests to skip from `file` - one test per line, # comments ignored
|
||||
|
||||
|
||||
Running a single test
|
||||
|
||||
@@ -1490,7 +1490,9 @@ proc clearInterval*(i: Interval) {.importc, nodecl.}
|
||||
proc addEventListener*(et: EventTarget, ev: cstring, cb: proc(ev: Event), useCapture: bool = false)
|
||||
proc addEventListener*(et: EventTarget, ev: cstring, cb: proc(ev: Event), options: AddEventListenerOptions)
|
||||
proc dispatchEvent*(et: EventTarget, ev: Event)
|
||||
proc removeEventListener*(et: EventTarget; ev: cstring; cb: proc(ev: Event))
|
||||
proc removeEventListener*(et: EventTarget, ev: cstring, cb: proc(ev: Event), useCapture: bool = false)
|
||||
proc removeEventListener*(et: EventTarget, ev: cstring, cb: proc(ev: Event), options: AddEventListenerOptions)
|
||||
|
||||
|
||||
# Window "methods"
|
||||
proc alert*(w: Window, msg: cstring)
|
||||
|
||||
1157
lib/pure/os.nim
1157
lib/pure/os.nim
File diff suppressed because it is too large
Load Diff
@@ -527,7 +527,6 @@ proc parseSaturatedNatural*(s: openArray[char], b: var int): int {.
|
||||
proc rawParseUInt(s: openArray[char], b: var BiggestUInt): int =
|
||||
var
|
||||
res = 0.BiggestUInt
|
||||
prev = 0.BiggestUInt
|
||||
i = 0
|
||||
if i < s.len - 1 and s[i] == '-' and s[i + 1] in {'0'..'9'}:
|
||||
integerOutOfRangeError()
|
||||
@@ -535,8 +534,11 @@ proc rawParseUInt(s: openArray[char], b: var BiggestUInt): int =
|
||||
if i < s.len and s[i] in {'0'..'9'}:
|
||||
b = 0
|
||||
while i < s.len and s[i] in {'0'..'9'}:
|
||||
prev = res
|
||||
res = res * 10 + (ord(s[i]) - ord('0')).BiggestUInt
|
||||
if res > BiggestUInt.high div 10: # Highest value that you can multiply 10 without overflow
|
||||
integerOutOfRangeError()
|
||||
res = res * 10
|
||||
let prev = res
|
||||
res += (ord(s[i]) - ord('0')).BiggestUInt
|
||||
if prev > res:
|
||||
integerOutOfRangeError()
|
||||
inc(i)
|
||||
|
||||
@@ -19,7 +19,7 @@ include system/inclrtl
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/widestrs
|
||||
|
||||
|
||||
when defined(nodejs):
|
||||
from std/private/oscommon import ReadDirEffect
|
||||
|
||||
@@ -33,8 +33,6 @@ elif defined(windows):
|
||||
import std/winlean
|
||||
elif defined(posix):
|
||||
import std/posix
|
||||
else:
|
||||
{.error: "The cmdline module has not been implemented for the target platform.".}
|
||||
|
||||
|
||||
# Needed by windows in order to obtain the command line for targets
|
||||
|
||||
@@ -5,9 +5,13 @@ import std/[oserrors]
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/[syncio, assertions, widestrs]
|
||||
|
||||
from std/staticos import PathComponent
|
||||
|
||||
## .. importdoc:: osdirs.nim, os.nim
|
||||
|
||||
const weirdTarget* = defined(nimscript) or defined(js)
|
||||
const
|
||||
weirdTarget* = defined(nimscript) or defined(js)
|
||||
supportedSystem* = weirdTarget or defined(windows) or defined(posix)
|
||||
|
||||
|
||||
type
|
||||
@@ -27,8 +31,6 @@ elif defined(posix):
|
||||
import std/posix
|
||||
proc c_rename(oldname, newname: cstring): cint {.
|
||||
importc: "rename", header: "<stdio.h>".}
|
||||
else:
|
||||
{.error: "OS module not ported to your operating system!".}
|
||||
|
||||
|
||||
when weirdTarget:
|
||||
@@ -65,122 +67,110 @@ when defined(windows) and not weirdTarget:
|
||||
result = f.cFileName[0].int == dot and (f.cFileName[1].int == 0 or
|
||||
f.cFileName[1].int == dot and f.cFileName[2].int == 0)
|
||||
|
||||
when supportedSystem:
|
||||
when defined(posix) and not weirdTarget:
|
||||
proc getSymlinkFileKind*(path: string):
|
||||
tuple[pc: PathComponent, isSpecial: bool] =
|
||||
# Helper function.
|
||||
var s: Stat
|
||||
assert(path != "")
|
||||
result = (pcLinkToFile, false)
|
||||
if stat(path, s) == 0'i32:
|
||||
if S_ISDIR(s.st_mode):
|
||||
result = (pcLinkToDir, false)
|
||||
elif not S_ISREG(s.st_mode):
|
||||
result = (pcLinkToFile, true)
|
||||
|
||||
type
|
||||
PathComponent* = enum ## Enumeration specifying a path component.
|
||||
proc tryMoveFSObject*(source, dest: string, isDir: bool): bool {.noWeirdTarget.} =
|
||||
## Moves a file (or directory if `isDir` is true) from `source` to `dest`.
|
||||
##
|
||||
## Returns false in case of `EXDEV` error or `AccessDeniedError` on Windows (if `isDir` is true).
|
||||
## In case of other errors `OSError` is raised.
|
||||
## Returns true in case of success.
|
||||
when defined(windows):
|
||||
let s = newWideCString(source)
|
||||
let d = newWideCString(dest)
|
||||
result = moveFileExW(s, d, MOVEFILE_COPY_ALLOWED or MOVEFILE_REPLACE_EXISTING) != 0'i32
|
||||
else:
|
||||
result = c_rename(source, dest) == 0'i32
|
||||
|
||||
if not result:
|
||||
let err = osLastError()
|
||||
let isAccessDeniedError =
|
||||
when defined(windows):
|
||||
const AccessDeniedError = OSErrorCode(5)
|
||||
isDir and err == AccessDeniedError
|
||||
else:
|
||||
err == EXDEV.OSErrorCode
|
||||
if not isAccessDeniedError:
|
||||
raiseOSError(err, $(source, dest))
|
||||
|
||||
when not defined(windows):
|
||||
const maxSymlinkLen* = 1024
|
||||
|
||||
proc fileExists*(filename: string): bool {.rtl, extern: "nos$1",
|
||||
tags: [ReadDirEffect], noNimJs, sideEffect.} =
|
||||
## Returns true if `filename` exists and is a regular file or symlink.
|
||||
##
|
||||
## Directories, device files, named pipes and sockets return false.
|
||||
##
|
||||
## See also:
|
||||
## * `walkDirRec iterator`_
|
||||
## * `FileInfo object`_
|
||||
pcFile, ## path refers to a file
|
||||
pcLinkToFile, ## path refers to a symbolic link to a file
|
||||
pcDir, ## path refers to a directory
|
||||
pcLinkToDir ## path refers to a symbolic link to a directory
|
||||
## * `dirExists proc`_
|
||||
## * `symlinkExists proc`_
|
||||
when defined(windows):
|
||||
wrapUnary(a, getFileAttributesW, filename)
|
||||
if a != -1'i32:
|
||||
result = (a and FILE_ATTRIBUTE_DIRECTORY) == 0'i32
|
||||
else:
|
||||
var res: Stat
|
||||
return stat(filename, res) >= 0'i32 and S_ISREG(res.st_mode)
|
||||
|
||||
|
||||
when defined(posix) and not weirdTarget:
|
||||
proc getSymlinkFileKind*(path: string):
|
||||
tuple[pc: PathComponent, isSpecial: bool] =
|
||||
# Helper function.
|
||||
var s: Stat
|
||||
assert(path != "")
|
||||
result = (pcLinkToFile, false)
|
||||
if stat(path, s) == 0'i32:
|
||||
if S_ISDIR(s.st_mode):
|
||||
result = (pcLinkToDir, false)
|
||||
elif not S_ISREG(s.st_mode):
|
||||
result = (pcLinkToFile, true)
|
||||
|
||||
proc tryMoveFSObject*(source, dest: string, isDir: bool): bool {.noWeirdTarget.} =
|
||||
## Moves a file (or directory if `isDir` is true) from `source` to `dest`.
|
||||
##
|
||||
## Returns false in case of `EXDEV` error or `AccessDeniedError` on Windows (if `isDir` is true).
|
||||
## In case of other errors `OSError` is raised.
|
||||
## Returns true in case of success.
|
||||
when defined(windows):
|
||||
let s = newWideCString(source)
|
||||
let d = newWideCString(dest)
|
||||
result = moveFileExW(s, d, MOVEFILE_COPY_ALLOWED or MOVEFILE_REPLACE_EXISTING) != 0'i32
|
||||
else:
|
||||
result = c_rename(source, dest) == 0'i32
|
||||
|
||||
if not result:
|
||||
let err = osLastError()
|
||||
let isAccessDeniedError =
|
||||
when defined(windows):
|
||||
const AccessDeniedError = OSErrorCode(5)
|
||||
isDir and err == AccessDeniedError
|
||||
else:
|
||||
err == EXDEV.OSErrorCode
|
||||
if not isAccessDeniedError:
|
||||
raiseOSError(err, $(source, dest))
|
||||
|
||||
when not defined(windows):
|
||||
const maxSymlinkLen* = 1024
|
||||
|
||||
proc fileExists*(filename: string): bool {.rtl, extern: "nos$1",
|
||||
tags: [ReadDirEffect], noNimJs, sideEffect.} =
|
||||
## Returns true if `filename` exists and is a regular file or symlink.
|
||||
##
|
||||
## Directories, device files, named pipes and sockets return false.
|
||||
##
|
||||
## See also:
|
||||
## * `dirExists proc`_
|
||||
## * `symlinkExists proc`_
|
||||
when defined(windows):
|
||||
wrapUnary(a, getFileAttributesW, filename)
|
||||
if a != -1'i32:
|
||||
result = (a and FILE_ATTRIBUTE_DIRECTORY) == 0'i32
|
||||
else:
|
||||
var res: Stat
|
||||
return stat(filename, res) >= 0'i32 and S_ISREG(res.st_mode)
|
||||
proc dirExists*(dir: string): bool {.rtl, extern: "nos$1", tags: [ReadDirEffect],
|
||||
noNimJs, sideEffect.} =
|
||||
## Returns true if the directory `dir` exists. If `dir` is a file, false
|
||||
## is returned. Follows symlinks.
|
||||
##
|
||||
## See also:
|
||||
## * `fileExists proc`_
|
||||
## * `symlinkExists proc`_
|
||||
when defined(windows):
|
||||
wrapUnary(a, getFileAttributesW, dir)
|
||||
if a != -1'i32:
|
||||
result = (a and FILE_ATTRIBUTE_DIRECTORY) != 0'i32
|
||||
else:
|
||||
var res: Stat
|
||||
result = stat(dir, res) >= 0'i32 and S_ISDIR(res.st_mode)
|
||||
|
||||
|
||||
proc dirExists*(dir: string): bool {.rtl, extern: "nos$1", tags: [ReadDirEffect],
|
||||
noNimJs, sideEffect.} =
|
||||
## Returns true if the directory `dir` exists. If `dir` is a file, false
|
||||
## is returned. Follows symlinks.
|
||||
##
|
||||
## See also:
|
||||
## * `fileExists proc`_
|
||||
## * `symlinkExists proc`_
|
||||
when defined(windows):
|
||||
wrapUnary(a, getFileAttributesW, dir)
|
||||
if a != -1'i32:
|
||||
result = (a and FILE_ATTRIBUTE_DIRECTORY) != 0'i32
|
||||
else:
|
||||
var res: Stat
|
||||
result = stat(dir, res) >= 0'i32 and S_ISDIR(res.st_mode)
|
||||
proc symlinkExists*(link: string): bool {.rtl, extern: "nos$1",
|
||||
tags: [ReadDirEffect],
|
||||
noWeirdTarget, sideEffect.} =
|
||||
## Returns true if the symlink `link` exists. Will return true
|
||||
## regardless of whether the link points to a directory or file.
|
||||
##
|
||||
## See also:
|
||||
## * `fileExists proc`_
|
||||
## * `dirExists proc`_
|
||||
when defined(windows):
|
||||
wrapUnary(a, getFileAttributesW, link)
|
||||
if a != -1'i32:
|
||||
# xxx see: bug #16784 (bug9); checking `IO_REPARSE_TAG_SYMLINK`
|
||||
# may also be needed.
|
||||
result = (a and FILE_ATTRIBUTE_REPARSE_POINT) != 0'i32
|
||||
else:
|
||||
var res: Stat
|
||||
result = lstat(link, res) >= 0'i32 and S_ISLNK(res.st_mode)
|
||||
|
||||
when defined(windows) and not weirdTarget:
|
||||
proc openHandle*(path: string, followSymlink=true, writeAccess=false): Handle =
|
||||
var flags = FILE_FLAG_BACKUP_SEMANTICS or FILE_ATTRIBUTE_NORMAL
|
||||
if not followSymlink:
|
||||
flags = flags or FILE_FLAG_OPEN_REPARSE_POINT
|
||||
let access = if writeAccess: GENERIC_WRITE else: 0'i32
|
||||
|
||||
proc symlinkExists*(link: string): bool {.rtl, extern: "nos$1",
|
||||
tags: [ReadDirEffect],
|
||||
noWeirdTarget, sideEffect.} =
|
||||
## Returns true if the symlink `link` exists. Will return true
|
||||
## regardless of whether the link points to a directory or file.
|
||||
##
|
||||
## See also:
|
||||
## * `fileExists proc`_
|
||||
## * `dirExists proc`_
|
||||
when defined(windows):
|
||||
wrapUnary(a, getFileAttributesW, link)
|
||||
if a != -1'i32:
|
||||
# xxx see: bug #16784 (bug9); checking `IO_REPARSE_TAG_SYMLINK`
|
||||
# may also be needed.
|
||||
result = (a and FILE_ATTRIBUTE_REPARSE_POINT) != 0'i32
|
||||
else:
|
||||
var res: Stat
|
||||
result = lstat(link, res) >= 0'i32 and S_ISLNK(res.st_mode)
|
||||
|
||||
when defined(windows) and not weirdTarget:
|
||||
proc openHandle*(path: string, followSymlink=true, writeAccess=false): Handle =
|
||||
var flags = FILE_FLAG_BACKUP_SEMANTICS or FILE_ATTRIBUTE_NORMAL
|
||||
if not followSymlink:
|
||||
flags = flags or FILE_FLAG_OPEN_REPARSE_POINT
|
||||
let access = if writeAccess: GENERIC_WRITE else: 0'i32
|
||||
|
||||
result = createFileW(
|
||||
newWideCString(path), access,
|
||||
FILE_SHARE_DELETE or FILE_SHARE_READ or FILE_SHARE_WRITE,
|
||||
nil, OPEN_EXISTING, flags, 0
|
||||
)
|
||||
result = createFileW(
|
||||
newWideCString(path), access,
|
||||
FILE_SHARE_DELETE or FILE_SHARE_READ or FILE_SHARE_WRITE,
|
||||
nil, OPEN_EXISTING, flags, 0
|
||||
)
|
||||
|
||||
@@ -6,7 +6,9 @@ import std/oserrors
|
||||
|
||||
import ospaths2, osfiles
|
||||
import oscommon
|
||||
export dirExists, PathComponent
|
||||
import std/staticos
|
||||
when supportedSystem:
|
||||
export dirExists, PathComponent
|
||||
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
@@ -20,9 +22,6 @@ elif defined(windows):
|
||||
elif defined(posix):
|
||||
import std/[posix, times]
|
||||
|
||||
else:
|
||||
{.error: "OS module not ported to your operating system!".}
|
||||
|
||||
|
||||
when weirdTarget:
|
||||
{.pragma: noWeirdTarget, error: "this proc is not available on the NimScript/js target".}
|
||||
@@ -152,10 +151,6 @@ iterator walkDirs*(pattern: string): string {.tags: [ReadDirEffect], noWeirdTarg
|
||||
assert "lib/pure/concurrency".unixToNativePath in paths
|
||||
walkCommon(pattern, isDir)
|
||||
|
||||
proc staticWalkDir(dir: string; relative: bool): seq[
|
||||
tuple[kind: PathComponent, path: string]] =
|
||||
discard
|
||||
|
||||
iterator walkDir*(dir: string; relative = false, checkDir = false,
|
||||
skipSpecial = false):
|
||||
tuple[kind: PathComponent, path: string] {.tags: [ReadDirEffect].} =
|
||||
@@ -325,7 +320,6 @@ iterator walkDirRec*(dir: string,
|
||||
# continue iteration.
|
||||
# Future work can provide a way to customize this and do error reporting.
|
||||
|
||||
|
||||
proc rawRemoveDir(dir: string) {.noWeirdTarget.} =
|
||||
when defined(windows):
|
||||
wrapUnary(res, removeDirectoryW, dir)
|
||||
|
||||
@@ -21,8 +21,6 @@ elif defined(posix):
|
||||
|
||||
proc toTime(ts: Timespec): times.Time {.inline.} =
|
||||
result = initTime(ts.tv_sec.int64, ts.tv_nsec.int)
|
||||
else:
|
||||
{.error: "OS module not ported to your operating system!".}
|
||||
|
||||
|
||||
when weirdTarget:
|
||||
|
||||
@@ -20,8 +20,6 @@ elif defined(windows):
|
||||
import std/winlean
|
||||
elif defined(posix):
|
||||
import std/posix, system/ansi_c
|
||||
else:
|
||||
{.error: "OS module not ported to your operating system!".}
|
||||
|
||||
when weirdTarget:
|
||||
{.pragma: noWeirdTarget, error: "this proc is not available on the NimScript/js target".}
|
||||
@@ -840,7 +838,7 @@ proc unixToNativePath*(path: string, drive=""): string {.
|
||||
inc(i)
|
||||
|
||||
|
||||
when not defined(nimscript):
|
||||
when not defined(nimscript) and supportedSystem:
|
||||
proc getCurrentDir*(): string {.rtl, extern: "nos$1", tags: [].} =
|
||||
## Returns the `current working directory`:idx: i.e. where the built
|
||||
## binary is run.
|
||||
@@ -889,7 +887,7 @@ when not defined(nimscript):
|
||||
else:
|
||||
raiseOSError(osLastError())
|
||||
|
||||
proc absolutePath*(path: string, root = getCurrentDir()): string =
|
||||
proc absolutePath*(path: string, root = when supportedSystem: getCurrentDir() else: ""): string =
|
||||
## Returns the absolute path of `path`, rooted at `root` (which must be absolute;
|
||||
## default: current directory).
|
||||
## If `path` is absolute, return it, ignoring `root`.
|
||||
@@ -907,7 +905,7 @@ proc absolutePath*(path: string, root = getCurrentDir()): string =
|
||||
joinPath(root, path)
|
||||
|
||||
proc absolutePathInternal(path: string): string =
|
||||
absolutePath(path, getCurrentDir())
|
||||
absolutePath(path)
|
||||
|
||||
|
||||
proc normalizePath*(path: var string) {.rtl, extern: "nos$1", tags: [].} =
|
||||
@@ -984,48 +982,49 @@ proc normalizeExe*(file: var string) {.since: (1, 3, 5).} =
|
||||
if file.len > 0 and DirSep notin file and file != "." and file != "..":
|
||||
file = "./" & file
|
||||
|
||||
proc sameFile*(path1, path2: string): bool {.rtl, extern: "nos$1",
|
||||
tags: [ReadDirEffect], noWeirdTarget.} =
|
||||
## Returns true if both pathname arguments refer to the same physical
|
||||
## file or directory.
|
||||
##
|
||||
## Raises `OSError` if any of the files does not
|
||||
## exist or information about it can not be obtained.
|
||||
##
|
||||
## This proc will return true if given two alternative hard-linked or
|
||||
## sym-linked paths to the same file or directory.
|
||||
##
|
||||
## See also:
|
||||
## * `sameFileContent proc`_
|
||||
result = false
|
||||
when defined(windows):
|
||||
var success = true
|
||||
var f1 = openHandle(path1)
|
||||
var f2 = openHandle(path2)
|
||||
when supportedSystem:
|
||||
proc sameFile*(path1, path2: string): bool {.rtl, extern: "nos$1",
|
||||
tags: [ReadDirEffect], noWeirdTarget.} =
|
||||
## Returns true if both pathname arguments refer to the same physical
|
||||
## file or directory.
|
||||
##
|
||||
## Raises `OSError` if any of the files does not
|
||||
## exist or information about it can not be obtained.
|
||||
##
|
||||
## This proc will return true if given two alternative hard-linked or
|
||||
## sym-linked paths to the same file or directory.
|
||||
##
|
||||
## See also:
|
||||
## * `sameFileContent proc`_
|
||||
result = false
|
||||
when defined(windows):
|
||||
var success = true
|
||||
var f1 = openHandle(path1)
|
||||
var f2 = openHandle(path2)
|
||||
|
||||
var lastErr: OSErrorCode
|
||||
if f1 != INVALID_HANDLE_VALUE and f2 != INVALID_HANDLE_VALUE:
|
||||
var fi1, fi2: BY_HANDLE_FILE_INFORMATION
|
||||
var lastErr: OSErrorCode
|
||||
if f1 != INVALID_HANDLE_VALUE and f2 != INVALID_HANDLE_VALUE:
|
||||
var fi1, fi2: BY_HANDLE_FILE_INFORMATION
|
||||
|
||||
if getFileInformationByHandle(f1, addr(fi1)) != 0 and
|
||||
getFileInformationByHandle(f2, addr(fi2)) != 0:
|
||||
result = fi1.dwVolumeSerialNumber == fi2.dwVolumeSerialNumber and
|
||||
fi1.nFileIndexHigh == fi2.nFileIndexHigh and
|
||||
fi1.nFileIndexLow == fi2.nFileIndexLow
|
||||
if getFileInformationByHandle(f1, addr(fi1)) != 0 and
|
||||
getFileInformationByHandle(f2, addr(fi2)) != 0:
|
||||
result = fi1.dwVolumeSerialNumber == fi2.dwVolumeSerialNumber and
|
||||
fi1.nFileIndexHigh == fi2.nFileIndexHigh and
|
||||
fi1.nFileIndexLow == fi2.nFileIndexLow
|
||||
else:
|
||||
lastErr = osLastError()
|
||||
success = false
|
||||
else:
|
||||
lastErr = osLastError()
|
||||
success = false
|
||||
else:
|
||||
lastErr = osLastError()
|
||||
success = false
|
||||
|
||||
discard closeHandle(f1)
|
||||
discard closeHandle(f2)
|
||||
discard closeHandle(f1)
|
||||
discard closeHandle(f2)
|
||||
|
||||
if not success: raiseOSError(lastErr, $(path1, path2))
|
||||
else:
|
||||
var a, b: Stat
|
||||
if stat(path1, a) < 0'i32 or stat(path2, b) < 0'i32:
|
||||
raiseOSError(osLastError(), $(path1, path2))
|
||||
if not success: raiseOSError(lastErr, $(path1, path2))
|
||||
else:
|
||||
result = a.st_dev == b.st_dev and a.st_ino == b.st_ino
|
||||
var a, b: Stat
|
||||
if stat(path1, a) < 0'i32 or stat(path2, b) < 0'i32:
|
||||
raiseOSError(osLastError(), $(path1, path2))
|
||||
else:
|
||||
result = a.st_dev == b.st_dev and a.st_ino == b.st_ino
|
||||
|
||||
@@ -2,7 +2,8 @@ include system/inclrtl
|
||||
import std/oserrors
|
||||
|
||||
import oscommon
|
||||
export symlinkExists
|
||||
when supportedSystem:
|
||||
export symlinkExists
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/[syncio, assertions, widestrs]
|
||||
@@ -13,8 +14,6 @@ elif defined(windows):
|
||||
import std/[winlean, times]
|
||||
elif defined(posix):
|
||||
import std/posix
|
||||
else:
|
||||
{.error: "OS module not ported to your operating system!".}
|
||||
|
||||
|
||||
when weirdTarget:
|
||||
|
||||
@@ -14,3 +14,25 @@ proc staticDirExists*(dir: string): bool {.compileTime.} =
|
||||
## Returns true if the directory `dir` exists. If `dir` is a file, false
|
||||
## is returned. Follows symlinks.
|
||||
raiseAssert "implemented in the vmops"
|
||||
|
||||
type
|
||||
PathComponent* = enum ## Enumeration specifying a path component.
|
||||
##
|
||||
## See also:
|
||||
## * `walkDirRec iterator`_
|
||||
## * `FileInfo object`_
|
||||
pcFile, ## path refers to a file
|
||||
pcLinkToFile, ## path refers to a symbolic link to a file
|
||||
pcDir, ## path refers to a directory
|
||||
pcLinkToDir ## path refers to a symbolic link to a directory
|
||||
|
||||
proc staticWalkDir*(dir: string; relative = false): seq[
|
||||
tuple[kind: PathComponent, path: string]] {.compileTime.} =
|
||||
## Walks over the directory `dir` and returns a seq with each directory or
|
||||
## file in `dir`. The component type and full path for each item are returned.
|
||||
##
|
||||
## Walking is not recursive.
|
||||
## * If `relative` is true (default: false)
|
||||
## the resulting path is shortened to be relative to ``dir``,
|
||||
## otherwise the full path is returned.
|
||||
raiseAssert "implemented in the vmops"
|
||||
|
||||
@@ -128,7 +128,7 @@ proc genTempPath*(prefix, suffix: string, dir = ""): string =
|
||||
##
|
||||
## The path begins with `prefix` and ends with `suffix`.
|
||||
##
|
||||
## .. note:: `dir` must exist (empty `dir` will resolve to `getTempDir <os.html#getTempDir>`_).
|
||||
## .. note:: `dir` must exist (empty `dir` will resolve to `getTempDir <appdirs.html#getTempDir>`_).
|
||||
let dir = getTempDirImpl(dir)
|
||||
result = dir / (prefix & randomPathName(nimTempPathLength) & suffix)
|
||||
|
||||
@@ -143,7 +143,7 @@ proc createTempFile*(prefix, suffix: string, dir = ""): tuple[cfile: File, path:
|
||||
##
|
||||
## .. note:: It is the caller's responsibility to close `result.cfile` and
|
||||
## remove `result.file` when no longer needed.
|
||||
## .. note:: `dir` must exist (empty `dir` will resolve to `getTempDir <os.html#getTempDir>`_).
|
||||
## .. note:: `dir` must exist (empty `dir` will resolve to `getTempDir <appdirs.html#getTempDir>`_).
|
||||
runnableExamples:
|
||||
import std/os
|
||||
doAssertRaises(OSError): discard createTempFile("", "", "nonexistent")
|
||||
@@ -176,7 +176,7 @@ proc createTempDir*(prefix, suffix: string, dir = ""): string =
|
||||
## If failing to create a temporary directory, `OSError` will be raised.
|
||||
##
|
||||
## .. note:: It is the caller's responsibility to remove the directory when no longer needed.
|
||||
## .. note:: `dir` must exist (empty `dir` will resolve to `getTempDir <os.html#getTempDir>`_).
|
||||
## .. note:: `dir` must exist (empty `dir` will resolve to `getTempDir <appdirs.html#getTempDir>`_).
|
||||
runnableExamples:
|
||||
import std/os
|
||||
doAssertRaises(OSError): discard createTempDir("", "", "nonexistent")
|
||||
|
||||
15
nimsuggest/tests/t21923.nim
Normal file
15
nimsuggest/tests/t21923.nim
Normal file
@@ -0,0 +1,15 @@
|
||||
discard """
|
||||
$nimsuggest --tester $file
|
||||
>outline $file
|
||||
outline;;skProc;;t21923.foo;;proc (x: int){.gcsafe, raises: <inferred> [].};;$file;;8;;5;;"";;100
|
||||
outline;;skTemplate;;t21923.foo2;;;;$file;;11;;9;;"";;100
|
||||
"""
|
||||
|
||||
proc foo(x: int) =
|
||||
echo "foo"
|
||||
|
||||
template foo2(x: int) =
|
||||
echo "foo2"
|
||||
|
||||
foo(12)
|
||||
foo2(12)
|
||||
@@ -6,7 +6,7 @@ tmp#[!]#
|
||||
discard """
|
||||
$nimsuggest --tester $file
|
||||
>sug $1
|
||||
sug;;skTemplate;;tsug_template.tmpa;;template ();;$file;;1;;9;;"";;100;;Prefix
|
||||
sug;;skMacro;;tsug_template.tmpb;;macro (){.noSideEffect, gcsafe, raises: <inferred> [].};;$file;;2;;6;;"";;100;;Prefix
|
||||
sug;;skConverter;;tsug_template.tmpc;;converter ();;$file;;3;;10;;"";;100;;Prefix
|
||||
sug;;skTemplate;;tsug_template.tmpa;;template ();;$file;;1;;9;;"";;100;;Prefix
|
||||
"""
|
||||
|
||||
@@ -128,4 +128,10 @@ block:
|
||||
var b = makeBoo()
|
||||
var b2 = makeBoo2()
|
||||
|
||||
main()
|
||||
main()
|
||||
|
||||
block: # bug #24658
|
||||
type
|
||||
A {.importcpp: "A".} = object
|
||||
|
||||
proc a(something: ptr cint = nil): A {.cdecl, constructor, importcpp: "A(@)".}
|
||||
|
||||
11
tests/errmsgs/tambtypegeneric.nim
Normal file
11
tests/errmsgs/tambtypegeneric.nim
Normal file
@@ -0,0 +1,11 @@
|
||||
import "."/[mambtype1, mambtype2]
|
||||
type H[K] = object
|
||||
proc b(_: int) = # slightly different, still not useful, error message if `b` generic
|
||||
proc r(): H[Y] = discard #[tt.Error
|
||||
^ cannot instantiate H [type declared in tambtypegeneric.nim(2, 6)]
|
||||
got: <typedesc[Y] | typedesc[Y]>
|
||||
but expected: <K>
|
||||
ambiguous identifier: 'Y' -- use one of the following:
|
||||
mambtype1.Y: Y
|
||||
mambtype2.Y: Y]#
|
||||
b(0)
|
||||
@@ -6,6 +6,54 @@ import unittest, strutils
|
||||
|
||||
block: # parseutils
|
||||
check: parseBiggestUInt("0") == 0'u64
|
||||
check: parseBiggestUInt("1") == 1'u64
|
||||
check: parseBiggestUInt("2") == 2'u64
|
||||
check: parseBiggestUInt("10") == 10'u64
|
||||
check: parseBiggestUInt("11") == 11'u64
|
||||
check: parseBiggestUInt("99") == 99'u64
|
||||
check: parseBiggestUInt("123") == 123'u64
|
||||
check: parseBiggestUInt("9876") == 9876'u64
|
||||
check: parseBiggestUInt("1_234") == 1234'u64
|
||||
check: parseBiggestUInt("123__4") == 1234'u64
|
||||
for i in 1.BiggestUInt .. 9.BiggestUInt:
|
||||
var x = i
|
||||
for j in 1 .. 19:
|
||||
check parseBiggestUInt((i + '0'.uint).char.repeat j) == x
|
||||
x *= 10
|
||||
x += i
|
||||
check: parseBiggestUInt("18446744073709551609") == 0xFFFF_FFFF_FFFF_FFF9'u64
|
||||
check: parseBiggestUInt("18446744073709551610") == 0xFFFF_FFFF_FFFF_FFFA'u64
|
||||
check: parseBiggestUInt("18446744073709551611") == 0xFFFF_FFFF_FFFF_FFFB'u64
|
||||
check: parseBiggestUInt("18446744073709551612") == 0xFFFF_FFFF_FFFF_FFFC'u64
|
||||
check: parseBiggestUInt("18446744073709551613") == 0xFFFF_FFFF_FFFF_FFFD'u64
|
||||
check: parseBiggestUInt("18446744073709551614") == 0xFFFF_FFFF_FFFF_FFFE'u64
|
||||
check: parseBiggestUInt("18446744073709551615") == 0xFFFF_FFFF_FFFF_FFFF'u64
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("18446744073709551616")
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("18446744073709551617")
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("18446744073709551618")
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("18446744073709551619")
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("18446744073709551620")
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("18446744073709551621")
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("18446744073709551622")
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("18446744073709551623")
|
||||
expect(ValueError):
|
||||
for i in 0 .. 999:
|
||||
discard parseBiggestUInt("18446744073709552" & intToStr(i, 3))
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("22751622367522324480000000")
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("41404969074137497600000000")
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("20701551093035827200000000000000000")
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("225462255024603136000000000000000000")
|
||||
expect(ValueError):
|
||||
discard parseBiggestUInt("204963831854661632000000000000000000")
|
||||
|
||||
9
tests/template/tfielduse.nim
Normal file
9
tests/template/tfielduse.nim
Normal file
@@ -0,0 +1,9 @@
|
||||
# issue #24657
|
||||
|
||||
proc g() {.error.} = discard
|
||||
|
||||
type T = object
|
||||
g: int
|
||||
|
||||
template B(): untyped = typeof(T.g)
|
||||
type _ = B()
|
||||
Reference in New Issue
Block a user