mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-16 20:08:29 +00:00
Merge branch 'devel' into pr_legacy_asm
This commit is contained in:
20
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
20
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -10,6 +10,16 @@ body:
|
||||
Please provide a minimal code example that reproduces the bug if possible.
|
||||
Reports with a reproducible example or detailed information will likely receive fixes faster.
|
||||
|
||||
- type: textarea
|
||||
id: nim-version
|
||||
attributes:
|
||||
label: Nim Version
|
||||
description: |
|
||||
Can be obtained from `nim -v` on the command line along with the OS/architecture.
|
||||
For development versions, including the commit hash may help.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
@@ -19,16 +29,6 @@ body:
|
||||
placeholder: Bug reports with reproducible code or detailed information will be fixed faster.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: nim-version
|
||||
attributes:
|
||||
label: Nim Version
|
||||
description: |
|
||||
Can be obtained from `nim -v` on the command line along with the OS/architecture.
|
||||
For development versions, make sure to include the commit hash.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: current-logs
|
||||
|
||||
2
.github/workflows/ci_docs.yml
vendored
2
.github/workflows/ci_docs.yml
vendored
@@ -41,7 +41,7 @@ jobs:
|
||||
target: [linux, windows, osx]
|
||||
include:
|
||||
- target: linux
|
||||
os: ubuntu-20.04
|
||||
os: ubuntu-22.04
|
||||
- target: windows
|
||||
os: windows-2019
|
||||
- target: osx
|
||||
|
||||
2
.github/workflows/ci_packages.yml
vendored
2
.github/workflows/ci_packages.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-20.04, macos-13]
|
||||
os: [ubuntu-22.04, macos-13]
|
||||
cpu: [amd64]
|
||||
batch: ["allowed_failures", "0_3", "1_3", "2_3"] # list of `index_num`
|
||||
name: '${{ matrix.os }} (batch: ${{ matrix.batch }})'
|
||||
|
||||
17
.github/workflows/ci_publish.yml
vendored
17
.github/workflows/ci_publish.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-20.04]
|
||||
os: [ubuntu-22.04]
|
||||
cpu: [amd64]
|
||||
name: '${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
@@ -21,10 +21,10 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: 'Install node.js 20.x'
|
||||
- name: 'Install node.js'
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20.x'
|
||||
node-version: ''
|
||||
|
||||
- name: 'Install dependencies (Linux amd64)'
|
||||
if: runner.os == 'Linux' && matrix.cpu == 'amd64'
|
||||
@@ -34,17 +34,6 @@ jobs:
|
||||
sudo apt-fast install --no-install-recommends -yq \
|
||||
libcurl4-openssl-dev libgc-dev libsdl1.2-dev libsfml-dev \
|
||||
valgrind libc6-dbg libblas-dev xorg-dev
|
||||
- name: 'Install dependencies (macOS)'
|
||||
if: runner.os == 'macOS'
|
||||
run: brew install boehmgc make sfml gtk+3
|
||||
- name: 'Install dependencies (Windows)'
|
||||
if: runner.os == 'Windows'
|
||||
shell: bash
|
||||
run: |
|
||||
set -e
|
||||
. ci/funs.sh
|
||||
nimInternalInstallDepsWindows
|
||||
echo_run echo "${{ github.workspace }}/dist/mingw64/bin" >> "${GITHUB_PATH}"
|
||||
|
||||
- name: 'Add build binaries to PATH'
|
||||
shell: bash
|
||||
|
||||
@@ -169,7 +169,7 @@ echo f
|
||||
- The Nim compiler now supports a new pragma called ``.localPassc`` to
|
||||
pass specific compiler options to the C(++) backend for the C(++) file
|
||||
that was produced from the current Nim module.
|
||||
- The compiler now inferes "sink parameters". To disable this for a specific routine,
|
||||
- The compiler now infers "sink parameters". To disable this for a specific routine,
|
||||
annotate it with `.nosinks`. To disable it for a section of code, use
|
||||
`{.push sinkInference: off.}`...`{.pop.}`.
|
||||
- The compiler now supports a new switch `--panics:on` that turns runtime
|
||||
@@ -261,7 +261,7 @@ echo f
|
||||
([#12812](https://github.com/nim-lang/Nim/issues/12812))
|
||||
- Fixed "Produce static/const initializations for variables when possible"
|
||||
([#12216](https://github.com/nim-lang/Nim/issues/12216))
|
||||
- Fixed "Assigning descriminator field leads to internal assert with --gc:destructors"
|
||||
- Fixed "Assigning discriminator field leads to internal assert with --gc:destructors"
|
||||
([#12821](https://github.com/nim-lang/Nim/issues/12821))
|
||||
- Fixed "nimsuggest `use` command does not return all instances of symbol"
|
||||
([#12832](https://github.com/nim-lang/Nim/issues/12832))
|
||||
|
||||
@@ -2198,6 +2198,13 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||
else: putIntoDest(p, d, e, cIntValue(lengthOrd(p.config, typ)))
|
||||
else: internalError(p.config, e.info, "genArrayLen()")
|
||||
|
||||
proc isTrivialTypesToSnippet(t: PType): Snippet =
|
||||
if containsGarbageCollectedRef(t) or
|
||||
hasDestructor(t):
|
||||
result = NimFalse
|
||||
else:
|
||||
result = NimTrue
|
||||
|
||||
proc genSetLengthSeq(p: BProc, e: PNode, d: var TLoc) =
|
||||
if optSeqDestructors in p.config.globalOptions:
|
||||
e[1] = makeAddr(e[1], p.module.idgen)
|
||||
@@ -2220,7 +2227,8 @@ proc genSetLengthSeq(p: BProc, e: PNode, d: var TLoc) =
|
||||
pExpr = cIfExpr(ra, cAddr(derefField(ra, "Sup")), NimNil)
|
||||
else:
|
||||
pExpr = ra
|
||||
call.snippet = cCast(rt, cgCall(p, "setLengthSeqV2", pExpr, rti, rb))
|
||||
call.snippet = cCast(rt, cgCall(p, "setLengthSeqV2", pExpr, rti, rb,
|
||||
isTrivialTypesToSnippet(t.skipTypes(abstractInst)[0])))
|
||||
|
||||
genAssignment(p, a, call, {})
|
||||
gcUsage(p.config, e)
|
||||
|
||||
@@ -57,11 +57,15 @@ proc mangleField(m: BModule; name: PIdent): string =
|
||||
|
||||
proc mangleProc(m: BModule; s: PSym; makeUnique: bool): string =
|
||||
result = "_Z" # Common prefix in Itanium ABI
|
||||
result.add encodeSym(m, s, makeUnique)
|
||||
var params = ""
|
||||
var staticLists = ""
|
||||
if s.typ.len > 1: #we dont care about the return param
|
||||
for i in 1..<s.typ.len:
|
||||
if s.typ[i].isNil: continue
|
||||
result.add encodeType(m, s.typ[i])
|
||||
params.add encodeType(m, s.typ[i], staticLists)
|
||||
|
||||
result.add encodeSym(m, s, makeUnique, staticLists)
|
||||
result.add params
|
||||
|
||||
if result in m.g.mangledPrcs:
|
||||
result = mangleProc(m, s, true)
|
||||
@@ -115,7 +119,7 @@ proc fillLocalName(p: BProc; s: PSym) =
|
||||
if s.kind == skTemp:
|
||||
# speed up conflict search for temps (these are quite common):
|
||||
if counter != 0: result.add "_" & rope(counter+1)
|
||||
elif counter != 0 or isKeyword(s.name) or p.module.g.config.cppDefines.contains(key):
|
||||
elif s.kind != skResult:
|
||||
result.add "_" & rope(counter+1)
|
||||
p.sigConflicts.inc(key)
|
||||
s.loc.snippet = result
|
||||
@@ -247,10 +251,6 @@ proc hasNoInit(t: PType): bool =
|
||||
|
||||
proc getTypeDescAux(m: BModule; origTyp: PType, check: var IntSet; kind: TypeDescKind): Rope
|
||||
|
||||
proc isObjLackingTypeField(typ: PType): bool {.inline.} =
|
||||
result = (typ.kind == tyObject) and ((tfFinal in typ.flags) and
|
||||
(typ.baseClass == nil) or isPureObject(typ))
|
||||
|
||||
proc isInvalidReturnType(conf: ConfigRef; typ: PType, isProc = true): bool =
|
||||
# Arrays and sets cannot be returned by a C procedure, because C is
|
||||
# such a poor programming language.
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
import
|
||||
ast, types, msgs, wordrecg,
|
||||
platform, trees, options, cgendata, mangleutils
|
||||
platform, trees, options, cgendata, mangleutils, renderer
|
||||
|
||||
import std/[hashes, strutils, formatfloat]
|
||||
|
||||
@@ -101,7 +101,11 @@ proc ccgIntroducedPtr*(conf: ConfigRef; s: PSym, retType: PType): bool =
|
||||
result = true # ordinary objects are always passed by reference,
|
||||
# otherwise casting doesn't work
|
||||
of tyTuple:
|
||||
result = (getSize(conf, pt) > conf.target.floatSize*3) or (optByRef in s.options)
|
||||
if s.typ.kind == tySink:
|
||||
# it's a sink, so we pass it by value
|
||||
result = false
|
||||
else:
|
||||
result = (getSize(conf, pt) > conf.target.floatSize*3) or (optByRef in s.options)
|
||||
else:
|
||||
result = false
|
||||
# first parameter and return type is 'lent T'? --> use pass by pointer
|
||||
@@ -120,14 +124,14 @@ proc makeUnique(m: BModule; s: PSym, name: string = ""): string =
|
||||
result.add "_u"
|
||||
result.add $s.itemId.item
|
||||
|
||||
proc encodeSym*(m: BModule; s: PSym; makeUnique: bool = false): string =
|
||||
proc encodeSym*(m: BModule; s: PSym; makeUnique: bool = false; extra: string = ""): string =
|
||||
#Module::Type
|
||||
var name = s.name.s
|
||||
var name = s.name.s & extra
|
||||
if makeUnique:
|
||||
name = makeUnique(m, s, name)
|
||||
"N" & encodeName(s.skipGenericOwner.name.s) & encodeName(name) & "E"
|
||||
|
||||
proc encodeType*(m: BModule; t: PType): string =
|
||||
proc encodeType*(m: BModule; t: PType; staticLists: var string): string =
|
||||
result = ""
|
||||
var kindName = ($t.kind)[2..^1]
|
||||
kindName[0] = toLower($kindName[0])[0]
|
||||
@@ -138,10 +142,10 @@ proc encodeType*(m: BModule; t: PType): string =
|
||||
result = encodeName(t[0].sym.name.s)
|
||||
result.add "I"
|
||||
for i in 1..<t.len - 1:
|
||||
result.add encodeType(m, t[i])
|
||||
result.add encodeType(m, t[i], staticLists)
|
||||
result.add "E"
|
||||
of tySequence, tyOpenArray, tyArray, tyVarargs, tyTuple, tyProc, tySet, tyTypeDesc,
|
||||
tyPtr, tyRef, tyVar, tyLent, tySink, tyStatic, tyUncheckedArray, tyOr, tyAnd, tyBuiltInTypeClass:
|
||||
tyPtr, tyRef, tyVar, tyLent, tySink, tyUncheckedArray, tyOr, tyAnd, tyBuiltInTypeClass:
|
||||
result =
|
||||
case t.kind:
|
||||
of tySequence: encodeName("seq")
|
||||
@@ -150,8 +154,13 @@ proc encodeType*(m: BModule; t: PType): string =
|
||||
for i in 0..<t.len:
|
||||
let s = t[i]
|
||||
if s.isNil: continue
|
||||
result.add encodeType(m, s)
|
||||
result.add encodeType(m, s, staticLists)
|
||||
result.add "E"
|
||||
of tyStatic:
|
||||
if t.n != nil:
|
||||
staticLists.add "_s" & renderTree(t.n)
|
||||
else:
|
||||
raiseAssert "unreachable"
|
||||
of tyRange:
|
||||
var val = "range_"
|
||||
if t.n[0].typ.kind in {tyFloat..tyFloat128}:
|
||||
@@ -164,7 +173,7 @@ proc encodeType*(m: BModule; t: PType): string =
|
||||
of tyString..tyUInt64, tyPointer, tyBool, tyChar, tyVoid, tyAnything, tyNil, tyEmpty:
|
||||
result = encodeName(kindName)
|
||||
of tyAlias, tyInferred, tyOwned:
|
||||
result = encodeType(m, t.elementType)
|
||||
result = encodeType(m, t.elementType, staticLists)
|
||||
else:
|
||||
assert false, "encodeType " & $t.kind
|
||||
|
||||
|
||||
@@ -172,6 +172,5 @@ proc initDefines*(symbols: StringTableRef) =
|
||||
defineSymbol("nimHasDefaultFloatRoundtrip")
|
||||
defineSymbol("nimHasXorSet")
|
||||
|
||||
defineSymbol("nimHasLegacyNoStrictDefs")
|
||||
|
||||
defineSymbol("nimHasAsmSemSymbol")
|
||||
|
||||
|
||||
@@ -1197,7 +1197,7 @@ proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
|
||||
fillStrOp(a, typ, result.ast[bodyPos], d, src)
|
||||
else:
|
||||
fillBody(a, typ, result.ast[bodyPos], d, src)
|
||||
if tk == tyObject and a.kind in {attachedAsgn, attachedSink, attachedDeepCopy, attachedDup} and not lacksMTypeField(typ):
|
||||
if tk == tyObject and a.kind in {attachedAsgn, attachedSink, attachedDeepCopy, attachedDup} and not isObjLackingTypeField(typ):
|
||||
# bug #19205: Do not forget to also copy the hidden type field:
|
||||
genTypeFieldCopy(a, typ, result.ast[bodyPos], d, src)
|
||||
|
||||
@@ -1207,6 +1207,8 @@ proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
|
||||
result.ast[pragmasPos].add newTree(nkExprColonExpr,
|
||||
newIdentNode(g.cache.getIdent("raises"), info), newNodeI(nkBracket, info))
|
||||
|
||||
if kind == attachedDestructor:
|
||||
incl result.options, optQuirky
|
||||
completePartialOp(g, idgen.module, typ, kind, result)
|
||||
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ define:useStdoutAsStdmsg
|
||||
|
||||
|
||||
@if nimUseStrictDefs:
|
||||
experimental:strictDefs # deadcode
|
||||
experimental:strictDefs
|
||||
warningAsError[Uninit]:on
|
||||
warningAsError[ProveInit]:on
|
||||
@end
|
||||
|
||||
@@ -248,8 +248,6 @@ type
|
||||
## Useful for libraries that rely on local passC
|
||||
jsNoLambdaLifting
|
||||
## Old transformation for closures in JS backend
|
||||
noStrictDefs
|
||||
## disable "strictdefs"
|
||||
noAsmSemSymbol
|
||||
## disable type checking for backticked symbols in the `asm/emit` statements
|
||||
|
||||
|
||||
@@ -590,7 +590,7 @@ proc processCompile(c: PContext, n: PNode) =
|
||||
var customArgs = ""
|
||||
if n.kind in nkCallKinds:
|
||||
s = getStrLit(c, n, 1)
|
||||
if n.len <= 3:
|
||||
if n.len == 3:
|
||||
customArgs = getStrLit(c, n, 2)
|
||||
else:
|
||||
localError(c.config, n.info, "'.compile' pragma takes up 2 arguments")
|
||||
@@ -1319,8 +1319,12 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||
pragmaProposition(c, it)
|
||||
of wEnsures:
|
||||
pragmaEnsures(c, it)
|
||||
of wEnforceNoRaises, wQuirky:
|
||||
of wEnforceNoRaises:
|
||||
sym.flags.incl sfNeverRaises
|
||||
of wQuirky:
|
||||
sym.flags.incl sfNeverRaises
|
||||
if sym.kind in {skProc, skMethod, skConverter, skFunc, skIterator}:
|
||||
sym.options.incl optQuirky
|
||||
of wSystemRaisesDefect:
|
||||
sym.flags.incl sfSystemRaisesDefect
|
||||
of wVirtual:
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -878,7 +878,7 @@ proc newHiddenAddrTaken(c: PContext, n: PNode, isOutParam: bool): PNode =
|
||||
if aa notin {arLValue, arLocalLValue}:
|
||||
if aa == arDiscriminant and c.inUncheckedAssignSection > 0:
|
||||
discard "allow access within a cast(unsafeAssign) section"
|
||||
elif noStrictDefs notin c.config.legacyFeatures and aa == arAddressableConst and
|
||||
elif strictDefs in c.features and aa == arAddressableConst and
|
||||
sym != nil and sym.kind == skLet and isOutParam:
|
||||
discard "allow let varaibles to be passed to out parameters"
|
||||
else:
|
||||
@@ -2068,8 +2068,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
|
||||
let root = getRoot(a)
|
||||
let useStrictDefLet = root != nil and root.kind == skLet and
|
||||
assignable == arAddressableConst and
|
||||
noStrictDefs notin c.config.legacyFeatures and
|
||||
isLocalSym(root)
|
||||
strictDefs in c.features and isLocalSym(root)
|
||||
if le == nil:
|
||||
localError(c.config, a.info, "expression has no type")
|
||||
elif (skipTypes(le, {tyGenericInst, tyAlias, tySink}).kind notin {tyVar} and
|
||||
@@ -2929,7 +2928,10 @@ proc semTupleFieldsConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType
|
||||
# hasEmpty/nil check is to not break existing code like
|
||||
# `const foo = [(1, {}), (2, {false})]`,
|
||||
# `const foo = if true: (0, nil) else: (1, new(int))`
|
||||
n[i][1] = fitNode(c, expectedElemType, n[i][1], n[i][1].info)
|
||||
let conversion = indexTypesMatch(c, expectedElemType, n[i][1].typ, n[i][1])
|
||||
# ignore matching error, full tuple will be matched later which may call converter, see #24609
|
||||
if conversion != nil:
|
||||
n[i][1] = conversion
|
||||
|
||||
if n[i][1].typ.kind == tyTypeDesc:
|
||||
localError(c.config, n[i][1].info, "typedesc not allowed as tuple field.")
|
||||
@@ -2942,7 +2944,14 @@ proc semTupleFieldsConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType
|
||||
typ.n.add newSymNode(f)
|
||||
n[i][0] = newSymNode(f)
|
||||
result.add n[i]
|
||||
let oldType = n.typ
|
||||
result.typ() = typ
|
||||
if oldType != nil and not hasEmpty(oldType): # see hasEmpty comment above
|
||||
# convert back to old type
|
||||
let conversion = indexTypesMatch(c, oldType, typ, result)
|
||||
# ignore matching error, the goal is just to keep the original type info
|
||||
if conversion != nil:
|
||||
result = conversion
|
||||
|
||||
proc semTuplePositionsConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType = nil): PNode =
|
||||
result = n # we don't modify n, but compute the type:
|
||||
@@ -2961,9 +2970,19 @@ proc semTuplePositionsConstr(c: PContext, n: PNode, flags: TExprFlags; expectedT
|
||||
# hasEmpty/nil check is to not break existing code like
|
||||
# `const foo = [(1, {}), (2, {false})]`,
|
||||
# `const foo = if true: (0, nil) else: (1, new(int))`
|
||||
n[i] = fitNode(c, expectedElemType, n[i], n[i].info)
|
||||
let conversion = indexTypesMatch(c, expectedElemType, n[i].typ, n[i])
|
||||
# ignore matching error, full tuple will be matched later which may call converter, see #24609
|
||||
if conversion != nil:
|
||||
n[i] = conversion
|
||||
addSonSkipIntLit(typ, n[i].typ.skipTypes({tySink}), c.idgen)
|
||||
let oldType = n.typ
|
||||
result.typ() = typ
|
||||
if oldType != nil and not hasEmpty(oldType): # see hasEmpty comment above
|
||||
# convert back to old type
|
||||
let conversion = indexTypesMatch(c, oldType, typ, result)
|
||||
# ignore matching error, the goal is just to keep the original type info
|
||||
if conversion != nil:
|
||||
result = conversion
|
||||
|
||||
include semobjconstr
|
||||
|
||||
@@ -3052,9 +3071,12 @@ proc semExport(c: PContext, n: PNode): PNode =
|
||||
s = nextOverloadIter(o, c, a)
|
||||
|
||||
proc semTupleConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType = nil): PNode =
|
||||
var tupexp = semTuplePositionsConstr(c, n, flags, expectedType)
|
||||
result = semTuplePositionsConstr(c, n, flags, expectedType)
|
||||
var tupexp = result
|
||||
while tupexp.kind == nkHiddenSubConv: tupexp = tupexp[1]
|
||||
var isTupleType: bool = false
|
||||
if tupexp.len > 0: # don't interpret () as type
|
||||
internalAssert c.config, tupexp.kind == nkTupleConstr
|
||||
isTupleType = tupexp[0].typ.kind == tyTypeDesc
|
||||
# check if either everything or nothing is tyTypeDesc
|
||||
for i in 1..<tupexp.len:
|
||||
@@ -3064,8 +3086,6 @@ proc semTupleConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PTyp
|
||||
result = n
|
||||
var typ = semTypeNode(c, n, nil).skipTypes({tyTypeDesc})
|
||||
result.typ() = makeTypeDesc(c, typ)
|
||||
else:
|
||||
result = tupexp
|
||||
|
||||
proc isExplicitGenericCall(c: PContext, n: PNode): bool =
|
||||
## checks if a call node `n` is a routine call with explicit generic params
|
||||
|
||||
@@ -36,7 +36,8 @@ proc instFieldLoopBody(c: TFieldInstCtx, n: PNode, forLoop: PNode): PNode =
|
||||
of nkIdent, nkSym:
|
||||
result = n
|
||||
let ident = considerQuotedIdent(c.c, n)
|
||||
if c.replaceByFieldName:
|
||||
if c.replaceByFieldName and
|
||||
ident.id != ord(wUnderscore):
|
||||
if ident.id == considerQuotedIdent(c.c, forLoop[0]).id:
|
||||
let fieldName = if c.tupleType.isNil: c.field.name.s
|
||||
elif c.tupleType.n.isNil: "Field" & $c.tupleIndex
|
||||
@@ -45,7 +46,8 @@ proc instFieldLoopBody(c: TFieldInstCtx, n: PNode, forLoop: PNode): PNode =
|
||||
return
|
||||
# other fields:
|
||||
for i in ord(c.replaceByFieldName)..<forLoop.len-2:
|
||||
if ident.id == considerQuotedIdent(c.c, forLoop[i]).id:
|
||||
if ident.id == considerQuotedIdent(c.c, forLoop[i]).id and
|
||||
ident.id != ord(wUnderscore):
|
||||
var call = forLoop[^2]
|
||||
var tupl = call[i+1-ord(c.replaceByFieldName)]
|
||||
if c.field.isNil:
|
||||
|
||||
@@ -55,7 +55,7 @@ proc semTypeOf(c: PContext; n: PNode): PNode =
|
||||
result.add typExpr
|
||||
if typExpr.typ.kind == tyFromExpr:
|
||||
typExpr.typ.flags.incl tfNonConstExpr
|
||||
result.typ() = makeTypeDesc(c, typExpr.typ)
|
||||
result.typ() = makeTypeDesc(c, typExpr.typ.skipTypes({tyStatic}))
|
||||
|
||||
type
|
||||
SemAsgnMode = enum asgnNormal, noOverloadedSubscript, noOverloadedAsgn
|
||||
|
||||
@@ -124,10 +124,11 @@ proc collectObjectTree(graph: ModuleGraph, n: PNode) =
|
||||
else:
|
||||
graph.objectTree[root].add (depthLevel, typ)
|
||||
|
||||
proc createTypeBoundOps(tracked: PEffects, typ: PType; info: TLineInfo) =
|
||||
if typ == nil or sfGeneratedOp in tracked.owner.flags:
|
||||
proc createTypeBoundOps(tracked: PEffects, typ: PType; info: TLineInfo; explicit = false) =
|
||||
if typ == nil or (sfGeneratedOp in tracked.owner.flags and not explicit):
|
||||
# don't create type bound ops for anything in a function with a `nodestroy` pragma
|
||||
# bug #21987
|
||||
# unless this is an explicit call, bug #24626
|
||||
return
|
||||
when false:
|
||||
let realType = typ.skipTypes(abstractInst)
|
||||
@@ -136,8 +137,9 @@ proc createTypeBoundOps(tracked: PEffects, typ: PType; info: TLineInfo) =
|
||||
createTypeBoundOps(tracked.graph, tracked.c, realType.lastSon, info)
|
||||
|
||||
createTypeBoundOps(tracked.graph, tracked.c, typ, info, tracked.c.idgen)
|
||||
if (tfHasAsgn in typ.flags) or
|
||||
optSeqDestructors in tracked.config.globalOptions:
|
||||
if tracked.config.selectedGC == gcRefc or
|
||||
optSeqDestructors in tracked.config.globalOptions or
|
||||
tfHasAsgn in typ.flags:
|
||||
tracked.owner.flags.incl sfInjectDestructors
|
||||
|
||||
proc isLocalSym(a: PEffects, s: PSym): bool =
|
||||
@@ -221,7 +223,7 @@ proc initVar(a: PEffects, n: PNode; volatileCheck: bool) =
|
||||
if volatileCheck: makeVolatile(a, s)
|
||||
for x in a.init:
|
||||
if x == s.id:
|
||||
if noStrictDefs notin a.c.config.legacyFeatures and s.kind == skLet:
|
||||
if strictDefs in a.c.features and s.kind == skLet:
|
||||
localError(a.config, n.info, errXCannotBeAssignedTo %
|
||||
renderTree(n, {renderNoComments}
|
||||
))
|
||||
@@ -379,7 +381,7 @@ proc useVar(a: PEffects, n: PNode) =
|
||||
if s.typ.requiresInit:
|
||||
message(a.config, n.info, warnProveInit, s.name.s)
|
||||
elif a.leftPartOfAsgn <= 0:
|
||||
if noStrictDefs notin a.c.config.legacyFeatures:
|
||||
if strictDefs in a.c.features:
|
||||
if s.kind == skLet:
|
||||
localError(a.config, n.info, errLetNeedsInit)
|
||||
else:
|
||||
@@ -1072,7 +1074,7 @@ proc trackCall(tracked: PEffects; n: PNode) =
|
||||
# rebind type bounds operations after createTypeBoundOps call
|
||||
let t = n[1].typ.skipTypes({tyAlias, tyVar})
|
||||
if a.sym != getAttachedOp(tracked.graph, t, TTypeAttachedOp(opKind)):
|
||||
createTypeBoundOps(tracked, t, n.info)
|
||||
createTypeBoundOps(tracked, t, n.info, explicit = true)
|
||||
let op = getAttachedOp(tracked.graph, t, TTypeAttachedOp(opKind))
|
||||
if op != nil:
|
||||
n[0].sym = op
|
||||
@@ -1664,7 +1666,7 @@ proc trackProc*(c: PContext; s: PSym, body: PNode) =
|
||||
|
||||
if not isEmptyType(s.typ.returnType) and
|
||||
(s.typ.returnType.requiresInit or s.typ.returnType.skipTypes(abstractInst).kind == tyVar or
|
||||
noStrictDefs notin c.config.legacyFeatures) and
|
||||
strictDefs in c.features) and
|
||||
s.kind in {skProc, skFunc, skConverter, skMethod} and s.magic == mNone and
|
||||
sfNoInit notin s.flags:
|
||||
var res = s.ast[resultPos].sym # get result symbol
|
||||
|
||||
@@ -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) =
|
||||
@@ -975,7 +964,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||
else:
|
||||
checkNilable(c, v)
|
||||
# allow let to not be initialised if imported from C:
|
||||
if v.kind == skLet and sfImportc notin v.flags and (noStrictDefs in c.config.legacyFeatures or not isLocalSym(v)):
|
||||
if v.kind == skLet and sfImportc notin v.flags and (strictDefs notin c.features or not isLocalSym(v)):
|
||||
localError(c.config, a.info, errLetNeedsInit)
|
||||
if sfCompileTime in v.flags:
|
||||
var x = newNodeI(result.kind, v.info)
|
||||
@@ -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:
|
||||
@@ -2158,9 +2158,6 @@ proc bindTypeHook(c: PContext; s: PSym; n: PNode; op: TTypeAttachedOp) =
|
||||
elif obj.kind == tyGenericInvocation: obj = obj.genericHead
|
||||
else: break
|
||||
if obj.kind in {tyObject, tyDistinct, tySequence, tyString}:
|
||||
if op == attachedDestructor and t.firstParamType.kind == tyVar and
|
||||
c.config.selectedGC in {gcArc, gcAtomicArc, gcOrc}:
|
||||
message(c.config, n.info, warnDeprecated, "A custom '=destroy' hook which takes a 'var T' parameter is deprecated; it should take a 'T' parameter")
|
||||
obj = canonType(c, obj)
|
||||
let ao = getAttachedOp(c.graph, obj, op)
|
||||
if ao == s:
|
||||
@@ -2351,7 +2348,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:
|
||||
|
||||
@@ -1501,7 +1501,10 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
|
||||
addParamOrResult(c, arg, kind)
|
||||
styleCheckDef(c, a[j].info, arg)
|
||||
onDef(a[j].info, arg)
|
||||
a[j] = newSymNode(arg)
|
||||
if a[j].kind == nkPragmaExpr:
|
||||
a[j][0] = newSymNode(arg)
|
||||
else:
|
||||
a[j] = newSymNode(arg)
|
||||
|
||||
var r: PType = nil
|
||||
if n[0].kind != nkEmpty:
|
||||
@@ -1671,6 +1674,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)
|
||||
|
||||
@@ -1728,10 +1736,10 @@ proc maybeAliasType(c: PContext; typeExpr, prev: PType): PType =
|
||||
else:
|
||||
result = nil
|
||||
|
||||
proc fixupTypeOf(c: PContext, prev: PType, typExpr: PNode) =
|
||||
proc fixupTypeOf(c: PContext, prev: PType, typ: PType) =
|
||||
if prev != nil:
|
||||
let result = newTypeS(tyAlias, c)
|
||||
result.rawAddSon typExpr.typ
|
||||
result.rawAddSon typ
|
||||
result.sym = prev.sym
|
||||
if prev.kind != tyGenericBody:
|
||||
assignType(prev, result)
|
||||
@@ -1923,10 +1931,11 @@ proc semTypeOf(c: PContext; n: PNode; prev: PType): PType =
|
||||
openScope(c)
|
||||
inc c.inTypeofContext
|
||||
defer: dec c.inTypeofContext # compiles can raise an exception
|
||||
let t = semExprWithType(c, n, {efInTypeof})
|
||||
let ex = semExprWithType(c, n, {efInTypeof})
|
||||
closeScope(c)
|
||||
let t = ex.typ.skipTypes({tyStatic})
|
||||
fixupTypeOf(c, prev, t)
|
||||
result = t.typ
|
||||
result = t
|
||||
if result.kind == tyFromExpr:
|
||||
result.flags.incl tfNonConstExpr
|
||||
|
||||
@@ -1941,10 +1950,11 @@ proc semTypeOf2(c: PContext; n: PNode; prev: PType): PType =
|
||||
m = mode.intVal
|
||||
inc c.inTypeofContext
|
||||
defer: dec c.inTypeofContext # compiles can raise an exception
|
||||
let t = semExprWithType(c, n[1], if m == 1: {efInTypeof} else: {})
|
||||
let ex = semExprWithType(c, n[1], if m == 1: {efInTypeof} else: {})
|
||||
closeScope(c)
|
||||
let t = ex.typ.skipTypes({tyStatic})
|
||||
fixupTypeOf(c, prev, t)
|
||||
result = t.typ
|
||||
result = t
|
||||
if result.kind == tyFromExpr:
|
||||
result.flags.incl tfNonConstExpr
|
||||
|
||||
|
||||
@@ -1424,7 +1424,8 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
return isNone
|
||||
|
||||
if fRange.rangeHasUnresolvedStatic:
|
||||
if aRange.kind in {tyGenericParam} and aRange.reduceToBase() == aRange:
|
||||
if (aRange.kind in {tyGenericParam} and aRange.reduceToBase() == aRange) or
|
||||
(aRange.kind == tyRange and aRange.rangeHasUnresolvedStatic):
|
||||
return
|
||||
return inferStaticsInRange(c, fRange, a)
|
||||
elif c.c.matchedConcept != nil and aRange.rangeHasUnresolvedStatic:
|
||||
@@ -1692,7 +1693,8 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
if aAsObject.kind == tyObject and trIsOutParam notin flags:
|
||||
let baseType = aAsObject.base
|
||||
if baseType != nil:
|
||||
inc c.inheritancePenalty, 1 + int(c.inheritancePenalty < 0)
|
||||
if tfFinal notin aAsObject.flags:
|
||||
inc c.inheritancePenalty, 1 + int(c.inheritancePenalty < 0)
|
||||
let ret = typeRel(c, f, baseType, flags)
|
||||
return if ret in {isEqual,isGeneric}: isSubtype else: ret
|
||||
|
||||
@@ -1733,6 +1735,10 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
let tr = typeRel(c, f[i], x[i], flags)
|
||||
if tr <= isSubtype: return
|
||||
result = isGeneric
|
||||
let impl = last(f[0])
|
||||
if impl.kind == tyObject and tfFinal notin impl.flags:
|
||||
# match non-invocation case
|
||||
inc c.inheritancePenalty, 0 + int(c.inheritancePenalty < 0)
|
||||
elif x.kind == tyGenericInst and f[0] == x[0] and
|
||||
x.len - 1 == f.len:
|
||||
for i in 1..<f.len:
|
||||
@@ -1789,7 +1795,8 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
depth = -1
|
||||
|
||||
if depth >= 0:
|
||||
inc c.inheritancePenalty, depth + int(c.inheritancePenalty < 0)
|
||||
if aobj.kind == tyObject and tfFinal notin aobj.flags:
|
||||
inc c.inheritancePenalty, depth + int(c.inheritancePenalty < 0)
|
||||
# bug #4863: We still need to bind generic alias crap, so
|
||||
# we cannot return immediately:
|
||||
result = if depth == 0: isGeneric else: isSubtype
|
||||
@@ -2251,7 +2258,7 @@ proc isLValue(c: PContext; n: PNode, isOutParam = false): bool {.inline.} =
|
||||
result = c.inUncheckedAssignSection > 0
|
||||
of arAddressableConst:
|
||||
let sym = getRoot(n)
|
||||
result = noStrictDefs notin c.config.legacyFeatures and sym != nil and sym.kind == skLet and isOutParam
|
||||
result = strictDefs in c.features and sym != nil and sym.kind == skLet and isOutParam
|
||||
else:
|
||||
result = false
|
||||
|
||||
|
||||
@@ -106,6 +106,13 @@ proc transformSons(c: PTransf, n: PNode, noConstFold = false): PNode =
|
||||
for i in 0..<n.len:
|
||||
result[i] = transform(c, n[i], noConstFold)
|
||||
|
||||
proc transformSonsAfterType(c: PTransf, n: PNode, noConstFold = false): PNode =
|
||||
result = newTransNode(n)
|
||||
assert n.len != 0
|
||||
result[0] = copyTree(n[0])
|
||||
for i in 1..<n.len:
|
||||
result[i] = transform(c, n[i], noConstFold)
|
||||
|
||||
proc newAsgnStmt(c: PTransf, kind: TNodeKind, le: PNode, ri: PNode; isFirstWrite: bool): PNode =
|
||||
result = newTransNode(kind, ri.info, 2)
|
||||
result[0] = le
|
||||
@@ -1102,6 +1109,9 @@ proc transform(c: PTransf, n: PNode, noConstFold = false): PNode =
|
||||
result = transformAddrDeref(c, n, {nkAddr, nkHiddenAddr})
|
||||
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
|
||||
result = transformConv(c, n)
|
||||
of nkObjConstr, nkCast:
|
||||
# don't try to transform type node
|
||||
result = transformSonsAfterType(c, n)
|
||||
of nkDiscardStmt:
|
||||
result = n
|
||||
if n[0].kind != nkEmpty:
|
||||
|
||||
@@ -1485,8 +1485,17 @@ proc commonSuperclass*(a, b: PType): PType =
|
||||
y = y.baseClass
|
||||
|
||||
proc lacksMTypeField*(typ: PType): bool {.inline.} =
|
||||
## Returns true if the type is an object that lacks a m_type field.
|
||||
## It doesn't check base classes.
|
||||
(typ.sym != nil and sfPure in typ.sym.flags) or tfFinal in typ.flags
|
||||
|
||||
proc isObjLackingTypeField*(typ: PType): bool {.inline.} =
|
||||
## Returns true if the type is an object that lacks a type field.
|
||||
## Object types that store type headers are not final or pure and
|
||||
## have inheritable root types, which are not pure, neither.
|
||||
result = (typ.kind == tyObject) and ((tfFinal in typ.flags) and
|
||||
(typ.baseClass == nil) or isPureObject(typ))
|
||||
|
||||
include sizealignoffsetimpl
|
||||
|
||||
proc computeSize*(conf: ConfigRef; typ: PType): BiggestInt =
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
import semmacrosanity
|
||||
import
|
||||
std/[strutils, tables, parseutils],
|
||||
std/[strutils, tables, intsets, parseutils],
|
||||
msgs, vmdef, vmgen, nimsets, types,
|
||||
parser, vmdeps, idents, trees, renderer, options, transf,
|
||||
gorgeimpl, lineinfos, btrees, macrocacheimpl,
|
||||
@@ -2425,9 +2425,12 @@ proc evalConstExprAux(module: PSym; idgen: IdGenerator;
|
||||
setupGlobalCtx(module, g, idgen)
|
||||
var c = PCtx g.vm
|
||||
let oldMode = c.mode
|
||||
let oldLocals = c.locals
|
||||
c.mode = mode
|
||||
c.locals = initIntSet()
|
||||
c.cannotEval = false
|
||||
let start = genExpr(c, n, requiresValue = mode!=emStaticStmt)
|
||||
c.locals = oldLocals
|
||||
if c.cannotEval:
|
||||
return errorNode(idgen, prc, n)
|
||||
if c.code[start].opcode == opcEof: return newNodeI(nkEmpty, n.info)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
## This module contains the type definitions for the new evaluation engine.
|
||||
## An instruction is 1-3 int32s in memory, it is a register based VM.
|
||||
|
||||
import std/[tables, strutils]
|
||||
import std/[tables, strutils, intsets]
|
||||
|
||||
import ast, idents, options, modulegraphs, lineinfos
|
||||
|
||||
@@ -272,6 +272,7 @@ type
|
||||
vmstateDiff*: seq[(PSym, PNode)] # we remember the "diff" to global state here (feature for IC)
|
||||
procToCodePos*: Table[int, int]
|
||||
cannotEval*: bool
|
||||
locals*: IntSet
|
||||
|
||||
PStackFrame* = ref TStackFrame
|
||||
TStackFrame* {.acyclic.} = object
|
||||
|
||||
@@ -1583,6 +1583,7 @@ proc checkCanEval(c: PCtx; n: PNode) =
|
||||
# are in the right scope:
|
||||
if sfGenSym in s.flags and c.prc.sym == nil: discard
|
||||
elif s.kind == skParam and s.typ.kind == tyTypeDesc: discard
|
||||
elif s.kind in {skVar, skLet} and s.id in c.locals: discard
|
||||
else: cannotEval(c, n)
|
||||
elif s.kind in {skProc, skFunc, skConverter, skMethod,
|
||||
skIterator} and sfForward in s.flags:
|
||||
@@ -1975,7 +1976,7 @@ proc genVarSection(c: PCtx; n: PNode) =
|
||||
c.gen(lowerTupleUnpacking(c.graph, a, c.idgen, c.getOwner))
|
||||
elif a[0].kind == nkSym:
|
||||
let s = a[0].sym
|
||||
checkCanEval(c, a[0])
|
||||
c.locals.incl(s.id)
|
||||
if s.isGlobal:
|
||||
let runtimeAccessToCompileTime = c.mode == emRepl and
|
||||
sfCompileTime in s.flags and s.position > 0
|
||||
@@ -2040,7 +2041,7 @@ proc genArrayConstr(c: PCtx, n: PNode, dest: var TDest) =
|
||||
c.gABx(n, opcLdNull, dest, c.genType(n.typ))
|
||||
|
||||
let intType = getSysType(c.graph, n.info, tyInt)
|
||||
let seqType = n.typ.skipTypes(abstractVar-{tyTypeDesc})
|
||||
let seqType = n.typ.skipTypes(abstractVar+{tyStatic}-{tyTypeDesc})
|
||||
if seqType.kind == tySequence:
|
||||
var tmp = c.getTemp(intType)
|
||||
c.gABx(n, opcLdImmInt, tmp, n.len)
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -21,4 +21,3 @@ when defined(nimStrictMode):
|
||||
# future work: XDeclaredButNotUsed
|
||||
|
||||
switch("define", "nimVersion:" & NimVersion) # deadcode
|
||||
switch("experimental", "strictDefs")
|
||||
|
||||
@@ -129,7 +129,8 @@ other associated resources. Variables are destroyed via this hook when
|
||||
they go out of scope or when the routine they were declared in is about
|
||||
to return.
|
||||
|
||||
A `=destroy` hook is allowed to have a parameter of a `var T` or `T` type. Taking a `var T` type is deprecated. The prototype of this hook for a type `T` needs to be:
|
||||
A `=destroy` hook is allowed to have a parameter of a `var T` or `T` type.
|
||||
The prototype of this hook for a type `T` needs to be:
|
||||
|
||||
```nim
|
||||
proc `=destroy`(x: T)
|
||||
|
||||
@@ -5186,22 +5186,22 @@ caught by reference. Example:
|
||||
proc fn() =
|
||||
let a = initRuntimeError("foo")
|
||||
doAssert $a.what == "foo"
|
||||
var b: cstring
|
||||
var b = ""
|
||||
try: raise initRuntimeError("foo2")
|
||||
except CStdException as e:
|
||||
doAssert e is CStdException
|
||||
b = e.what()
|
||||
doAssert $b == "foo2"
|
||||
b = $e.what()
|
||||
doAssert b == "foo2"
|
||||
|
||||
try: raise initStdException()
|
||||
except CStdException: discard
|
||||
|
||||
try: raise initRuntimeError("foo3")
|
||||
except CRuntimeError as e:
|
||||
b = e.what()
|
||||
b = $e.what()
|
||||
except CStdException:
|
||||
doAssert false
|
||||
doAssert $b == "foo3"
|
||||
doAssert b == "foo3"
|
||||
|
||||
fn()
|
||||
```
|
||||
|
||||
@@ -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
|
||||
|
||||
2
koch.nim
2
koch.nim
@@ -171,7 +171,7 @@ proc bundleAtlasExe(latest: bool, args: string) =
|
||||
cloneDependency(distDir, "https://github.com/nim-lang/atlas.git",
|
||||
commit = commit, allowBundled = true)
|
||||
cloneDependency(distDir / "atlas" / distDir, "https://github.com/nim-lang/sat.git",
|
||||
commit = SatStableCommit, allowBundled = true)
|
||||
commit = SatStableCommit, allowBundled = true)
|
||||
# installer.ini expects it under $nim/bin
|
||||
nimCompile("dist/atlas/src/atlas.nim",
|
||||
options = "-d:release --noNimblePath -d:nimAtlasBootstrap " & args)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -33,7 +33,7 @@ runnableExamples:
|
||||
{.push checks: off, line_dir: off, stack_trace: off, debugger: off.}
|
||||
# the user does not want to trace a part of the standard library!
|
||||
|
||||
import std/[math, strformat]
|
||||
import std/[math, strformat, strutils]
|
||||
|
||||
type
|
||||
Complex*[T: SomeFloat] = object
|
||||
|
||||
@@ -105,7 +105,7 @@ when not defined(js) and not defined(nimscript): # C
|
||||
when compileOption("overflowChecks"):
|
||||
if y == 0:
|
||||
raise new(DivByZeroDefect)
|
||||
elif (x == T.low and y == -1.T):
|
||||
elif (x == T.low and int64(y) == -1):
|
||||
raise new(OverflowDefect)
|
||||
let res = divmod_c(x, y)
|
||||
result[0] = res.quot
|
||||
@@ -1145,6 +1145,37 @@ func prod*[T](x: openArray[T]): T =
|
||||
result = T(1)
|
||||
for i in items(x): result = result * i
|
||||
|
||||
func cumprod*[T](x: var openArray[T]) =
|
||||
## Transforms ``x`` in-place (must be declared as `var`) into its
|
||||
## product.
|
||||
##
|
||||
## See also:
|
||||
## * `prod proc <#sum,openArray[T]>`_
|
||||
## * `cumproded proc <#cumproded,openArray[T]>`_ for a version which
|
||||
## returns cumproded sequence
|
||||
runnableExamples:
|
||||
var a = [1, 2, 3, 4]
|
||||
cumprod(a)
|
||||
doAssert a == @[1, 2, 6, 24]
|
||||
for i in 1 ..< x.len: x[i] = x[i-1] * x[i]
|
||||
|
||||
func cumproded*[T](x: openArray[T]): seq[T] =
|
||||
## Return cumulative (aka prefix) product of ``x``.
|
||||
##
|
||||
## See also:
|
||||
## * `prod proc <#prod,openArray[T]>`_
|
||||
## * `cumprod proc <#cumprod,openArray[T]>`_ for the in-place version
|
||||
runnableExamples:
|
||||
let a = [1, 2, 3, 4]
|
||||
doAssert cumproded(a) == @[1, 2, 6, 24]
|
||||
result = @[]
|
||||
let xLen = x.len
|
||||
if xLen == 0:
|
||||
return @[]
|
||||
result.setLen(xLen)
|
||||
result[0] = x[0]
|
||||
for i in 1 ..< xLen: result[i] = result[i-1] * x[i]
|
||||
|
||||
func cumsummed*[T](x: openArray[T]): seq[T] =
|
||||
## Returns the cumulative (aka prefix) summation of `x`.
|
||||
##
|
||||
@@ -1353,3 +1384,4 @@ func lcm*[T](x: openArray[T]): T {.since: (1, 1).} =
|
||||
result = x[0]
|
||||
for i in 1 ..< x.len:
|
||||
result = lcm(result, x[i])
|
||||
|
||||
|
||||
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)
|
||||
|
||||
@@ -109,7 +109,7 @@ import std/private/since
|
||||
import std/exitprocs
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
import std/[assertions, syncio]
|
||||
|
||||
import std/[macros, strutils, streams, times, sets, sequtils]
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -110,6 +110,10 @@ when defined(js):
|
||||
}
|
||||
if (Number.isSafeInteger(`a`))
|
||||
`result` = `a` === 0 && 1 / `a` < 0 ? "-0.0" : `a`+".0";
|
||||
else if (isNaN(`a`)) // Number.isNaN is since ES6
|
||||
`result` = "nan"; // or it'll be "NaN"
|
||||
else if (!isFinite(`a`)) // Number.isFinite newer but unnecessary here
|
||||
`result` = `a` > 0 ? "inf" : "-inf"; // or it'll be [-]Infinity
|
||||
else {
|
||||
`result` = `a`+"";
|
||||
if(nimOnlyDigitsOrMinus(`result`)){
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -2965,14 +2965,16 @@ when notJSnotNims and not defined(nimSeqsV2):
|
||||
assert y == "abcgh"
|
||||
discard
|
||||
|
||||
proc arrayWith*[T](y: T, size: static int): array[size, T] {.raises: [].} =
|
||||
proc arrayWith*[T](y: T, size: static int): array[size, T] {.noinit, nodestroy, raises: [].} =
|
||||
## Creates a new array filled with `y`.
|
||||
result = zeroDefault(array[size, T])
|
||||
for i in 0..size-1:
|
||||
result[i] = y
|
||||
when (NimMajor, NimMinor, NimPatch) >= (2, 3, 1):
|
||||
result[i] = `=dup`(y)
|
||||
else:
|
||||
wasMoved(result[i])
|
||||
`=copy`(result[i], y)
|
||||
|
||||
proc arrayWithDefault*[T](size: static int): array[size, T] {.raises: [].} =
|
||||
proc arrayWithDefault*[T](size: static int): array[size, T] {.noinit, nodestroy, raises: [].} =
|
||||
## Creates a new array filled with `default(T)`.
|
||||
result = zeroDefault(array[size, T])
|
||||
for i in 0..size-1:
|
||||
result[i] = default(T)
|
||||
|
||||
@@ -87,6 +87,9 @@ else:
|
||||
template count(x: Cell): untyped =
|
||||
x.rc shr rcShift
|
||||
|
||||
when not defined(nimHasQuirky):
|
||||
{.pragma: quirky.}
|
||||
|
||||
proc nimNewObj(size, alignment: int): pointer {.compilerRtl.} =
|
||||
let hdrSize = align(sizeof(RefHeader), alignment)
|
||||
let s = size + hdrSize
|
||||
@@ -190,7 +193,7 @@ proc nimRawDispose(p: pointer, alignment: int) {.compilerRtl.} =
|
||||
template `=dispose`*[T](x: owned(ref T)) = nimRawDispose(cast[pointer](x), T.alignOf)
|
||||
#proc dispose*(x: pointer) = nimRawDispose(x)
|
||||
|
||||
proc nimDestroyAndDispose(p: pointer) {.compilerRtl, raises: [].} =
|
||||
proc nimDestroyAndDispose(p: pointer) {.compilerRtl, quirky, raises: [].} =
|
||||
let rti = cast[ptr PNimTypeV2](p)
|
||||
if rti.destructor != nil:
|
||||
cast[DestructorProc](rti.destructor)(p)
|
||||
|
||||
@@ -144,8 +144,11 @@ proc grow*[T](x: var seq[T]; newLen: Natural; value: T) {.nodestroy.} =
|
||||
xu.p = cast[typeof(xu.p)](prepareSeqAddUninit(oldLen, xu.p, newLen - oldLen, sizeof(T), alignof(T)))
|
||||
xu.len = newLen
|
||||
for i in oldLen .. newLen-1:
|
||||
wasMoved(xu.p.data[i])
|
||||
`=copy`(xu.p.data[i], value)
|
||||
when (NimMajor, NimMinor, NimPatch) >= (2, 3, 1):
|
||||
xu.p.data[i] = `=dup`(value)
|
||||
else:
|
||||
wasMoved(xu.p.data[i])
|
||||
`=copy`(xu.p.data[i], value)
|
||||
|
||||
proc add*[T](x: var seq[T]; y: sink T) {.magic: "AppendSeqElem", noSideEffect, nodestroy.} =
|
||||
## Generic proc for adding a data item `y` to a container `x`.
|
||||
|
||||
@@ -112,9 +112,10 @@ proc nimToCStringConv(s: NimStringV2): cstring {.compilerproc, nonReloadable, in
|
||||
|
||||
proc appendString(dest: var NimStringV2; src: NimStringV2) {.compilerproc, inline.} =
|
||||
if src.len > 0:
|
||||
# also copy the \0 terminator:
|
||||
copyMem(unsafeAddr dest.p.data[dest.len], unsafeAddr src.p.data[0], src.len+1)
|
||||
# don't copy the \0 terminator:
|
||||
copyMem(unsafeAddr dest.p.data[dest.len], unsafeAddr src.p.data[0], src.len)
|
||||
inc dest.len, src.len
|
||||
dest.p.data[dest.len] = '\0'
|
||||
|
||||
proc appendChar(dest: var NimStringV2; c: char) {.compilerproc, inline.} =
|
||||
dest.p.data[dest.len] = c
|
||||
|
||||
@@ -300,7 +300,7 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, elemAlign, newLen: int): PGenericS
|
||||
zeroMem(dataPointer(result, elemAlign, elemSize, newLen), (result.len-%newLen) *% elemSize)
|
||||
result.len = newLen
|
||||
|
||||
proc setLengthSeqV2(s: PGenericSeq, typ: PNimType, newLen: int): PGenericSeq {.
|
||||
proc setLengthSeqV2(s: PGenericSeq, typ: PNimType, newLen: int, isTrivial: bool): PGenericSeq {.
|
||||
compilerRtl.} =
|
||||
sysAssert typ.kind == tySequence, "setLengthSeqV2: type is not a seq"
|
||||
if s == nil:
|
||||
@@ -334,7 +334,8 @@ proc setLengthSeqV2(s: PGenericSeq, typ: PNimType, newLen: int): PGenericSeq {.
|
||||
# presence of user defined destructors, the user will expect the cell to be
|
||||
# "destroyed" thus creating the same problem. We can destroy the cell in the
|
||||
# finalizer of the sequence, but this makes destruction non-deterministic.
|
||||
zeroMem(dataPointer(result, elemAlign, elemSize, newLen), (result.len-%newLen) *% elemSize)
|
||||
if not isTrivial: # optimization for trivial types
|
||||
zeroMem(dataPointer(result, elemAlign, elemSize, newLen), (result.len-%newLen) *% elemSize)
|
||||
else:
|
||||
result = s
|
||||
zeroMem(dataPointer(result, elemAlign, elemSize, result.len), (newLen-%result.len) *% elemSize)
|
||||
|
||||
@@ -16,6 +16,8 @@ import ../compiler / [idents, llstream, ast, msgs, syntaxes, options, pathutils,
|
||||
|
||||
import parseopt, strutils, os, sequtils
|
||||
|
||||
import std/tempfiles
|
||||
|
||||
const
|
||||
Version = "0.2"
|
||||
Usage = "nimpretty - Nim Pretty Printer Version " & Version & """
|
||||
@@ -26,6 +28,7 @@ Usage:
|
||||
Options:
|
||||
--out:file set the output file (default: overwrite the input file)
|
||||
--outDir:dir set the output dir (default: overwrite the input files)
|
||||
--stdin read input from stdin and write output to stdout
|
||||
--indent:N[=0] set the number of spaces that is used for indentation
|
||||
--indent:0 means autodetection (default behaviour)
|
||||
--maxLineLen:N set the desired maximum line length (default: 80)
|
||||
@@ -84,7 +87,7 @@ proc finalCheck(content: string; origAst: PNode): bool {.nimcall.} =
|
||||
closeParser(parser)
|
||||
result = conf.errorCounter == oldErrors # and goodEnough(newAst, origAst)
|
||||
|
||||
proc prettyPrint*(infile, outfile: string, opt: PrettyOptions) =
|
||||
proc prettyPrint*(infile, outfile: string; opt: PrettyOptions) =
|
||||
var conf = newConfigRef()
|
||||
let fileIdx = fileInfoIdx(conf, AbsoluteFile infile)
|
||||
let f = splitFile(outfile.expandTilde)
|
||||
@@ -99,12 +102,28 @@ proc prettyPrint*(infile, outfile: string, opt: PrettyOptions) =
|
||||
when defined(nimpretty):
|
||||
closeEmitter(parser.em, fullAst, finalCheck)
|
||||
|
||||
proc handleStdinInput(opt: PrettyOptions) =
|
||||
var content = readAll(stdin)
|
||||
|
||||
var (cfile, path) = createTempFile("nimpretty_", ".nim")
|
||||
|
||||
writeFile(path, content)
|
||||
|
||||
prettyPrint(path, path, opt)
|
||||
|
||||
echo(readAll(cfile))
|
||||
|
||||
close(cfile)
|
||||
removeFile(path)
|
||||
|
||||
proc main =
|
||||
var outfile, outdir: string
|
||||
|
||||
var infiles = newSeq[string]()
|
||||
var outfiles = newSeq[string]()
|
||||
|
||||
var isStdin = false
|
||||
|
||||
var backup = false
|
||||
# when `on`, create a backup file of input in case
|
||||
# `prettyPrint` could overwrite it (note that the backup may happen even
|
||||
@@ -112,7 +131,6 @@ proc main =
|
||||
# --backup was un-documented (rely on git instead).
|
||||
var opt = PrettyOptions(indWidth: 0, maxLineLen: 80)
|
||||
|
||||
|
||||
for kind, key, val in getopt():
|
||||
case kind
|
||||
of cmdArgument:
|
||||
@@ -132,8 +150,15 @@ proc main =
|
||||
of "outDir", "outdir": outdir = val
|
||||
of "indent": opt.indWidth = parseInt(val)
|
||||
of "maxlinelen": opt.maxLineLen = parseInt(val)
|
||||
# "" is equal to '-' as input
|
||||
of "stdin", "": isStdin = true
|
||||
else: writeHelp()
|
||||
of cmdEnd: assert(false) # cannot happen
|
||||
|
||||
if isStdin:
|
||||
handleStdinInput(opt)
|
||||
return
|
||||
|
||||
if infiles.len == 0:
|
||||
quit "[Error] no input file."
|
||||
|
||||
|
||||
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
|
||||
"""
|
||||
|
||||
@@ -33,6 +33,7 @@ copying
|
||||
123
|
||||
42
|
||||
@["", "d", ""]
|
||||
mutate: 1
|
||||
ok
|
||||
destroying variable: 20
|
||||
destroying variable: 10
|
||||
@@ -882,3 +883,18 @@ proc test_18070() = # bug #18070
|
||||
doAssert msg == "", "expected empty string but got: " & $msg
|
||||
|
||||
test_18070()
|
||||
|
||||
type AnObject = tuple
|
||||
a: string
|
||||
b: int
|
||||
c: int
|
||||
|
||||
proc mutate(a: sink AnObject) =
|
||||
`=wasMoved`(a)
|
||||
echo "mutate: 1"
|
||||
|
||||
# echo "Value is: ", obj.value
|
||||
proc bar =
|
||||
mutate(("1.2", 0, 0))
|
||||
|
||||
bar()
|
||||
|
||||
24
tests/arc/tnodestroyexplicithook.nim
Normal file
24
tests/arc/tnodestroyexplicithook.nim
Normal file
@@ -0,0 +1,24 @@
|
||||
discard """
|
||||
ccodecheck: "'Result[(i_1 - 0)] = eqdup'"
|
||||
"""
|
||||
|
||||
# issue #24626
|
||||
|
||||
proc arrayWith2[T](y: T, size: static int): array[size, T] {.noinit, nodestroy, raises: [].} =
|
||||
## Creates a new array filled with `y`.
|
||||
for i in 0..size-1:
|
||||
when defined(nimHasDup):
|
||||
result[i] = `=dup`(y)
|
||||
else:
|
||||
wasMoved(result[i])
|
||||
`=copy`(result[i], y)
|
||||
|
||||
proc useArray(x: seq[int]) =
|
||||
var a = arrayWith2(x, 2)
|
||||
|
||||
proc main =
|
||||
let x = newSeq[int](100)
|
||||
for i in 0..5:
|
||||
useArray(x)
|
||||
|
||||
main()
|
||||
16
tests/arc/tvalgrind.nim
Normal file
16
tests/arc/tvalgrind.nim
Normal file
@@ -0,0 +1,16 @@
|
||||
discard """
|
||||
cmd: "nim c --mm:orc -d:useMalloc $file"
|
||||
valgrind: "true"
|
||||
"""
|
||||
|
||||
import std/streams
|
||||
|
||||
|
||||
proc foo() =
|
||||
var name = newStringStream("2r2")
|
||||
raise newException(ValueError, "sh")
|
||||
|
||||
try:
|
||||
foo()
|
||||
except:
|
||||
discard
|
||||
@@ -1,7 +1,7 @@
|
||||
discard """
|
||||
matrix: "--mm:refc"
|
||||
output: "Hello"
|
||||
ccodecheck: "\\i@'a = ((NimStringDesc*) NIM_NIL)'"
|
||||
ccodecheck: "\\i@'a_1 = ((NimStringDesc*) NIM_NIL)'"
|
||||
"""
|
||||
|
||||
proc main() =
|
||||
|
||||
@@ -161,3 +161,21 @@ typedef struct { int base; } S;
|
||||
|
||||
var t = newT()
|
||||
doAssert t.s.base == 1
|
||||
|
||||
type QObject* {.inheritable, pure.} = object
|
||||
h*: pointer
|
||||
|
||||
proc `=destroy`(self: var QObject) =discard
|
||||
|
||||
proc `=copy`(dest: var QObject, source: QObject) {.error.}
|
||||
|
||||
type QAbstractItemModel* = object of QObject
|
||||
|
||||
type VTable = ref object
|
||||
inst: QAbstractItemModel
|
||||
|
||||
proc g() =
|
||||
var x: VTable = VTable()
|
||||
x.inst = QAbstractItemModel()
|
||||
|
||||
g()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
discard """
|
||||
output: "1"
|
||||
cmd: r"nim c --hints:on $options --mm:refc -d:release $file"
|
||||
ccodecheck: "'NI volatile state;'"
|
||||
ccodecheck: "'NI volatile state_1;'"
|
||||
targets: "c"
|
||||
"""
|
||||
|
||||
|
||||
@@ -45,3 +45,14 @@ block: # bug #22354
|
||||
|
||||
|
||||
main()
|
||||
|
||||
proc main = # bug #24677
|
||||
let NULL = 1
|
||||
doAssert NULL == 1
|
||||
|
||||
var COMMA = 1
|
||||
doAssert COMMA == 1
|
||||
|
||||
for NDEBUG in 0..2:
|
||||
doAssert NDEBUG == NDEBUG
|
||||
main()
|
||||
|
||||
@@ -29,6 +29,8 @@ discard """
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE9ContainerI3intE'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE10Container2I5int325int32E'"
|
||||
ccodecheck: "'_ZN14titaniummangle8testFuncE9ContainerI10Container2I5int325int32EE'"
|
||||
ccodecheck: "'_ZN14titaniummangle7xxx_s10E'"
|
||||
ccodecheck: "'_ZN14titaniummangle7xxx_s20E'"
|
||||
"""
|
||||
|
||||
#When debugging this notice that if one check fails, it can be due to any of the above.
|
||||
@@ -151,6 +153,9 @@ proc testFunc(a: int, xs: varargs[string]) =
|
||||
for x in xs:
|
||||
echo x
|
||||
|
||||
proc xxx(v: static int) =
|
||||
echo v
|
||||
|
||||
proc testFunc() =
|
||||
var a = 2
|
||||
var aPtr = a.addr
|
||||
@@ -188,6 +193,8 @@ proc testFunc() =
|
||||
let c2 = Container2[int32, int32](data: 10, data2: 20)
|
||||
testFunc(c2)
|
||||
testFunc(Container[Container2[int32, int32]](data: c2))
|
||||
|
||||
xxx(10)
|
||||
xxx(20)
|
||||
|
||||
|
||||
testFunc()
|
||||
@@ -240,3 +240,11 @@ block: # bug #17197
|
||||
result = true
|
||||
|
||||
doAssert needlemanWunsch("ABC", "DEFG", 1, 2, 3)
|
||||
|
||||
block: # bug #12340
|
||||
func consume(x: sink seq[int]) =
|
||||
x[0] += 5
|
||||
|
||||
let x = @[1, 2, 3, 4]
|
||||
consume x
|
||||
doAssert x == @[1, 2, 3, 4]
|
||||
|
||||
@@ -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(@)".}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
discard """
|
||||
# doesn't work on macos 13 seemingly due to libc++ linking issue https://stackoverflow.com/a/77375947
|
||||
disabled: osx
|
||||
targets: cpp
|
||||
"""
|
||||
|
||||
@@ -18,21 +16,21 @@ proc initStdException(): CStdException {.importcpp: "std::exception()", construc
|
||||
proc fn() =
|
||||
let a = initRuntimeError("foo")
|
||||
doAssert $a.what == "foo"
|
||||
var b: cstring
|
||||
var b = ""
|
||||
try: raise initRuntimeError("foo2")
|
||||
except CStdException as e:
|
||||
doAssert e is CStdException
|
||||
b = e.what()
|
||||
doAssert $b == "foo2"
|
||||
b = $e.what()
|
||||
doAssert b == "foo2"
|
||||
|
||||
try: raise initStdException()
|
||||
except CStdException: discard
|
||||
|
||||
try: raise initRuntimeError("foo3")
|
||||
except CRuntimeError as e:
|
||||
b = e.what()
|
||||
b = $e.what()
|
||||
except CStdException:
|
||||
doAssert false
|
||||
doAssert $b == "foo3"
|
||||
doAssert b == "foo3"
|
||||
|
||||
fn()
|
||||
|
||||
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)
|
||||
9
tests/generics/ttypeofstatic.nim
Normal file
9
tests/generics/ttypeofstatic.nim
Normal file
@@ -0,0 +1,9 @@
|
||||
# issue #24715
|
||||
|
||||
type H[c: static[float64]] = object
|
||||
value: typeof(c)
|
||||
|
||||
proc u[T: H](_: typedesc[T]) =
|
||||
discard default(T)
|
||||
|
||||
u(H[1'f64])
|
||||
@@ -1,5 +1,4 @@
|
||||
discard """
|
||||
matrix: "--legacy:nostrictdefs"
|
||||
joinable: false
|
||||
"""
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
discard """
|
||||
action: compile
|
||||
disabled: "windows"
|
||||
disabled: osx
|
||||
"""
|
||||
|
||||
import sfml, os
|
||||
|
||||
21
tests/overload/tgenericrangedisamb.nim
Normal file
21
tests/overload/tgenericrangedisamb.nim
Normal file
@@ -0,0 +1,21 @@
|
||||
# issue #24708
|
||||
|
||||
type Matrix[m, n: static int] = array[m * n, float]
|
||||
|
||||
func `[]`(A: Matrix, i, j: int): float =
|
||||
A[A.n * i + j]
|
||||
|
||||
func `[]`(A: var Matrix, i, j: int): var float =
|
||||
A[A.n * i + j]
|
||||
|
||||
func `*`[m, n, p: static int](A: Matrix[m, n], B: Matrix[n, p]): Matrix[m, p] =
|
||||
for i in 0 ..< m:
|
||||
for k in 0 ..< p:
|
||||
for j in 0 ..< n:
|
||||
result[i, k] += A[i, j] * B[j, k]
|
||||
|
||||
func square[n: static int](A: Matrix[n, n]): Matrix[n, n] =
|
||||
A * A
|
||||
|
||||
let A: Matrix[2, 2] = [-1, 1, 0, -1]
|
||||
doAssert square(A) == [1.0, -2.0, 0.0, 1.0]
|
||||
16
tests/pragmas/tparamcustompragma.nim
Normal file
16
tests/pragmas/tparamcustompragma.nim
Normal file
@@ -0,0 +1,16 @@
|
||||
discard """
|
||||
nimout: '''
|
||||
proc foo(a {.attr.}: int) =
|
||||
discard
|
||||
|
||||
'''
|
||||
"""
|
||||
|
||||
# fixes #24702
|
||||
|
||||
import macros
|
||||
template attr*() {.pragma.}
|
||||
proc foo(a {.attr.}: int) = discard
|
||||
macro showImpl(a: typed) =
|
||||
echo repr getImpl(a)
|
||||
showImpl(foo)
|
||||
@@ -2,7 +2,7 @@ discard """
|
||||
matrix: "--mm:refc; --mm:orc"
|
||||
"""
|
||||
|
||||
import std/[complex, math]
|
||||
import std/[complex, math, strformat, formatfloat]
|
||||
import std/assertions
|
||||
|
||||
proc `=~`[T](x, y: Complex[T]): bool =
|
||||
@@ -113,3 +113,7 @@ doAssert 123.0.im + 456.0 == complex64(456, 123)
|
||||
|
||||
let localA = complex(0.1'f32)
|
||||
doAssert localA.im is float32
|
||||
|
||||
block: # bug #24666
|
||||
let z = complex64(1, 2)
|
||||
doAssert fmt"{z}" == "(1.0, 2.0)"
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
discard """
|
||||
matrix: "--mm:orc; --mm:refc"
|
||||
matrix: "--mm:orc"
|
||||
"""
|
||||
|
||||
# TODO: --mm:refc
|
||||
|
||||
import std/marshal
|
||||
import std/[assertions, objectdollar, streams]
|
||||
|
||||
|
||||
@@ -245,6 +245,25 @@ template main() =
|
||||
empty.cumsum
|
||||
doAssert empty == @[]
|
||||
|
||||
block: # cumprod
|
||||
block: #cumprod int seq return
|
||||
let counts = [ 1, 2, 3, 4 ]
|
||||
doAssert counts.cumproded == [ 1, 2, 6, 24 ]
|
||||
|
||||
block: # cumprod float seq return
|
||||
let counts = [ 1.0, 2.0, 3.0, 4.0 ]
|
||||
doAssert counts.cumproded == [ 1.0, 2.0, 6.0, 24.0 ]
|
||||
|
||||
block: # cumprod int in-place
|
||||
var counts = [ 1, 2, 3, 4 ]
|
||||
counts.cumprod
|
||||
doAssert counts == [ 1, 2, 6, 24 ]
|
||||
|
||||
block: # cumprod float in-place
|
||||
var counts = [ 1.0, 2.0, 3.0, 4.0 ]
|
||||
counts.cumprod
|
||||
doAssert counts == [ 1.0, 2.0, 6.0, 24.0 ]
|
||||
|
||||
block: # ^ compiles for valid types
|
||||
doAssert: compiles(5 ^ 2)
|
||||
doAssert: compiles(5.5 ^ 2)
|
||||
@@ -525,3 +544,9 @@ when not defined(js) and not defined(danger):
|
||||
|
||||
doAssertRaises(OverflowDefect):
|
||||
discard sum(x)
|
||||
|
||||
block: # bug #24673
|
||||
let x: Natural = 5
|
||||
let y: Natural = 3
|
||||
|
||||
doAssert divmod(x, y) == (Natural 1, Natural 2)
|
||||
|
||||
@@ -37,3 +37,30 @@ block: # bug #16771
|
||||
a.foo b
|
||||
doAssert a.n == 42
|
||||
doAssert b.n == 1
|
||||
|
||||
block: # bug #24683
|
||||
block:
|
||||
var v = newSeq[int](100)
|
||||
v[99]= 444
|
||||
v.setLen(5)
|
||||
v.setLen(100)
|
||||
doAssert v[99] == 0
|
||||
|
||||
when not defined(js):
|
||||
block:
|
||||
var
|
||||
x = @[1, 2, 3, 4, 45, 56, 67, 999, 88, 777]
|
||||
|
||||
x.setLen(0) # zero-fills 1mb of released data
|
||||
|
||||
type
|
||||
TGenericSeq = object
|
||||
len, reserved: int
|
||||
PGenericSeq = ptr TGenericSeq
|
||||
|
||||
when defined(gcRefc):
|
||||
cast[PGenericSeq](x).len = 10
|
||||
else:
|
||||
cast[ptr int](addr x)[] = 10
|
||||
|
||||
doAssert x == @[1, 2, 3, 4, 45, 56, 67, 999, 88, 777]
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -13,3 +13,8 @@ block:
|
||||
type _ = float
|
||||
doAssert not (compiles do:
|
||||
let x: _ = 3)
|
||||
|
||||
block: # bug #24339
|
||||
const r = (0, 0)
|
||||
for _ in r.fields:
|
||||
let _ = 0
|
||||
|
||||
14
tests/system/t24664.nim
Normal file
14
tests/system/t24664.nim
Normal file
@@ -0,0 +1,14 @@
|
||||
discard """
|
||||
output: '''
|
||||
TestString123TestString123
|
||||
TestString123TestString123
|
||||
'''
|
||||
"""
|
||||
|
||||
proc foostring() = # bug #24664
|
||||
for i in 0..1:
|
||||
var s = "TestString123"
|
||||
s.add s
|
||||
echo s
|
||||
|
||||
foostring()
|
||||
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()
|
||||
15
tests/template/tgenericobjconstr.nim
Normal file
15
tests/template/tgenericobjconstr.nim
Normal file
@@ -0,0 +1,15 @@
|
||||
discard """
|
||||
matrix: "--skipParentCfg"
|
||||
"""
|
||||
|
||||
# issue #24631
|
||||
|
||||
type
|
||||
V[d: static bool] = object
|
||||
l: int
|
||||
|
||||
template y(): V[false] = V[false](l: 0)
|
||||
discard y()
|
||||
|
||||
template z(): V[false] = cast[V[false]](V[false](l: 0))
|
||||
discard z()
|
||||
13
tests/tuples/tconstfield.nim
Normal file
13
tests/tuples/tconstfield.nim
Normal file
@@ -0,0 +1,13 @@
|
||||
# issue #24698
|
||||
|
||||
type Point = tuple[x, y: int]
|
||||
|
||||
const Origin: Point = (0, 0)
|
||||
|
||||
import macros
|
||||
|
||||
template next(point: Point): Point =
|
||||
(point.x + 1, point.y + 1)
|
||||
|
||||
discard Origin.x # OK: the field is visible.
|
||||
discard next(Origin) # Compilation error: the field is not visible.
|
||||
18
tests/tuples/ttupleconverter.nim
Normal file
18
tests/tuples/ttupleconverter.nim
Normal file
@@ -0,0 +1,18 @@
|
||||
# issue #24609
|
||||
|
||||
import std/options
|
||||
|
||||
type
|
||||
Config* = object
|
||||
bits*: tuple[r, g, b, a: Option[int32]]
|
||||
|
||||
# works on 2.0.8
|
||||
#
|
||||
# results in error on 2.2.0
|
||||
# type mismatch: got 'int literal(8)' for '8' but expected 'Option[system.int32]'
|
||||
#
|
||||
converter toInt32Tuple*(t: tuple[r,g,b,a: int]): tuple[r,g,b,a: Option[int32]] =
|
||||
(some(t.r.int32), some(t.g.int32), some(t.b.int32), some(t.a.int32))
|
||||
|
||||
var cfg: Config
|
||||
cfg.bits = (r: 8, g: 8, b: 8, a: 16)
|
||||
79
tests/vm/tconststaticvar.nim
Normal file
79
tests/vm/tconststaticvar.nim
Normal file
@@ -0,0 +1,79 @@
|
||||
block: # issue #8758
|
||||
template baz() =
|
||||
var i = 0
|
||||
|
||||
proc foo() =
|
||||
static:
|
||||
var i = 0
|
||||
baz()
|
||||
|
||||
block: # issue #10828
|
||||
proc test(i: byte): bool =
|
||||
const SET = block: # No issues when defined outside proc
|
||||
var s: set[byte]
|
||||
for i in 0u8 .. 255u8: incl(s, i)
|
||||
s
|
||||
return i in SET
|
||||
doAssert test(0)
|
||||
doAssert test(127)
|
||||
doAssert test(255)
|
||||
|
||||
block: # issue #12172
|
||||
const TEST = block:
|
||||
var test: array[5, string]
|
||||
for i in low(test)..high(test):
|
||||
test[i] = $i
|
||||
test
|
||||
proc test =
|
||||
const TEST2 = block:
|
||||
var test: array[5, string] # Error here
|
||||
for i in low(test)..high(test):
|
||||
test[i] = $i
|
||||
test
|
||||
doAssert TEST == TEST2
|
||||
doAssert TEST == @["0", "1", "2", "3", "4"]
|
||||
doAssert TEST2 == @["0", "1", "2", "3", "4"]
|
||||
test()
|
||||
|
||||
block: # issue #21610
|
||||
func stuff(): int =
|
||||
const r = block:
|
||||
var r = 1 # Error: cannot evaluate at compile time: r
|
||||
for i in 2..10:
|
||||
r *= i
|
||||
r
|
||||
r
|
||||
doAssert stuff() == 3628800
|
||||
|
||||
block: # issue #23803
|
||||
func foo1(c: int): int {.inline.} =
|
||||
const arr = block:
|
||||
var res: array[0..99, int]
|
||||
res[42] = 43
|
||||
res
|
||||
arr[c]
|
||||
doAssert foo1(41) == 0
|
||||
doAssert foo1(42) == 43
|
||||
doAssert foo1(43) == 0
|
||||
|
||||
# works
|
||||
func foo2(c: int): int {.inline.} =
|
||||
func initArr(): auto =
|
||||
var res: array[0..99, int]
|
||||
res[42] = 43
|
||||
res
|
||||
const arr = initArr()
|
||||
arr[c]
|
||||
doAssert foo2(41) == 0
|
||||
doAssert foo2(42) == 43
|
||||
doAssert foo2(43) == 0
|
||||
|
||||
# also works
|
||||
const globalArr = block:
|
||||
var res: array[0..99, int]
|
||||
res[42] = 43
|
||||
res
|
||||
func foo3(c: int): int {.inline.} = globalArr[c]
|
||||
doAssert foo3(41) == 0
|
||||
doAssert foo3(42) == 43
|
||||
doAssert foo3(43) == 0
|
||||
13
tests/vm/tconststaticvar2.nim
Normal file
13
tests/vm/tconststaticvar2.nim
Normal file
@@ -0,0 +1,13 @@
|
||||
# issue #24634
|
||||
|
||||
type J = object
|
||||
|
||||
template m(u: J): int =
|
||||
let v = u
|
||||
0
|
||||
|
||||
proc g() =
|
||||
const x = J()
|
||||
const _ = m(x)
|
||||
|
||||
g()
|
||||
9
tests/vm/tconststaticvar3.nim
Normal file
9
tests/vm/tconststaticvar3.nim
Normal file
@@ -0,0 +1,9 @@
|
||||
# issue #24633
|
||||
|
||||
import std/sequtils
|
||||
|
||||
proc f(a: static openArray[int]) =
|
||||
const s1 = a.mapIt(it)
|
||||
const s2 = a.toSeq()
|
||||
|
||||
f([1,2,3])
|
||||
6
tests/vm/tconststaticvar_wrong.nim
Normal file
6
tests/vm/tconststaticvar_wrong.nim
Normal file
@@ -0,0 +1,6 @@
|
||||
proc test =
|
||||
const TEST = block:
|
||||
let i = 1
|
||||
const j = i + 1 #[tt.Error
|
||||
^ cannot evaluate at compile time: i]#
|
||||
j
|
||||
@@ -87,3 +87,12 @@ block: # bug #22095
|
||||
z = fn()
|
||||
|
||||
doAssert z.limbs[0] == 10
|
||||
|
||||
block: # bug #24630
|
||||
func f(a: static openArray[int]): int =
|
||||
12
|
||||
|
||||
func g(a: static openArray[int]) =
|
||||
const b = f(a)
|
||||
|
||||
g(@[1,2,3])
|
||||
|
||||
@@ -4,10 +4,12 @@ import std/private/gitutils
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
proc exec(cmd: string) =
|
||||
proc tryexec(cmd: string): int =
|
||||
echo "deps.cmd: " & cmd
|
||||
let status = execShellCmd(cmd)
|
||||
doAssert status == 0, cmd
|
||||
execShellCmd(cmd)
|
||||
|
||||
proc exec(cmd: string) =
|
||||
doAssert tryexec(cmd) == 0, cmd
|
||||
|
||||
proc execRetry(cmd: string) =
|
||||
let ok = retryCall(call = block:
|
||||
@@ -34,8 +36,10 @@ proc cloneDependency*(destDirBase: string, url: string, commit = commitHead,
|
||||
let oldDir = getCurrentDir()
|
||||
setCurrentDir(destDir)
|
||||
try:
|
||||
execRetry "git fetch -q"
|
||||
exec fmt"git checkout -q {commit}"
|
||||
let checkoutCmd = fmt"git checkout -q {commit}"
|
||||
if tryexec(checkoutCmd) != 0:
|
||||
execRetry "git fetch -q"
|
||||
exec checkoutCmd
|
||||
finally:
|
||||
setCurrentDir(oldDir)
|
||||
elif allowBundled:
|
||||
|
||||
@@ -1,47 +1,501 @@
|
||||
# bash completion for nim -*- shell-script -*-
|
||||
|
||||
__is_short_or_long()
|
||||
{
|
||||
local actual short long
|
||||
actual="$1"
|
||||
short="$2"
|
||||
long="$3"
|
||||
[[ ! -z $short && $actual == $short ]] && return 0
|
||||
[[ ! -z $long && $actual == $long ]] && return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
__ask_for_subcmd_or_subopts()
|
||||
{
|
||||
local args cmd subcmd words sub_words word_first word_last word_lastlast
|
||||
local len ilast ilastlast i ele sub_len n_nopts
|
||||
|
||||
args=("$@")
|
||||
ask_for_what="${args[0]}"
|
||||
cmd="${args[1]}"
|
||||
subcmd="${args[2]}"
|
||||
ilast="${args[3]}"
|
||||
words=("${args[@]:4}")
|
||||
len=${#words[@]}
|
||||
ilastlast=$((ilast - 1))
|
||||
sub_words=("${words[@]:0:ilast}")
|
||||
sub_len=${#sub_words[@]}
|
||||
word_first=${words[0]}
|
||||
word_last=${words[ilast]}
|
||||
word_lastlast=${words[ilastlast]}
|
||||
n_nopts=0
|
||||
|
||||
# printf "\n[DBUG] word_first:${word_first}|ilast:${ilast}|words(${len}):${words[*]}|sub_words(${sub_len}):${sub_words[*]}\n"
|
||||
|
||||
if [[ $word_first != $cmd ]]
|
||||
then
|
||||
return 1
|
||||
fi
|
||||
|
||||
i=0
|
||||
while [[ $i -lt $len ]]
|
||||
do
|
||||
ele=${words[i]}
|
||||
if [[ ! $ele =~ ^- ]]
|
||||
then
|
||||
if [[ $ele == $cmd || $ele == $subcmd ]]
|
||||
then
|
||||
((n_nopts+=1))
|
||||
elif [[ $i -eq $ilast && $ele =~ ^[a-zA-Z] ]]
|
||||
then
|
||||
((i=i))
|
||||
elif [[ -z $ele ]]
|
||||
then
|
||||
((i=i))
|
||||
elif [[ $ele =~ ^: ]]
|
||||
then
|
||||
((i+=1))
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
((i+=1))
|
||||
done
|
||||
|
||||
case $ask_for_what in
|
||||
1)
|
||||
if [[ n_nopts -eq 1 ]]
|
||||
then
|
||||
if [[ -z $word_last || $word_last =~ ^[a-zA-Z] ]] && [[ $word_lastlast != : ]]
|
||||
then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
2)
|
||||
if [[ n_nopts -eq 2 ]]
|
||||
then
|
||||
if [[ -z $word_last ]] || [[ $word_last =~ ^[-:] ]]
|
||||
then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
esac
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
__ask_for_subcmd()
|
||||
{
|
||||
__ask_for_subcmd_or_subopts 1 "$@"
|
||||
}
|
||||
|
||||
__ask_for_subcmd_opts()
|
||||
{
|
||||
__ask_for_subcmd_or_subopts 2 "$@"
|
||||
}
|
||||
|
||||
|
||||
_nim()
|
||||
{
|
||||
local cur prev words cword split
|
||||
_init_completion -s || return
|
||||
local curr prev prevprev words
|
||||
local i_curr n_words i_prev i_prevprev
|
||||
|
||||
COMPREPLY=()
|
||||
i_curr=$COMP_CWORD
|
||||
n_words=$((i_curr+1))
|
||||
i_prev=$((i_curr-1))
|
||||
i_prevprev=$((i_curr-2))
|
||||
curr="${COMP_WORDS[i_curr]}"
|
||||
prev="${COMP_WORDS[i_prev]}"
|
||||
prevprev="${COMP_WORDS[i_prevprev]}"
|
||||
words=("${COMP_WORDS[@]:0:n_words}")
|
||||
|
||||
COMPREPLY=()
|
||||
cur=${COMP_WORDS[COMP_CWORD]}
|
||||
local subcmds opts candids
|
||||
|
||||
if [ $COMP_CWORD -eq 1 ] ; then
|
||||
# first item - suggest commands
|
||||
kw="compile c doc compileToC cc compileToCpp cpp compileToOC objc js e rst2html rst2tex jsondoc buildIndex genDepend dump check"
|
||||
COMPREPLY=( $( compgen -W "${kw}" -- $cur ) )
|
||||
return 0
|
||||
fi
|
||||
case $prev in
|
||||
--stackTrace|--lineTrace|--threads|-x|--checks|--objChecks|--fieldChecks|--rangeChecks|--boundChecks|--overflowChecks|-a|--assertions|--floatChecks|--nanChecks|--infChecks)
|
||||
# Options that require on/off
|
||||
[[ "$cur" == "=" ]] && cur=""
|
||||
COMPREPLY=( $(compgen -W 'on off' -- "$cur") )
|
||||
return 0
|
||||
;;
|
||||
--opt)
|
||||
[[ "$cur" == "=" ]] && cur=""
|
||||
COMPREPLY=( $(compgen -W 'none speed size' -- "$cur") )
|
||||
return 0
|
||||
;;
|
||||
--app)
|
||||
[[ "$cur" == "=" ]] && cur=""
|
||||
COMPREPLY=( $(compgen -W 'console gui lib staticlib' -- "$cur") )
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
kw="-r -p= --path= -d= --define= -u= --undef= -f --forceBuild --opt= --app= --stackTrace= --lineTrace= --threads= -x= --checks= --objChecks= --fieldChecks= --rangeChecks= --boundChecks= --overflowChecks= -a= --assertions= --floatChecks= --nanChecks= --infChecks="
|
||||
COMPREPLY=( $( compgen -W "${kw}" -- $cur ) )
|
||||
_filedir '@(nim)'
|
||||
#$split
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
return 0
|
||||
# printf "\n[DBUG] curr:$curr|prev:$prev|words(${#words[*]}):${words[*]}\n"
|
||||
|
||||
# Asking for a subcommand
|
||||
if __ask_for_subcmd nim nim $i_curr "${words[@]}"
|
||||
then
|
||||
subcmds=""
|
||||
# basic
|
||||
subcmds="${subcmds} compile c"
|
||||
subcmds="${subcmds} r"
|
||||
subcmds="${subcmds} doc"
|
||||
# advanced
|
||||
subcmds="${subcmds} compileToC cc"
|
||||
subcmds="${subcmds} compileToCpp cpp"
|
||||
subcmds="${subcmds} compileToOC objc"
|
||||
subcmds="${subcmds} js"
|
||||
subcmds="${subcmds} e"
|
||||
subcmds="${subcmds} md2html"
|
||||
subcmds="${subcmds} rst2html"
|
||||
subcmds="${subcmds} md2tex"
|
||||
subcmds="${subcmds} rst2tex"
|
||||
subcmds="${subcmds} doc2tex"
|
||||
subcmds="${subcmds} jsondoc"
|
||||
subcmds="${subcmds} ctags"
|
||||
subcmds="${subcmds} buildIndex"
|
||||
subcmds="${subcmds} genDepend"
|
||||
subcmds="${subcmds} dump"
|
||||
subcmds="${subcmds} check"
|
||||
COMPREPLY=( $( compgen -W "${subcmds}" -- ${curr}) )
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Prioritize subcmd over opt
|
||||
if false
|
||||
then
|
||||
return 124
|
||||
|
||||
elif false && __ask_for_subcmd_opts nim compileToC $i_curr "${words[@]}"
|
||||
then # for future use
|
||||
opts=() \
|
||||
&& candids=()
|
||||
opts+=("-u" "--undef" "SYMBOL") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
|
||||
else
|
||||
opts=() \
|
||||
&& candids=()
|
||||
opts+=("-p" "--path" "PATH") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("-d" "--define" "SYMBOL") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
# note, any preceeding left parenthesis will vanish the context
|
||||
opts+=("-u" "--undef" "SYMBOL") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("-f" "--forceBuild" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--stackTrace" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--lineTrace" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--threads" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--checks" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--assertions" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--opt" "none speed size") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--debugger" "native") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--app" "console gui lib staticlib") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("-r" "--run" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--eval" "CMD") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--fullhelp" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("-h" "--help" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("-v" "--version" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--objChecks" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--fieldChecks" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--rangeChecks" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--boundChecks" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--overflowChecks" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--floatChecks" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--nanChecks" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--infChecks" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--defusages" "FILE,LINE,COL") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("-o" "--output" "FILE") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--outdir" "DIR") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--usenimcache" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--stdout" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--colors" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--filenames" "abs canonical legacyRelProj") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--processing" "dots filenames off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--unitsep" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--declaredLocs" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--spellSuggest" "NUM") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--hints" "on off list") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--hint" "HINT:on") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--hintAsError" "HINT:on") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("-w" "--warnings" "on off list") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--warning" "WARNING:on") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--warningAsError" "X:on X:off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--styleCheck" "off hint error") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--showAllMismatches" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--lib" "PATH") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--import" "PATH") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--include" "PATH") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--nimcache" "PATH") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--compileOnly" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--noLinking" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--noMain" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--genScript" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--os" "SYMBOL") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--cpu" "SYMBOL") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--debuginfo" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--passC" "OPTION") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--passL" "OPTION") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--cc" "SYMBOL") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--cincludes" "DIR") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--clibdir" "DIR") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--clib" "LIBNAME") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--project" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--docRoot" "PATH") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--backend" "c cpp js objc") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--docCmd" "CMD") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--docSeeSrcUrl" "URL") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--docInternal" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--lineDir" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--embedsrc" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--tlsEmulation" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--implicitStatic" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--trmacros" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--multimethods" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--hotCodeReloading" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--excessiveStackTrace" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--stackTraceMsgs" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--skipCfg" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--skipUserCfg" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--skipParentCfg" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--skipProjCfg" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--mm" "orc arc refc markAndSweep boehm go none regions") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--exceptions" "setjmp cpp goto quirky") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--index" "on off only") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--noImportdoc" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--putenv" "KEY=VALUE") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--NimblePath" "PATH") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--noNimblePath" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--clearNimblePath" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--cppCompileToNamespace" "NAMESPACE") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--nimMainPrefix" "PREFIX") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--expandMacro" "MACRO") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--expandArc" "PROCNAME") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--excludePath" "PATH") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--dynlibOverride" "SYMBOL") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--dynlibOverrideAll" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--listCmd" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--asm" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--parallelBuild" "N") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--incremental" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--verbosity" "0 1 2 3") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--errorMax" "N") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--maxLoopIterationsVM" "N") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--experimental" "dotOperators callOperator parallel destructor notnil dynamicBindSym forLoopMacros caseStmtMacros codeReordering compiletimeFFI vmopsDanger strictFuncs views strictNotNil overloadableEnums strictEffects unicodeOperators flexibleOptionalParams strictDefs strictCaseObjects inferGenericTypes openSym genericsOpenSym vtables") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--legacy" "allowSemcheckedAstModification checkUnsignedConversions laxEffects verboseTypeMismatch emitGenerics jsNoLambdaLifting") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--benchmarkVM" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--profileVM" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--panics" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--deepcopy" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--jsbigint64" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--nimBasePattern" "nimbase.h") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
fi
|
||||
|
||||
local c_short c_long c_accvals
|
||||
local len i idx0 idx1 idx2
|
||||
|
||||
case $curr in
|
||||
# Asking for accepted optvalues, e.g., `out:`
|
||||
:)
|
||||
len=${#opts[@]}
|
||||
i=0
|
||||
|
||||
while [[ $i -lt $len ]]
|
||||
do
|
||||
idx0=$((i / 3 * 3))
|
||||
idx1=$((idx0 + 1))
|
||||
idx2=$((idx1 + 1))
|
||||
c_short=${opts[idx0]}
|
||||
c_long=${opts[idx1]}
|
||||
c_accvals=${opts[idx2]}
|
||||
(false \
|
||||
|| __is_short_or_long $prev ${c_short} ${c_long} \
|
||||
|| false) \
|
||||
&& COMPREPLY=( $(compgen -W "${c_accvals}" --) ) \
|
||||
&& return 0
|
||||
((i+=3))
|
||||
done
|
||||
|
||||
return 124
|
||||
;;
|
||||
|
||||
*)
|
||||
# When in a incomplete opt value, e.g., `--check:of`
|
||||
if [[ $prev == : ]]
|
||||
then
|
||||
len=${#opts[@]}
|
||||
i=0
|
||||
while [[ $i -lt $len ]]
|
||||
do
|
||||
idx0=$((i / 3 * 3))
|
||||
idx1=$((idx0 + 1))
|
||||
idx2=$((idx1 + 1))
|
||||
c_short=${opts[idx0]}
|
||||
c_long=${opts[idx1]}
|
||||
c_accvals=${opts[idx2]}
|
||||
(false \
|
||||
|| __is_short_or_long $prevprev ${c_short} ${c_long} \
|
||||
|| false) \
|
||||
&& COMPREPLY=( $(compgen -W "${c_accvals}" -- ${curr}) ) \
|
||||
&& return 0
|
||||
((i+=3))
|
||||
done
|
||||
return 124
|
||||
fi
|
||||
|
||||
# When in a complete optname, might need optvalue, e.g., `--check`
|
||||
if [[ $curr =~ ^--?[:()a-zA-Z]+$ ]]
|
||||
then
|
||||
len=${#opts[@]}
|
||||
i=0
|
||||
while [[ $i -lt $len ]]
|
||||
do
|
||||
idx0=$(((i / 3 * 3)))
|
||||
idx1=$((idx0 + 1))
|
||||
idx2=$((idx1 + 1))
|
||||
c_short=${opts[idx0]}
|
||||
c_long=${opts[idx1]}
|
||||
c_accvals=${opts[idx2]}
|
||||
|
||||
if __is_short_or_long $curr ${c_short} ${c_long}
|
||||
then
|
||||
if [[ ! -z $c_accvals ]]
|
||||
then
|
||||
COMPREPLY=( $(compgen -W "${curr}:" -- ${curr}) ) \
|
||||
&& compopt -o nospace \
|
||||
&& return 0
|
||||
else
|
||||
COMPREPLY=( $(compgen -W "${curr}" -- ${curr}) ) \
|
||||
&& return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
((i+=3))
|
||||
done # while
|
||||
|
||||
if true
|
||||
then
|
||||
COMPREPLY=( $(compgen -W "${candids[*]}" -- "$curr") )
|
||||
compopt -o nospace
|
||||
return 0
|
||||
fi
|
||||
|
||||
# When in an incomplete optname, e.g., `--chec`
|
||||
elif [[ $curr =~ ^--?[^:]* ]]
|
||||
then
|
||||
if true
|
||||
then
|
||||
COMPREPLY=( $(compgen -W "${candids[*]}" -- "$curr") )
|
||||
compopt -o nospace
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
if true
|
||||
then
|
||||
compopt -o filenames
|
||||
COMPREPLY=( $(compgen -f -- "$curr") )
|
||||
compopt -o nospace
|
||||
return 0
|
||||
fi
|
||||
|
||||
;;
|
||||
esac
|
||||
return 0
|
||||
|
||||
} &&
|
||||
complete -onospace -F _nim nim
|
||||
complete -F _nim nim
|
||||
|
||||
# ex: ts=2 sw=2 et filetypesh
|
||||
# ex: filetype=sh
|
||||
|
||||
339
tools/nimgrep.bash-completion
Normal file
339
tools/nimgrep.bash-completion
Normal file
@@ -0,0 +1,339 @@
|
||||
# bash completion for nimgrep -*- shell-script -*-
|
||||
|
||||
__is_short_or_long()
|
||||
{
|
||||
local actual short long
|
||||
actual="$1"
|
||||
short="$2"
|
||||
long="$3"
|
||||
[[ ! -z $short && $actual == $short ]] && return 0
|
||||
[[ ! -z $long && $actual == $long ]] && return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
__ask_for_subcmd_or_subopts()
|
||||
{
|
||||
local args cmd subcmd words sub_words word_first word_last word_lastlast
|
||||
local len ilast ilastlast i ele sub_len n_nopts
|
||||
|
||||
args=("$@")
|
||||
ask_for_what="${args[0]}"
|
||||
cmd="${args[1]}"
|
||||
subcmd="${args[2]}"
|
||||
ilast="${args[3]}"
|
||||
words=("${args[@]:4}")
|
||||
len=${#words[@]}
|
||||
ilastlast=$((ilast - 1))
|
||||
sub_words=("${words[@]:0:ilast}")
|
||||
sub_len=${#sub_words[@]}
|
||||
word_first=${words[0]}
|
||||
word_last=${words[ilast]}
|
||||
word_lastlast=${words[ilastlast]}
|
||||
n_nopts=0
|
||||
|
||||
# printf "\n[DBUG] word_first:${word_first}|ilast:${ilast}|words(${len}):${words[*]}|sub_words(${sub_len}):${sub_words[*]}\n"
|
||||
|
||||
if [[ $word_first != $cmd ]]
|
||||
then
|
||||
return 1
|
||||
fi
|
||||
|
||||
i=0
|
||||
while [[ $i -lt $len ]]
|
||||
do
|
||||
ele=${words[i]}
|
||||
if [[ ! $ele =~ ^- ]]
|
||||
then
|
||||
if [[ $ele == $cmd || $ele == $subcmd ]]
|
||||
then
|
||||
((n_nopts+=1))
|
||||
elif [[ $i -eq $ilast && $ele =~ ^[a-zA-Z] ]]
|
||||
then
|
||||
((i=i))
|
||||
elif [[ -z $ele ]]
|
||||
then
|
||||
((i=i))
|
||||
elif [[ $ele =~ ^: ]]
|
||||
then
|
||||
((i+=1))
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
((i+=1))
|
||||
done
|
||||
|
||||
case $ask_for_what in
|
||||
1)
|
||||
if [[ n_nopts -eq 1 ]]
|
||||
then
|
||||
if [[ -z $word_last || $word_last =~ ^[a-zA-Z] ]] && [[ $word_lastlast != : ]]
|
||||
then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
2)
|
||||
if [[ n_nopts -eq 2 ]]
|
||||
then
|
||||
if [[ -z $word_last ]] || [[ $word_last =~ ^[-:] ]]
|
||||
then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
esac
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
__ask_for_subcmd()
|
||||
{
|
||||
__ask_for_subcmd_or_subopts 1 "$@"
|
||||
}
|
||||
|
||||
__ask_for_subcmd_opts()
|
||||
{
|
||||
__ask_for_subcmd_or_subopts 2 "$@"
|
||||
}
|
||||
|
||||
_nimgrep()
|
||||
{
|
||||
local curr prev prevprev words
|
||||
local i_curr n_words i_prev i_prevprev
|
||||
|
||||
COMPREPLY=()
|
||||
i_curr=$COMP_CWORD
|
||||
n_words=$((i_curr+1))
|
||||
i_prev=$((i_curr-1))
|
||||
i_prevprev=$((i_curr-2))
|
||||
curr="${COMP_WORDS[i_curr]}"
|
||||
prev="${COMP_WORDS[i_prev]}"
|
||||
prevprev="${COMP_WORDS[i_prevprev]}"
|
||||
words=("${COMP_WORDS[@]:0:n_words}")
|
||||
|
||||
local subcmds opts candids
|
||||
|
||||
# printf "\n[DBUG] curr:$curr|prev:$prev|words(${#words[*]}):${words[*]}\n"
|
||||
|
||||
# Asking for a subcommand
|
||||
if false && __ask_for_subcmd nimgrep nimgrep $i_curr "${words[@]}"
|
||||
then
|
||||
subcmds=""
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Prioritize subcmd over opt
|
||||
if false
|
||||
then
|
||||
return 124
|
||||
elif false && __ask_for_subcmd_opts nimgrep compileToC $i_curr "${words[@]}"
|
||||
then
|
||||
opts=() \
|
||||
&& candids=()
|
||||
else
|
||||
opts=() \
|
||||
&& candids=()
|
||||
opts+=("-f" "--find" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--replace" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--confirm" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--filenames" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--peg" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--re" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("-x" "--rex" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("-w" "--word" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("-i" "--ignoreCase" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("-y" "--ignoreStyle" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("-r" "--recursive" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--follow" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("-s" "--sortTime" "asc desc") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--extensions" "EX") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--notextensions" "EX") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--filename" "PAT") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--notfilename" "PAT") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--dirname" "PAT") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--notdirname" "PAT") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--dirpath" "PAT") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--notdirpath" "PAT") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--inFile" "PAT") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--notinFile" "PAT") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--bin" "on off only") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("-t" "--text" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--inContext" "PAT") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--notinContext" "PAT") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--nocolor" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--colorTheme" "THEME") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--color" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--count" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("-c" "--context" "N") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("-a" "--afterContext" "N") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("-b" "--beforeContext" "N") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("-g" "--group" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("-l" "--newLine" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--cols" "N auto") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--onlyAscii" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("-j" "--threads" "N") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--stdin" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--verbose" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("-h" "--help" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("-v" "--version" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
fi
|
||||
|
||||
local c_short c_long c_accvals
|
||||
local len i idx0 idx1 idx2
|
||||
|
||||
case $curr in
|
||||
# Asking for accepted optvalues, e.g., `out:`
|
||||
:)
|
||||
len=${#opts[@]}
|
||||
i=0
|
||||
|
||||
while [[ $i -lt $len ]]
|
||||
do
|
||||
idx0=$((i / 3 * 3))
|
||||
idx1=$((idx0 + 1))
|
||||
idx2=$((idx1 + 1))
|
||||
c_short=${opts[idx0]}
|
||||
c_long=${opts[idx1]}
|
||||
c_accvals=${opts[idx2]}
|
||||
(false \
|
||||
|| __is_short_or_long $prev ${c_short} ${c_long} \
|
||||
|| false) \
|
||||
&& COMPREPLY=( $(compgen -W "${c_accvals}" --) ) \
|
||||
&& return 0
|
||||
((i+=3))
|
||||
done
|
||||
|
||||
return 124
|
||||
;;
|
||||
|
||||
*)
|
||||
# When in a incomplete opt value, e.g., `--check:of`
|
||||
if [[ $prev == : ]]
|
||||
then
|
||||
len=${#opts[@]}
|
||||
i=0
|
||||
while [[ $i -lt $len ]]
|
||||
do
|
||||
idx0=$((i / 3 * 3))
|
||||
idx1=$((idx0 + 1))
|
||||
idx2=$((idx1 + 1))
|
||||
c_short=${opts[idx0]}
|
||||
c_long=${opts[idx1]}
|
||||
c_accvals=${opts[idx2]}
|
||||
(false \
|
||||
|| __is_short_or_long $prevprev ${c_short} ${c_long} \
|
||||
|| false) \
|
||||
&& COMPREPLY=( $(compgen -W "${c_accvals}" -- ${curr}) ) \
|
||||
&& return 0
|
||||
((i+=3))
|
||||
done
|
||||
return 124
|
||||
fi
|
||||
|
||||
# When in a complete optname, might need optvalue, e.g., `--check`
|
||||
if [[ $curr =~ ^--?[:()a-zA-Z]+$ ]]
|
||||
then
|
||||
len=${#opts[@]}
|
||||
i=0
|
||||
while [[ $i -lt $len ]]
|
||||
do
|
||||
idx0=$(((i / 3 * 3)))
|
||||
idx1=$((idx0 + 1))
|
||||
idx2=$((idx1 + 1))
|
||||
c_short=${opts[idx0]}
|
||||
c_long=${opts[idx1]}
|
||||
c_accvals=${opts[idx2]}
|
||||
|
||||
if __is_short_or_long $curr ${c_short} ${c_long}
|
||||
then
|
||||
if [[ ! -z $c_accvals ]]
|
||||
then
|
||||
COMPREPLY=( $(compgen -W "${curr}:" -- ${curr}) ) \
|
||||
&& compopt -o nospace \
|
||||
&& return 0
|
||||
else
|
||||
COMPREPLY=( $(compgen -W "${curr}" -- ${curr}) ) \
|
||||
&& return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
((i+=3))
|
||||
done # while
|
||||
|
||||
if true
|
||||
then
|
||||
COMPREPLY=( $(compgen -W "${candids[*]}" -- "$curr") )
|
||||
compopt -o nospace
|
||||
return 0
|
||||
fi
|
||||
|
||||
# When in an incomplete optname, e.g., `--chec`
|
||||
elif [[ $curr =~ ^--?[^:]* ]]
|
||||
then
|
||||
if true
|
||||
then
|
||||
COMPREPLY=( $(compgen -W "${candids[*]}" -- "$curr") )
|
||||
compopt -o nospace
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
if true
|
||||
then
|
||||
compopt -o filenames
|
||||
COMPREPLY=( $(compgen -f -- "$curr") )
|
||||
compopt -o nospace
|
||||
return 0
|
||||
fi
|
||||
|
||||
;;
|
||||
esac
|
||||
return 0
|
||||
|
||||
} &&
|
||||
complete -F _nimgrep nimgrep
|
||||
|
||||
# ex: filetype=sh
|
||||
267
tools/nimpretty.bash-completion
Normal file
267
tools/nimpretty.bash-completion
Normal file
@@ -0,0 +1,267 @@
|
||||
# bash completion for nimpretty -*- shell-script -*-
|
||||
|
||||
__is_short_or_long()
|
||||
{
|
||||
local actual short long
|
||||
actual="$1"
|
||||
short="$2"
|
||||
long="$3"
|
||||
[[ ! -z $short && $actual == $short ]] && return 0
|
||||
[[ ! -z $long && $actual == $long ]] && return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
__ask_for_subcmd_or_subopts()
|
||||
{
|
||||
local args cmd subcmd words sub_words word_first word_last word_lastlast
|
||||
local len ilast ilastlast i ele sub_len n_nopts
|
||||
|
||||
args=("$@")
|
||||
ask_for_what="${args[0]}"
|
||||
cmd="${args[1]}"
|
||||
subcmd="${args[2]}"
|
||||
ilast="${args[3]}"
|
||||
words=("${args[@]:4}")
|
||||
len=${#words[@]}
|
||||
ilastlast=$((ilast - 1))
|
||||
sub_words=("${words[@]:0:ilast}")
|
||||
sub_len=${#sub_words[@]}
|
||||
word_first=${words[0]}
|
||||
word_last=${words[ilast]}
|
||||
word_lastlast=${words[ilastlast]}
|
||||
n_nopts=0
|
||||
|
||||
# printf "\n[DBUG] word_first:${word_first}|ilast:${ilast}|words(${len}):${words[*]}|sub_words(${sub_len}):${sub_words[*]}\n"
|
||||
|
||||
if [[ $word_first != $cmd ]]
|
||||
then
|
||||
return 1
|
||||
fi
|
||||
|
||||
i=0
|
||||
while [[ $i -lt $len ]]
|
||||
do
|
||||
ele=${words[i]}
|
||||
if [[ ! $ele =~ ^- ]]
|
||||
then
|
||||
if [[ $ele == $cmd || $ele == $subcmd ]]
|
||||
then
|
||||
((n_nopts+=1))
|
||||
elif [[ $i -eq $ilast && $ele =~ ^[a-zA-Z] ]]
|
||||
then
|
||||
((i=i))
|
||||
elif [[ -z $ele ]]
|
||||
then
|
||||
((i=i))
|
||||
elif [[ $ele =~ ^: ]]
|
||||
then
|
||||
((i+=1))
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
((i+=1))
|
||||
done
|
||||
|
||||
case $ask_for_what in
|
||||
1)
|
||||
if [[ n_nopts -eq 1 ]]
|
||||
then
|
||||
if [[ -z $word_last || $word_last =~ ^[a-zA-Z] ]] && [[ $word_lastlast != : ]]
|
||||
then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
2)
|
||||
if [[ n_nopts -eq 2 ]]
|
||||
then
|
||||
if [[ -z $word_last ]] || [[ $word_last =~ ^[-:] ]]
|
||||
then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
esac
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
__ask_for_subcmd()
|
||||
{
|
||||
__ask_for_subcmd_or_subopts 1 "$@"
|
||||
}
|
||||
|
||||
__ask_for_subcmd_opts()
|
||||
{
|
||||
__ask_for_subcmd_or_subopts 2 "$@"
|
||||
}
|
||||
|
||||
_nimpretty()
|
||||
{
|
||||
local curr prev prevprev words
|
||||
local i_curr n_words i_prev i_prevprev
|
||||
|
||||
COMPREPLY=()
|
||||
i_curr=$COMP_CWORD
|
||||
n_words=$((i_curr+1))
|
||||
i_prev=$((i_curr-1))
|
||||
i_prevprev=$((i_curr-2))
|
||||
curr="${COMP_WORDS[i_curr]}"
|
||||
prev="${COMP_WORDS[i_prev]}"
|
||||
prevprev="${COMP_WORDS[i_prevprev]}"
|
||||
words=("${COMP_WORDS[@]:0:n_words}")
|
||||
|
||||
local subcmds opts candids
|
||||
|
||||
# printf "\n[DBUG] curr:$curr|prev:$prev|words(${#words[*]}):${words[*]}\n"
|
||||
|
||||
# Asking for a subcommand
|
||||
if false && __ask_for_subcmd nimpretty nimpretty $i_curr "${words[@]}"
|
||||
then
|
||||
subcmds=""
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Prioritize subcmd over opt
|
||||
if false
|
||||
then
|
||||
return 124
|
||||
elif false && __ask_for_subcmd_opts nimpretty compileToC $i_curr "${words[@]}"
|
||||
then
|
||||
opts=() \
|
||||
&& candids=()
|
||||
else
|
||||
opts=() \
|
||||
&& candids=()
|
||||
opts+=("" "--out" "file") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--outDir" "DIR") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--stdin" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--indent" "N") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--maxLineLen" "N") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--version" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--help" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
fi
|
||||
|
||||
local c_short c_long c_accvals
|
||||
local len i idx0 idx1 idx2
|
||||
|
||||
case $curr in
|
||||
# Asking for accepted optvalues, e.g., `out:`
|
||||
:)
|
||||
len=${#opts[@]}
|
||||
i=0
|
||||
|
||||
while [[ $i -lt $len ]]
|
||||
do
|
||||
idx0=$((i / 3 * 3))
|
||||
idx1=$((idx0 + 1))
|
||||
idx2=$((idx1 + 1))
|
||||
c_short=${opts[idx0]}
|
||||
c_long=${opts[idx1]}
|
||||
c_accvals=${opts[idx2]}
|
||||
(false \
|
||||
|| __is_short_or_long $prev ${c_short} ${c_long} \
|
||||
|| false) \
|
||||
&& COMPREPLY=( $(compgen -W "${c_accvals}" --) ) \
|
||||
&& return 0
|
||||
((i+=3))
|
||||
done
|
||||
|
||||
return 124
|
||||
;;
|
||||
|
||||
*)
|
||||
# When in a incomplete opt value, e.g., `--check:of`
|
||||
if [[ $prev == : ]]
|
||||
then
|
||||
len=${#opts[@]}
|
||||
i=0
|
||||
while [[ $i -lt $len ]]
|
||||
do
|
||||
idx0=$((i / 3 * 3))
|
||||
idx1=$((idx0 + 1))
|
||||
idx2=$((idx1 + 1))
|
||||
c_short=${opts[idx0]}
|
||||
c_long=${opts[idx1]}
|
||||
c_accvals=${opts[idx2]}
|
||||
(false \
|
||||
|| __is_short_or_long $prevprev ${c_short} ${c_long} \
|
||||
|| false) \
|
||||
&& COMPREPLY=( $(compgen -W "${c_accvals}" -- ${curr}) ) \
|
||||
&& return 0
|
||||
((i+=3))
|
||||
done
|
||||
return 124
|
||||
fi
|
||||
|
||||
# When in a complete optname, might need optvalue, e.g., `--check`
|
||||
if [[ $curr =~ ^--?[:()a-zA-Z]+$ ]]
|
||||
then
|
||||
len=${#opts[@]}
|
||||
i=0
|
||||
while [[ $i -lt $len ]]
|
||||
do
|
||||
idx0=$(((i / 3 * 3)))
|
||||
idx1=$((idx0 + 1))
|
||||
idx2=$((idx1 + 1))
|
||||
c_short=${opts[idx0]}
|
||||
c_long=${opts[idx1]}
|
||||
c_accvals=${opts[idx2]}
|
||||
|
||||
if __is_short_or_long $curr ${c_short} ${c_long}
|
||||
then
|
||||
if [[ ! -z $c_accvals ]]
|
||||
then
|
||||
COMPREPLY=( $(compgen -W "${curr}:" -- ${curr}) ) \
|
||||
&& compopt -o nospace \
|
||||
&& return 0
|
||||
else
|
||||
COMPREPLY=( $(compgen -W "${curr}" -- ${curr}) ) \
|
||||
&& return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
((i+=3))
|
||||
done # while
|
||||
|
||||
if true
|
||||
then
|
||||
COMPREPLY=( $(compgen -W "${candids[*]}" -- "$curr") )
|
||||
compopt -o nospace
|
||||
return 0
|
||||
fi
|
||||
|
||||
# When in an incomplete optname, e.g., `--chec`
|
||||
elif [[ $curr =~ ^--?[^:]* ]]
|
||||
then
|
||||
if true
|
||||
then
|
||||
COMPREPLY=( $(compgen -W "${candids[*]}" -- "$curr") )
|
||||
compopt -o nospace
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
if true
|
||||
then
|
||||
compopt -o filenames
|
||||
COMPREPLY=( $(compgen -f -- "$curr") )
|
||||
compopt -o nospace
|
||||
return 0
|
||||
fi
|
||||
|
||||
;;
|
||||
esac
|
||||
return 0
|
||||
|
||||
} &&
|
||||
complete -F _nimpretty nimpretty
|
||||
|
||||
# ex: filetype=sh
|
||||
291
tools/nimsuggest.bash-completion
Normal file
291
tools/nimsuggest.bash-completion
Normal file
@@ -0,0 +1,291 @@
|
||||
# bash completion for nimsuggest -*- shell-script -*-
|
||||
|
||||
__is_short_or_long()
|
||||
{
|
||||
local actual short long
|
||||
actual="$1"
|
||||
short="$2"
|
||||
long="$3"
|
||||
[[ ! -z $short && $actual == $short ]] && return 0
|
||||
[[ ! -z $long && $actual == $long ]] && return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
__ask_for_subcmd_or_subopts()
|
||||
{
|
||||
local args cmd subcmd words sub_words word_first word_last word_lastlast
|
||||
local len ilast ilastlast i ele sub_len n_nopts
|
||||
|
||||
args=("$@")
|
||||
ask_for_what="${args[0]}"
|
||||
cmd="${args[1]}"
|
||||
subcmd="${args[2]}"
|
||||
ilast="${args[3]}"
|
||||
words=("${args[@]:4}")
|
||||
len=${#words[@]}
|
||||
ilastlast=$((ilast - 1))
|
||||
sub_words=("${words[@]:0:ilast}")
|
||||
sub_len=${#sub_words[@]}
|
||||
word_first=${words[0]}
|
||||
word_last=${words[ilast]}
|
||||
word_lastlast=${words[ilastlast]}
|
||||
n_nopts=0
|
||||
|
||||
# printf "\n[DBUG] word_first:${word_first}|ilast:${ilast}|words(${len}):${words[*]}|sub_words(${sub_len}):${sub_words[*]}\n"
|
||||
|
||||
if [[ $word_first != $cmd ]]
|
||||
then
|
||||
return 1
|
||||
fi
|
||||
|
||||
i=0
|
||||
while [[ $i -lt $len ]]
|
||||
do
|
||||
ele=${words[i]}
|
||||
if [[ ! $ele =~ ^- ]]
|
||||
then
|
||||
if [[ $ele == $cmd || $ele == $subcmd ]]
|
||||
then
|
||||
((n_nopts+=1))
|
||||
elif [[ $i -eq $ilast && $ele =~ ^[a-zA-Z] ]]
|
||||
then
|
||||
((i=i))
|
||||
elif [[ -z $ele ]]
|
||||
then
|
||||
((i=i))
|
||||
elif [[ $ele =~ ^: ]]
|
||||
then
|
||||
((i+=1))
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
((i+=1))
|
||||
done
|
||||
|
||||
case $ask_for_what in
|
||||
1)
|
||||
if [[ n_nopts -eq 1 ]]
|
||||
then
|
||||
if [[ -z $word_last || $word_last =~ ^[a-zA-Z] ]] && [[ $word_lastlast != : ]]
|
||||
then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
2)
|
||||
if [[ n_nopts -eq 2 ]]
|
||||
then
|
||||
if [[ -z $word_last ]] || [[ $word_last =~ ^[-:] ]]
|
||||
then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
esac
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
__ask_for_subcmd()
|
||||
{
|
||||
__ask_for_subcmd_or_subopts 1 "$@"
|
||||
}
|
||||
|
||||
__ask_for_subcmd_opts()
|
||||
{
|
||||
__ask_for_subcmd_or_subopts 2 "$@"
|
||||
}
|
||||
|
||||
_nimsuggest()
|
||||
{
|
||||
local curr prev prevprev words
|
||||
local i_curr n_words i_prev i_prevprev
|
||||
|
||||
COMPREPLY=()
|
||||
i_curr=$COMP_CWORD
|
||||
n_words=$((i_curr+1))
|
||||
i_prev=$((i_curr-1))
|
||||
i_prevprev=$((i_curr-2))
|
||||
curr="${COMP_WORDS[i_curr]}"
|
||||
prev="${COMP_WORDS[i_prev]}"
|
||||
prevprev="${COMP_WORDS[i_prevprev]}"
|
||||
words=("${COMP_WORDS[@]:0:n_words}")
|
||||
|
||||
local subcmds opts candids
|
||||
|
||||
# printf "\n[DBUG] curr:$curr|prev:$prev|words(${#words[*]}):${words[*]}\n"
|
||||
|
||||
# Asking for a subcommand
|
||||
if false && __ask_for_subcmd nimsuggest nimsuggest $i_curr "${words[@]}"
|
||||
then
|
||||
subcmds=""
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Prioritize subcmd over opt
|
||||
if false
|
||||
then
|
||||
return 124
|
||||
elif false && __ask_for_subcmd_opts nimsuggest compileToC $i_curr "${words[@]}"
|
||||
then
|
||||
opts=() \
|
||||
&& candids=()
|
||||
else
|
||||
opts=() \
|
||||
&& candids=()
|
||||
opts+=("" "--autobind" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--port" "PORT") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--address" "HOST") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--stdin" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--clientProcessId" "PID") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--epc" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--debug" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--log" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--v1" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--v2" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--v3" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--v4" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--info" "nimVer protocolVer capabilities") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--refresh" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--maxresults" "N") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--tester" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--find" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--exceptionInlayHints" "on off") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
opts+=("" "--help" "") \
|
||||
&& candids+=(${opts[$((${#opts[@]}-3))]} ${opts[$((${#opts[@]}-2))]})
|
||||
fi
|
||||
|
||||
local c_short c_long c_accvals
|
||||
local len i idx0 idx1 idx2
|
||||
|
||||
case $curr in
|
||||
# Asking for accepted optvalues, e.g., `out:`
|
||||
:)
|
||||
len=${#opts[@]}
|
||||
i=0
|
||||
|
||||
while [[ $i -lt $len ]]
|
||||
do
|
||||
idx0=$((i / 3 * 3))
|
||||
idx1=$((idx0 + 1))
|
||||
idx2=$((idx1 + 1))
|
||||
c_short=${opts[idx0]}
|
||||
c_long=${opts[idx1]}
|
||||
c_accvals=${opts[idx2]}
|
||||
(false \
|
||||
|| __is_short_or_long $prev ${c_short} ${c_long} \
|
||||
|| false) \
|
||||
&& COMPREPLY=( $(compgen -W "${c_accvals}" --) ) \
|
||||
&& return 0
|
||||
((i+=3))
|
||||
done
|
||||
|
||||
return 124
|
||||
;;
|
||||
|
||||
*)
|
||||
# When in a incomplete opt value, e.g., `--check:of`
|
||||
if [[ $prev == : ]]
|
||||
then
|
||||
len=${#opts[@]}
|
||||
i=0
|
||||
while [[ $i -lt $len ]]
|
||||
do
|
||||
idx0=$((i / 3 * 3))
|
||||
idx1=$((idx0 + 1))
|
||||
idx2=$((idx1 + 1))
|
||||
c_short=${opts[idx0]}
|
||||
c_long=${opts[idx1]}
|
||||
c_accvals=${opts[idx2]}
|
||||
(false \
|
||||
|| __is_short_or_long $prevprev ${c_short} ${c_long} \
|
||||
|| false) \
|
||||
&& COMPREPLY=( $(compgen -W "${c_accvals}" -- ${curr}) ) \
|
||||
&& return 0
|
||||
((i+=3))
|
||||
done
|
||||
return 124
|
||||
fi
|
||||
|
||||
# When in a complete optname, might need optvalue, e.g., `--check`
|
||||
if [[ $curr =~ ^--?[:()a-zA-Z]+$ ]]
|
||||
then
|
||||
len=${#opts[@]}
|
||||
i=0
|
||||
while [[ $i -lt $len ]]
|
||||
do
|
||||
idx0=$(((i / 3 * 3)))
|
||||
idx1=$((idx0 + 1))
|
||||
idx2=$((idx1 + 1))
|
||||
c_short=${opts[idx0]}
|
||||
c_long=${opts[idx1]}
|
||||
c_accvals=${opts[idx2]}
|
||||
|
||||
if __is_short_or_long $curr ${c_short} ${c_long}
|
||||
then
|
||||
if [[ ! -z $c_accvals ]]
|
||||
then
|
||||
COMPREPLY=( $(compgen -W "${curr}:" -- ${curr}) ) \
|
||||
&& compopt -o nospace \
|
||||
&& return 0
|
||||
else
|
||||
COMPREPLY=( $(compgen -W "${curr}" -- ${curr}) ) \
|
||||
&& return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
((i+=3))
|
||||
done # while
|
||||
|
||||
if true
|
||||
then
|
||||
COMPREPLY=( $(compgen -W "${candids[*]}" -- "$curr") )
|
||||
compopt -o nospace
|
||||
return 0
|
||||
fi
|
||||
|
||||
# When in an incomplete optname, e.g., `--chec`
|
||||
elif [[ $curr =~ ^--?[^:]* ]]
|
||||
then
|
||||
if true
|
||||
then
|
||||
COMPREPLY=( $(compgen -W "${candids[*]}" -- "$curr") )
|
||||
compopt -o nospace
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
if true
|
||||
then
|
||||
compopt -o filenames
|
||||
COMPREPLY=( $(compgen -f -- "$curr") )
|
||||
compopt -o nospace
|
||||
return 0
|
||||
fi
|
||||
|
||||
;;
|
||||
esac
|
||||
return 0
|
||||
|
||||
} &&
|
||||
complete -F _nimsuggest nimsuggest
|
||||
|
||||
# ex: filetype=sh
|
||||
Reference in New Issue
Block a user