WIP: disallow 'nil' for strings and seqs
This commit is contained in:
parent
32afc1a562
commit
dae5450947
43 changed files with 207 additions and 173 deletions
|
|
@ -1150,7 +1150,10 @@ proc copyObjectSet*(dest: var TObjectSet, src: TObjectSet) =
|
||||||
for i in countup(0, high(src.data)): dest.data[i] = src.data[i]
|
for i in countup(0, high(src.data)): dest.data[i] = src.data[i]
|
||||||
|
|
||||||
proc discardSons*(father: PNode) =
|
proc discardSons*(father: PNode) =
|
||||||
father.sons = nil
|
when defined(nimNoNilSeqs):
|
||||||
|
father.sons = @[]
|
||||||
|
else:
|
||||||
|
father.sons = nil
|
||||||
|
|
||||||
proc withInfo*(n: PNode, info: TLineInfo): PNode =
|
proc withInfo*(n: PNode, info: TLineInfo): PNode =
|
||||||
n.info = info
|
n.info = info
|
||||||
|
|
@ -1367,7 +1370,7 @@ proc createModuleAlias*(s: PSym, newIdent: PIdent, info: TLineInfo;
|
||||||
result.loc = s.loc
|
result.loc = s.loc
|
||||||
result.annex = s.annex
|
result.annex = s.annex
|
||||||
# XXX once usedGenerics is used, ensure module aliases keep working!
|
# XXX once usedGenerics is used, ensure module aliases keep working!
|
||||||
assert s.usedGenerics == nil
|
assert s.usedGenerics.len == 0
|
||||||
|
|
||||||
proc initStrTable*(x: var TStrTable) =
|
proc initStrTable*(x: var TStrTable) =
|
||||||
x.counter = 0
|
x.counter = 0
|
||||||
|
|
@ -1592,7 +1595,10 @@ proc getStr*(a: PNode): string =
|
||||||
of nkStrLit..nkTripleStrLit: result = a.strVal
|
of nkStrLit..nkTripleStrLit: result = a.strVal
|
||||||
of nkNilLit:
|
of nkNilLit:
|
||||||
# let's hope this fixes more problems than it creates:
|
# let's hope this fixes more problems than it creates:
|
||||||
result = nil
|
when defined(nimNoNilSeqs):
|
||||||
|
result = ""
|
||||||
|
else:
|
||||||
|
result = nil
|
||||||
else:
|
else:
|
||||||
doAssert false, "getStr"
|
doAssert false, "getStr"
|
||||||
#internalError(a.info, "getStr")
|
#internalError(a.info, "getStr")
|
||||||
|
|
|
||||||
|
|
@ -431,7 +431,7 @@ proc genInfixCall(p: BProc, le, ri: PNode, d: var TLoc) =
|
||||||
assert(sonsLen(typ) == sonsLen(typ.n))
|
assert(sonsLen(typ) == sonsLen(typ.n))
|
||||||
# don't call '$' here for efficiency:
|
# don't call '$' here for efficiency:
|
||||||
let pat = ri.sons[0].sym.loc.r.data
|
let pat = ri.sons[0].sym.loc.r.data
|
||||||
internalAssert p.config, pat != nil
|
internalAssert p.config, pat.len > 0
|
||||||
if pat.contains({'#', '(', '@', '\''}):
|
if pat.contains({'#', '(', '@', '\''}):
|
||||||
var pl = genPatternCall(p, ri, pat, typ)
|
var pl = genPatternCall(p, ri, pat, typ)
|
||||||
# simpler version of 'fixupCall' that works with the pl+params combination:
|
# simpler version of 'fixupCall' that works with the pl+params combination:
|
||||||
|
|
@ -480,7 +480,7 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
|
||||||
|
|
||||||
# don't call '$' here for efficiency:
|
# don't call '$' here for efficiency:
|
||||||
let pat = ri.sons[0].sym.loc.r.data
|
let pat = ri.sons[0].sym.loc.r.data
|
||||||
internalAssert p.config, pat != nil
|
internalAssert p.config, pat.len > 0
|
||||||
var start = 3
|
var start = 3
|
||||||
if ' ' in pat:
|
if ' ' in pat:
|
||||||
start = 1
|
start = 1
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,8 @@ proc genLiteral(p: BProc, n: PNode, ty: PType): Rope =
|
||||||
of tyString:
|
of tyString:
|
||||||
# with the new semantics for 'nil' strings, we can map "" to nil and
|
# with the new semantics for 'nil' strings, we can map "" to nil and
|
||||||
# save tons of allocations:
|
# save tons of allocations:
|
||||||
if n.strVal.len == 0: result = genNilStringLiteral(p.module, n.info)
|
if n.strVal.len == 0 and optNilSeqs notin p.options:
|
||||||
|
result = genNilStringLiteral(p.module, n.info)
|
||||||
else:
|
else:
|
||||||
result = genStringLiteral(p.module, n)
|
result = genStringLiteral(p.module, n)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ proc genSectionEnd*(fs: TCFileSection; conf: ConfigRef): Rope =
|
||||||
|
|
||||||
proc genSectionStart*(ps: TCProcSection; conf: ConfigRef): Rope =
|
proc genSectionStart*(ps: TCProcSection; conf: ConfigRef): Rope =
|
||||||
if compilationCachePresent(conf):
|
if compilationCachePresent(conf):
|
||||||
result = rope(nil)
|
result = rope("")
|
||||||
add(result, "\n/*\t")
|
add(result, "\n/*\t")
|
||||||
add(result, CProcSectionNames[ps])
|
add(result, CProcSectionNames[ps])
|
||||||
add(result, ":*/\n")
|
add(result, ":*/\n")
|
||||||
|
|
|
||||||
|
|
@ -496,6 +496,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||||
else:
|
else:
|
||||||
localError(conf, info, errOnOrOffExpectedButXFound % arg)
|
localError(conf, info, errOnOrOffExpectedButXFound % arg)
|
||||||
of "laxstrings": processOnOffSwitch(conf, {optLaxStrings}, arg, pass, info)
|
of "laxstrings": processOnOffSwitch(conf, {optLaxStrings}, arg, pass, info)
|
||||||
|
of "nilseqs": processOnOffSwitch(conf, {optNilSeqs}, arg, pass, info)
|
||||||
of "checks", "x": processOnOffSwitch(conf, ChecksOptions, arg, pass, info)
|
of "checks", "x": processOnOffSwitch(conf, ChecksOptions, arg, pass, info)
|
||||||
of "floatchecks":
|
of "floatchecks":
|
||||||
processOnOffSwitch(conf, {optNaNCheck, optInfCheck}, arg, pass, info)
|
processOnOffSwitch(conf, {optNaNCheck, optInfCheck}, arg, pass, info)
|
||||||
|
|
|
||||||
|
|
@ -74,3 +74,4 @@ proc initDefines*(symbols: StringTableRef) =
|
||||||
defineSymbol("nimVmExportFixed")
|
defineSymbol("nimVmExportFixed")
|
||||||
defineSymbol("nimIncrSeqV3")
|
defineSymbol("nimIncrSeqV3")
|
||||||
defineSymbol("nimAshr")
|
defineSymbol("nimAshr")
|
||||||
|
defineSymbol("nimNoNilSeqs")
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,7 @@ proc ropeFormatNamedVars(conf: ConfigRef; frmt: FormatStr,
|
||||||
proc genComment(d: PDoc, n: PNode): string =
|
proc genComment(d: PDoc, n: PNode): string =
|
||||||
result = ""
|
result = ""
|
||||||
var dummyHasToc: bool
|
var dummyHasToc: bool
|
||||||
if n.comment != nil:
|
if n.comment.len > 0:
|
||||||
renderRstToOut(d[], parseRst(n.comment, toFilename(d.conf, n.info),
|
renderRstToOut(d[], parseRst(n.comment, toFilename(d.conf, n.info),
|
||||||
toLinenumber(n.info), toColumn(n.info),
|
toLinenumber(n.info), toColumn(n.info),
|
||||||
dummyHasToc, d.options, d.conf), result)
|
dummyHasToc, d.options, d.conf), result)
|
||||||
|
|
@ -205,7 +205,8 @@ proc genRecComment(d: PDoc, n: PNode): Rope =
|
||||||
result = genRecComment(d, n.sons[i])
|
result = genRecComment(d, n.sons[i])
|
||||||
if result != nil: return
|
if result != nil: return
|
||||||
else:
|
else:
|
||||||
n.comment = nil
|
when defined(nimNoNilSeqs): n.comment = ""
|
||||||
|
else: n.comment = nil
|
||||||
|
|
||||||
proc getPlainDocstring(n: PNode): string =
|
proc getPlainDocstring(n: PNode): string =
|
||||||
## Gets the plain text docstring of a node non destructively.
|
## Gets the plain text docstring of a node non destructively.
|
||||||
|
|
@ -215,7 +216,7 @@ proc getPlainDocstring(n: PNode): string =
|
||||||
## the concatenated ``##`` comments of the node.
|
## the concatenated ``##`` comments of the node.
|
||||||
result = ""
|
result = ""
|
||||||
if n == nil: return
|
if n == nil: return
|
||||||
if n.comment != nil and startsWith(n.comment, "##"):
|
if startsWith(n.comment, "##"):
|
||||||
result = n.comment
|
result = n.comment
|
||||||
if result.len < 1:
|
if result.len < 1:
|
||||||
for i in countup(0, safeLen(n)-1):
|
for i in countup(0, safeLen(n)-1):
|
||||||
|
|
@ -564,9 +565,9 @@ proc genJsonItem(d: PDoc, n, nameNode: PNode, k: TSymKind): JsonNode =
|
||||||
|
|
||||||
result = %{ "name": %name, "type": %($k), "line": %n.info.line.int,
|
result = %{ "name": %name, "type": %($k), "line": %n.info.line.int,
|
||||||
"col": %n.info.col}
|
"col": %n.info.col}
|
||||||
if comm != nil and comm != "":
|
if comm.len > 0:
|
||||||
result["description"] = %comm
|
result["description"] = %comm
|
||||||
if r.buf != nil:
|
if r.buf.len > 0:
|
||||||
result["code"] = %r.buf
|
result["code"] = %r.buf
|
||||||
|
|
||||||
proc checkForFalse(n: PNode): bool =
|
proc checkForFalse(n: PNode): bool =
|
||||||
|
|
@ -634,7 +635,7 @@ proc add(d: PDoc; j: JsonNode) =
|
||||||
proc generateJson*(d: PDoc, n: PNode) =
|
proc generateJson*(d: PDoc, n: PNode) =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkCommentStmt:
|
of nkCommentStmt:
|
||||||
if n.comment != nil and startsWith(n.comment, "##"):
|
if startsWith(n.comment, "##"):
|
||||||
let stripped = n.comment.substr(2).strip
|
let stripped = n.comment.substr(2).strip
|
||||||
d.add %{ "comment": %stripped, "line": %n.info.line.int,
|
d.add %{ "comment": %stripped, "line": %n.info.line.int,
|
||||||
"col": %n.info.col }
|
"col": %n.info.col }
|
||||||
|
|
@ -678,7 +679,7 @@ proc genTagsItem(d: PDoc, n, nameNode: PNode, k: TSymKind): string =
|
||||||
proc generateTags*(d: PDoc, n: PNode, r: var Rope) =
|
proc generateTags*(d: PDoc, n: PNode, r: var Rope) =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkCommentStmt:
|
of nkCommentStmt:
|
||||||
if n.comment != nil and startsWith(n.comment, "##"):
|
if startsWith(n.comment, "##"):
|
||||||
let stripped = n.comment.substr(2).strip
|
let stripped = n.comment.substr(2).strip
|
||||||
r.add stripped
|
r.add stripped
|
||||||
of nkProcDef:
|
of nkProcDef:
|
||||||
|
|
|
||||||
|
|
@ -1267,7 +1267,7 @@ proc genInfixCall(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
if f.loc.r == nil: f.loc.r = mangleName(p.module, f)
|
if f.loc.r == nil: f.loc.r = mangleName(p.module, f)
|
||||||
if sfInfixCall in f.flags:
|
if sfInfixCall in f.flags:
|
||||||
let pat = n.sons[0].sym.loc.r.data
|
let pat = n.sons[0].sym.loc.r.data
|
||||||
internalAssert p.config, pat != nil
|
internalAssert p.config, pat.len > 0
|
||||||
if pat.contains({'#', '(', '@'}):
|
if pat.contains({'#', '(', '@'}):
|
||||||
var typ = skipTypes(n.sons[0].typ, abstractInst)
|
var typ = skipTypes(n.sons[0].typ, abstractInst)
|
||||||
assert(typ.kind == tyProc)
|
assert(typ.kind == tyProc)
|
||||||
|
|
@ -1350,7 +1350,7 @@ proc arrayTypeForElemType(typ: PType): string =
|
||||||
of tyUint8: "Uint8Array"
|
of tyUint8: "Uint8Array"
|
||||||
of tyFloat32: "Float32Array"
|
of tyFloat32: "Float32Array"
|
||||||
of tyFloat64, tyFloat: "Float64Array"
|
of tyFloat64, tyFloat: "Float64Array"
|
||||||
else: nil
|
else: ""
|
||||||
|
|
||||||
proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
|
proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
|
||||||
var t = skipTypes(typ, abstractInst)
|
var t = skipTypes(typ, abstractInst)
|
||||||
|
|
|
||||||
|
|
@ -164,13 +164,13 @@ type
|
||||||
TNoteKinds* = set[TNoteKind]
|
TNoteKinds* = set[TNoteKind]
|
||||||
|
|
||||||
proc computeNotesVerbosity(): array[0..3, TNoteKinds] =
|
proc computeNotesVerbosity(): array[0..3, TNoteKinds] =
|
||||||
result[3] = {low(TNoteKind)..high(TNoteKind)} - {}
|
result[3] = {low(TNoteKind)..high(TNoteKind)} - {}
|
||||||
result[2] = result[3] - {hintStackTrace, warnUninit, hintExtendedContext}
|
result[2] = result[3] - {hintStackTrace, warnUninit, hintExtendedContext}
|
||||||
result[1] = result[2] - {warnShadowIdent, warnProveField, warnProveIndex,
|
result[1] = result[2] - {warnShadowIdent, warnProveField, warnProveIndex,
|
||||||
warnGcUnsafe, hintPath, hintDependency, hintCodeBegin, hintCodeEnd,
|
warnGcUnsafe, hintPath, hintDependency, hintCodeBegin, hintCodeEnd,
|
||||||
hintSource, hintGlobalVar, hintGCStats}
|
hintSource, hintGlobalVar, hintGCStats}
|
||||||
result[0] = result[1] - {hintSuccessX, hintSuccess, hintConf,
|
result[0] = result[1] - {hintSuccessX, hintSuccess, hintConf,
|
||||||
hintProcessing, hintPattern, hintExecuting, hintLinking}
|
hintProcessing, hintPattern, hintExecuting, hintLinking}
|
||||||
|
|
||||||
const
|
const
|
||||||
NotesVerbosity* = computeNotesVerbosity()
|
NotesVerbosity* = computeNotesVerbosity()
|
||||||
|
|
|
||||||
|
|
@ -262,7 +262,7 @@ proc errorUndeclaredIdentifier*(c: PContext; info: TLineInfo; name: string) =
|
||||||
err.add "\nThis might be caused by a recursive module dependency: "
|
err.add "\nThis might be caused by a recursive module dependency: "
|
||||||
err.add c.recursiveDep
|
err.add c.recursiveDep
|
||||||
# prevent excessive errors for 'nim check'
|
# prevent excessive errors for 'nim check'
|
||||||
c.recursiveDep = nil
|
c.recursiveDep = ""
|
||||||
localError(c.config, info, errGenerated, err)
|
localError(c.config, info, errGenerated, err)
|
||||||
|
|
||||||
proc lookUp*(c: PContext, n: PNode): PSym =
|
proc lookUp*(c: PContext, n: PNode): PSym =
|
||||||
|
|
|
||||||
|
|
@ -391,10 +391,10 @@ proc rawMessage*(conf: ConfigRef; msg: TMsgKind, args: openArray[string]) =
|
||||||
|
|
||||||
if conf.structuredErrorHook != nil:
|
if conf.structuredErrorHook != nil:
|
||||||
conf.structuredErrorHook(conf, unknownLineInfo(),
|
conf.structuredErrorHook(conf, unknownLineInfo(),
|
||||||
s & (if kind != nil: KindFormat % kind else: ""), sev)
|
s & (if kind.len > 0: KindFormat % kind else: ""), sev)
|
||||||
|
|
||||||
if not ignoreMsgBecauseOfIdeTools(conf, msg):
|
if not ignoreMsgBecauseOfIdeTools(conf, msg):
|
||||||
if kind != nil:
|
if kind.len > 0:
|
||||||
styledMsgWriteln(color, title, resetStyle, s,
|
styledMsgWriteln(color, title, resetStyle, s,
|
||||||
KindColor, `%`(KindFormat, kind))
|
KindColor, `%`(KindFormat, kind))
|
||||||
else:
|
else:
|
||||||
|
|
@ -483,9 +483,9 @@ proc liMessage(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string,
|
||||||
|
|
||||||
if not ignoreMsg:
|
if not ignoreMsg:
|
||||||
if conf.structuredErrorHook != nil:
|
if conf.structuredErrorHook != nil:
|
||||||
conf.structuredErrorHook(conf, info, s & (if kind != nil: KindFormat % kind else: ""), sev)
|
conf.structuredErrorHook(conf, info, s & (if kind.len > 0: KindFormat % kind else: ""), sev)
|
||||||
if not ignoreMsgBecauseOfIdeTools(conf, msg):
|
if not ignoreMsgBecauseOfIdeTools(conf, msg):
|
||||||
if kind != nil:
|
if kind.len > 0:
|
||||||
styledMsgWriteln(styleBright, x, resetStyle, color, title, resetStyle, s,
|
styledMsgWriteln(styleBright, x, resetStyle, color, title, resetStyle, s,
|
||||||
KindColor, `%`(KindFormat, kind))
|
KindColor, `%`(KindFormat, kind))
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,8 @@ type # please make sure we have under 32 options
|
||||||
optPatterns, # en/disable pattern matching
|
optPatterns, # en/disable pattern matching
|
||||||
optMemTracker,
|
optMemTracker,
|
||||||
optHotCodeReloading,
|
optHotCodeReloading,
|
||||||
optLaxStrings
|
optLaxStrings,
|
||||||
|
optNilSeqs
|
||||||
|
|
||||||
TOptions* = set[TOption]
|
TOptions* = set[TOption]
|
||||||
TGlobalOption* = enum # **keep binary compatible**
|
TGlobalOption* = enum # **keep binary compatible**
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,8 @@ template sameOrNoInd(p): bool = p.tok.indent == p.currInd or p.tok.indent < 0
|
||||||
proc rawSkipComment(p: var TParser, node: PNode) =
|
proc rawSkipComment(p: var TParser, node: PNode) =
|
||||||
if p.tok.tokType == tkComment:
|
if p.tok.tokType == tkComment:
|
||||||
if node != nil:
|
if node != nil:
|
||||||
if node.comment == nil: node.comment = ""
|
when not defined(nimNoNilSeqs):
|
||||||
|
if node.comment == nil: node.comment = ""
|
||||||
when defined(nimpretty):
|
when defined(nimpretty):
|
||||||
if p.tok.commentOffsetB > p.tok.commentOffsetA:
|
if p.tok.commentOffsetB > p.tok.commentOffsetA:
|
||||||
add node.comment, fileSection(p.lex.config, p.lex.fileIdx, p.tok.commentOffsetA, p.tok.commentOffsetB)
|
add node.comment, fileSection(p.lex.config, p.lex.fileIdx, p.tok.commentOffsetA, p.tok.commentOffsetB)
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,10 @@ proc matchStmtList(c: PPatternContext, p, n: PNode): PNode =
|
||||||
for j in 0 ..< p.len:
|
for j in 0 ..< p.len:
|
||||||
if not matches(c, p.sons[j], n.sons[i+j]):
|
if not matches(c, p.sons[j], n.sons[i+j]):
|
||||||
# we need to undo any bindings:
|
# we need to undo any bindings:
|
||||||
if not isNil(c.mapping): c.mapping = nil
|
when defined(nimNoNilSeqs):
|
||||||
|
c.mapping = @[]
|
||||||
|
else:
|
||||||
|
if not isNil(c.mapping): c.mapping = nil
|
||||||
return false
|
return false
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -281,7 +281,7 @@ const
|
||||||
|
|
||||||
proc shouldRenderComment(g: var TSrcGen, n: PNode): bool =
|
proc shouldRenderComment(g: var TSrcGen, n: PNode): bool =
|
||||||
result = false
|
result = false
|
||||||
if n.comment != nil:
|
if n.comment.len > 0:
|
||||||
result = (renderNoComments notin g.flags) or
|
result = (renderNoComments notin g.flags) or
|
||||||
(renderDocComments in g.flags)
|
(renderDocComments in g.flags)
|
||||||
|
|
||||||
|
|
@ -402,7 +402,7 @@ proc lsons(g: TSrcGen; n: PNode, start: int = 0, theEnd: int = - 1): int =
|
||||||
proc lsub(g: TSrcGen; n: PNode): int =
|
proc lsub(g: TSrcGen; n: PNode): int =
|
||||||
# computes the length of a tree
|
# computes the length of a tree
|
||||||
if isNil(n): return 0
|
if isNil(n): return 0
|
||||||
if n.comment != nil: return MaxLineLen + 1
|
if n.comment.len > 0: return MaxLineLen + 1
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkEmpty: result = 0
|
of nkEmpty: result = 0
|
||||||
of nkTripleStrLit:
|
of nkTripleStrLit:
|
||||||
|
|
@ -500,7 +500,7 @@ proc lsub(g: TSrcGen; n: PNode): int =
|
||||||
of nkBreakStmt: result = lsub(g, n.sons[0]) + len("break_")
|
of nkBreakStmt: result = lsub(g, n.sons[0]) + len("break_")
|
||||||
of nkContinueStmt: result = lsub(g, n.sons[0]) + len("continue_")
|
of nkContinueStmt: result = lsub(g, n.sons[0]) + len("continue_")
|
||||||
of nkPragma: result = lcomma(g, n) + 4
|
of nkPragma: result = lcomma(g, n) + 4
|
||||||
of nkCommentStmt: result = if n.comment.isNil: 0 else: len(n.comment)
|
of nkCommentStmt: result = len(n.comment)
|
||||||
of nkOfBranch: result = lcomma(g, n, 0, - 2) + lsub(g, lastSon(n)) + len("of_:_")
|
of nkOfBranch: result = lcomma(g, n, 0, - 2) + lsub(g, lastSon(n)) + len("of_:_")
|
||||||
of nkImportAs: result = lsub(g, n.sons[0]) + len("_as_") + lsub(g, n.sons[1])
|
of nkImportAs: result = lsub(g, n.sons[0]) + len("_as_") + lsub(g, n.sons[1])
|
||||||
of nkElifBranch: result = lsons(g, n) + len("elif_:_")
|
of nkElifBranch: result = lsons(g, n) + len("elif_:_")
|
||||||
|
|
@ -539,7 +539,7 @@ proc gsub(g: var TSrcGen, n: PNode) =
|
||||||
proc hasCom(n: PNode): bool =
|
proc hasCom(n: PNode): bool =
|
||||||
result = false
|
result = false
|
||||||
if n.isNil: return false
|
if n.isNil: return false
|
||||||
if n.comment != nil: return true
|
if n.comment.len > 0: return true
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkEmpty..nkNilLit: discard
|
of nkEmpty..nkNilLit: discard
|
||||||
else:
|
else:
|
||||||
|
|
@ -602,7 +602,7 @@ proc gsection(g: var TSrcGen, n: PNode, c: TContext, kind: TTokType,
|
||||||
dedent(g)
|
dedent(g)
|
||||||
|
|
||||||
proc longMode(g: TSrcGen; n: PNode, start: int = 0, theEnd: int = - 1): bool =
|
proc longMode(g: TSrcGen; n: PNode, start: int = 0, theEnd: int = - 1): bool =
|
||||||
result = n.comment != nil
|
result = n.comment.len > 0
|
||||||
if not result:
|
if not result:
|
||||||
# check further
|
# check further
|
||||||
for i in countup(start, sonsLen(n) + theEnd):
|
for i in countup(start, sonsLen(n) + theEnd):
|
||||||
|
|
@ -637,7 +637,7 @@ proc gstmts(g: var TSrcGen, n: PNode, c: TContext, doIndent=true) =
|
||||||
proc gcond(g: var TSrcGen, n: PNode) =
|
proc gcond(g: var TSrcGen, n: PNode) =
|
||||||
if n.kind == nkStmtListExpr:
|
if n.kind == nkStmtListExpr:
|
||||||
put(g, tkParLe, "(")
|
put(g, tkParLe, "(")
|
||||||
gsub(g, n)
|
gsub(g, n)
|
||||||
if n.kind == nkStmtListExpr:
|
if n.kind == nkStmtListExpr:
|
||||||
put(g, tkParRi, ")")
|
put(g, tkParRi, ")")
|
||||||
|
|
||||||
|
|
@ -864,7 +864,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
|
||||||
if isNil(n): return
|
if isNil(n): return
|
||||||
var
|
var
|
||||||
a: TContext
|
a: TContext
|
||||||
if n.comment != nil: pushCom(g, n)
|
if n.comment.len > 0: pushCom(g, n)
|
||||||
case n.kind # atoms:
|
case n.kind # atoms:
|
||||||
of nkTripleStrLit: put(g, tkTripleStrLit, atom(g, n))
|
of nkTripleStrLit: put(g, tkTripleStrLit, atom(g, n))
|
||||||
of nkEmpty: discard
|
of nkEmpty: discard
|
||||||
|
|
@ -1079,7 +1079,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
|
||||||
elif n[0].kind in {nkOpenSymChoice, nkClosedSymChoice}: n[0][0].sym.name
|
elif n[0].kind in {nkOpenSymChoice, nkClosedSymChoice}: n[0][0].sym.name
|
||||||
else: nil
|
else: nil
|
||||||
var n_next = n[1]
|
var n_next = n[1]
|
||||||
while n_next.kind in {nkCheckedFieldExpr, nkHiddenAddr, nkHiddenDeref,
|
while n_next.kind in {nkCheckedFieldExpr, nkHiddenAddr, nkHiddenDeref,
|
||||||
nkStringToCString, nkCStringToString} and n_next.len > 0:
|
nkStringToCString, nkCStringToString} and n_next.len > 0:
|
||||||
n_next = n_next[0]
|
n_next = n_next[0]
|
||||||
if n_next.kind == nkPrefix or (opr != nil and renderer.isKeyword(opr)):
|
if n_next.kind == nkPrefix or (opr != nil and renderer.isKeyword(opr)):
|
||||||
|
|
|
||||||
|
|
@ -66,29 +66,19 @@ type
|
||||||
Rope* = ref RopeObj
|
Rope* = ref RopeObj
|
||||||
RopeObj*{.acyclic.} = object of RootObj # the empty rope is represented
|
RopeObj*{.acyclic.} = object of RootObj # the empty rope is represented
|
||||||
# by nil to safe space
|
# by nil to safe space
|
||||||
left*, right*: Rope
|
left, right: Rope
|
||||||
length*: int
|
L: int # <= 0 if a leaf
|
||||||
data*: string # != nil if a leaf
|
data*: string
|
||||||
|
|
||||||
proc len*(a: Rope): int =
|
proc len*(a: Rope): int =
|
||||||
## the rope's length
|
## the rope's length
|
||||||
if a == nil: result = 0
|
if a == nil: result = 0
|
||||||
else: result = a.length
|
else: result = abs a.L
|
||||||
|
|
||||||
proc newRope(data: string = nil): Rope =
|
proc newRope(data: string = ""): Rope =
|
||||||
new(result)
|
new(result)
|
||||||
if data != nil:
|
result.L = -len(data)
|
||||||
result.length = len(data)
|
result.data = data
|
||||||
result.data = data
|
|
||||||
|
|
||||||
proc newMutableRope*(capacity = 30): Rope =
|
|
||||||
## creates a new rope that supports direct modifications of the rope's
|
|
||||||
## 'data' and 'length' fields.
|
|
||||||
new(result)
|
|
||||||
result.data = newStringOfCap(capacity)
|
|
||||||
|
|
||||||
proc freezeMutableRope*(r: Rope) {.inline.} =
|
|
||||||
r.length = r.data.len
|
|
||||||
|
|
||||||
var
|
var
|
||||||
cache: array[0..2048*2 - 1, Rope] # XXX Global here!
|
cache: array[0..2048*2 - 1, Rope] # XXX Global here!
|
||||||
|
|
@ -147,7 +137,7 @@ proc `&`*(a, b: Rope): Rope =
|
||||||
result = a
|
result = a
|
||||||
else:
|
else:
|
||||||
result = newRope()
|
result = newRope()
|
||||||
result.length = a.length + b.length
|
result.L = abs(a.L) + abs(b.L)
|
||||||
result.left = a
|
result.left = a
|
||||||
result.right = b
|
result.right = b
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
|
||||||
template cbos(name, body) {.dirty.} =
|
template cbos(name, body) {.dirty.} =
|
||||||
result.registerCallback "stdlib.system." & astToStr(name),
|
result.registerCallback "stdlib.system." & astToStr(name),
|
||||||
proc (a: VmArgs) =
|
proc (a: VmArgs) =
|
||||||
errorMsg = nil
|
errorMsg = ""
|
||||||
try:
|
try:
|
||||||
body
|
body
|
||||||
except OSError:
|
except OSError:
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ proc commonType*(x, y: PType): PType =
|
||||||
elif b.kind == tyStmt: result = b
|
elif b.kind == tyStmt: result = b
|
||||||
elif a.kind == tyTypeDesc:
|
elif a.kind == tyTypeDesc:
|
||||||
# turn any concrete typedesc into the abstract typedesc type
|
# turn any concrete typedesc into the abstract typedesc type
|
||||||
if a.sons == nil: result = a
|
if a.len == 0: result = a
|
||||||
else:
|
else:
|
||||||
result = newType(tyTypeDesc, a.owner)
|
result = newType(tyTypeDesc, a.owner)
|
||||||
rawAddSon(result, newType(tyNone, a.owner))
|
rawAddSon(result, newType(tyNone, a.owner))
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode,
|
||||||
continue
|
continue
|
||||||
determineType(c, sym)
|
determineType(c, sym)
|
||||||
initCandidate(c, z, sym, initialBinding, scope, diagnosticsFlag)
|
initCandidate(c, z, sym, initialBinding, scope, diagnosticsFlag)
|
||||||
if c.currentScope.symbols.counter == counterInitial or syms != nil:
|
if c.currentScope.symbols.counter == counterInitial or syms.len != 0:
|
||||||
matches(c, n, orig, z)
|
matches(c, n, orig, z)
|
||||||
if z.state == csMatch:
|
if z.state == csMatch:
|
||||||
#if sym.name.s == "==" and (n.info ?? "temp3"):
|
#if sym.name.s == "==" and (n.info ?? "temp3"):
|
||||||
|
|
@ -237,7 +237,7 @@ proc bracketNotFoundError(c: PContext; n: PNode) =
|
||||||
if symx.kind in routineKinds:
|
if symx.kind in routineKinds:
|
||||||
errors.add(CandidateError(sym: symx,
|
errors.add(CandidateError(sym: symx,
|
||||||
unmatchedVarParam: 0, firstMismatch: 0,
|
unmatchedVarParam: 0, firstMismatch: 0,
|
||||||
diagnostics: nil,
|
diagnostics: @[],
|
||||||
enabled: false))
|
enabled: false))
|
||||||
symx = nextOverloadIter(o, c, headSymbol)
|
symx = nextOverloadIter(o, c, headSymbol)
|
||||||
if errors.len == 0:
|
if errors.len == 0:
|
||||||
|
|
@ -455,7 +455,7 @@ proc tryDeref(n: PNode): PNode =
|
||||||
|
|
||||||
proc semOverloadedCall(c: PContext, n, nOrig: PNode,
|
proc semOverloadedCall(c: PContext, n, nOrig: PNode,
|
||||||
filter: TSymKinds, flags: TExprFlags): PNode =
|
filter: TSymKinds, flags: TExprFlags): PNode =
|
||||||
var errors: CandidateErrors = if efExplain in flags: @[] else: nil
|
var errors: CandidateErrors = @[] # if efExplain in flags: @[] else: nil
|
||||||
var r = resolveOverloads(c, n, nOrig, filter, flags, errors, efExplain in flags)
|
var r = resolveOverloads(c, n, nOrig, filter, flags, errors, efExplain in flags)
|
||||||
if r.state == csMatch:
|
if r.state == csMatch:
|
||||||
# this may be triggered, when the explain pragma is used
|
# this may be triggered, when the explain pragma is used
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ type
|
||||||
# in standalone ``except`` and ``finally``
|
# in standalone ``except`` and ``finally``
|
||||||
next*: PProcCon # used for stacking procedure contexts
|
next*: PProcCon # used for stacking procedure contexts
|
||||||
wasForwarded*: bool # whether the current proc has a separate header
|
wasForwarded*: bool # whether the current proc has a separate header
|
||||||
|
mappingExists*: bool
|
||||||
mapping*: TIdTable
|
mapping*: TIdTable
|
||||||
|
|
||||||
TMatchedConcept* = object
|
TMatchedConcept* = object
|
||||||
|
|
@ -176,12 +177,14 @@ proc lastOptionEntry*(c: PContext): POptionEntry =
|
||||||
proc popProcCon*(c: PContext) {.inline.} = c.p = c.p.next
|
proc popProcCon*(c: PContext) {.inline.} = c.p = c.p.next
|
||||||
|
|
||||||
proc put*(p: PProcCon; key, val: PSym) =
|
proc put*(p: PProcCon; key, val: PSym) =
|
||||||
if p.mapping.data == nil: initIdTable(p.mapping)
|
if not p.mappingExists:
|
||||||
|
initIdTable(p.mapping)
|
||||||
|
p.mappingExists = true
|
||||||
#echo "put into table ", key.info
|
#echo "put into table ", key.info
|
||||||
p.mapping.idTablePut(key, val)
|
p.mapping.idTablePut(key, val)
|
||||||
|
|
||||||
proc get*(p: PProcCon; key: PSym): PSym =
|
proc get*(p: PProcCon; key: PSym): PSym =
|
||||||
if p.mapping.data == nil: return nil
|
if not p.mappingExists: return nil
|
||||||
result = PSym(p.mapping.idTableGet(key))
|
result = PSym(p.mapping.idTableGet(key))
|
||||||
|
|
||||||
proc getGenSym*(c: PContext; s: PSym): PSym =
|
proc getGenSym*(c: PContext; s: PSym): PSym =
|
||||||
|
|
|
||||||
|
|
@ -97,10 +97,9 @@ proc sameInstantiation(a, b: TInstantiation): bool =
|
||||||
|
|
||||||
proc genericCacheGet(genericSym: PSym, entry: TInstantiation;
|
proc genericCacheGet(genericSym: PSym, entry: TInstantiation;
|
||||||
id: CompilesId): PSym =
|
id: CompilesId): PSym =
|
||||||
if genericSym.procInstCache != nil:
|
for inst in genericSym.procInstCache:
|
||||||
for inst in genericSym.procInstCache:
|
if inst.compilesId == id and sameInstantiation(entry, inst[]):
|
||||||
if inst.compilesId == id and sameInstantiation(entry, inst[]):
|
return inst.sym
|
||||||
return inst.sym
|
|
||||||
|
|
||||||
when false:
|
when false:
|
||||||
proc `$`(x: PSym): string =
|
proc `$`(x: PSym): string =
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ proc missingMandatoryFields(c: PContext, fieldsRecList, initExpr: PNode): string
|
||||||
if {tfNotNil, tfNeedsInit} * r.sym.typ.flags != {}:
|
if {tfNotNil, tfNeedsInit} * r.sym.typ.flags != {}:
|
||||||
let assignment = locateFieldInInitExpr(c, r.sym, initExpr)
|
let assignment = locateFieldInInitExpr(c, r.sym, initExpr)
|
||||||
if assignment == nil:
|
if assignment == nil:
|
||||||
if result == nil:
|
if result.len == 0:
|
||||||
result = r.sym.name.s
|
result = r.sym.name.s
|
||||||
else:
|
else:
|
||||||
result.add ", "
|
result.add ", "
|
||||||
|
|
@ -129,7 +129,7 @@ proc missingMandatoryFields(c: PContext, fieldsRecList, initExpr: PNode): string
|
||||||
|
|
||||||
proc checkForMissingFields(c: PContext, recList, initExpr: PNode) =
|
proc checkForMissingFields(c: PContext, recList, initExpr: PNode) =
|
||||||
let missing = missingMandatoryFields(c, recList, initExpr)
|
let missing = missingMandatoryFields(c, recList, initExpr)
|
||||||
if missing != nil:
|
if missing.len > 0:
|
||||||
localError(c.config, initExpr.info, "fields not initialized: $1.", [missing])
|
localError(c.config, initExpr.info, "fields not initialized: $1.", [missing])
|
||||||
|
|
||||||
proc semConstructFields(c: PContext, recNode: PNode,
|
proc semConstructFields(c: PContext, recNode: PNode,
|
||||||
|
|
|
||||||
|
|
@ -970,7 +970,10 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
|
||||||
var body = s.typ.lastSon
|
var body = s.typ.lastSon
|
||||||
if body.kind == tyObject:
|
if body.kind == tyObject:
|
||||||
# erases all declared fields
|
# erases all declared fields
|
||||||
body.n.sons = nil
|
when defined(nimNoNilSeqs):
|
||||||
|
body.n.sons = @[]
|
||||||
|
else:
|
||||||
|
body.n.sons = nil
|
||||||
|
|
||||||
popOwner(c)
|
popOwner(c)
|
||||||
closeScope(c)
|
closeScope(c)
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,8 @@ proc searchInstTypes*(key: PType): PType =
|
||||||
if not (genericTyp.kind == tyGenericBody and
|
if not (genericTyp.kind == tyGenericBody and
|
||||||
key.sons[0] == genericTyp and genericTyp.sym != nil): return
|
key.sons[0] == genericTyp and genericTyp.sym != nil): return
|
||||||
|
|
||||||
if genericTyp.sym.typeInstCache == nil:
|
when not defined(nimNoNilSeqs):
|
||||||
return
|
if genericTyp.sym.typeInstCache == nil: return
|
||||||
|
|
||||||
for inst in genericTyp.sym.typeInstCache:
|
for inst in genericTyp.sym.typeInstCache:
|
||||||
if inst.id == key.id: return inst
|
if inst.id == key.id: return inst
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ proc initCandidate*(ctx: PContext, c: var TCandidate, callee: PSym,
|
||||||
c.calleeScope = 1
|
c.calleeScope = 1
|
||||||
else:
|
else:
|
||||||
c.calleeScope = calleeScope
|
c.calleeScope = calleeScope
|
||||||
c.diagnostics = if diagnosticsEnabled: @[] else: nil
|
c.diagnostics = @[] # if diagnosticsEnabled: @[] else: nil
|
||||||
c.diagnosticsEnabled = diagnosticsEnabled
|
c.diagnosticsEnabled = diagnosticsEnabled
|
||||||
c.magic = c.calleeSym.magic
|
c.magic = c.calleeSym.magic
|
||||||
initIdTable(c.bindings)
|
initIdTable(c.bindings)
|
||||||
|
|
@ -535,6 +535,12 @@ proc recordRel(c: var TCandidate, f, a: PType): TTypeRelation =
|
||||||
proc allowsNil(f: PType): TTypeRelation {.inline.} =
|
proc allowsNil(f: PType): TTypeRelation {.inline.} =
|
||||||
result = if tfNotNil notin f.flags: isSubtype else: isNone
|
result = if tfNotNil notin f.flags: isSubtype else: isNone
|
||||||
|
|
||||||
|
proc allowsNilDeprecated(c: TCandidate, f: PType): TTypeRelation =
|
||||||
|
if optNilSeqs in c.c.config.options:
|
||||||
|
result = allowsNil(f)
|
||||||
|
else:
|
||||||
|
result = isNone
|
||||||
|
|
||||||
proc inconsistentVarTypes(f, a: PType): bool {.inline.} =
|
proc inconsistentVarTypes(f, a: PType): bool {.inline.} =
|
||||||
result = f.kind != a.kind and (f.kind in {tyVar, tyLent} or a.kind in {tyVar, tyLent})
|
result = f.kind != a.kind and (f.kind in {tyVar, tyLent} or a.kind in {tyVar, tyLent})
|
||||||
|
|
||||||
|
|
@ -741,7 +747,7 @@ proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType =
|
||||||
diagnostics = @[]
|
diagnostics = @[]
|
||||||
flags = {efExplain}
|
flags = {efExplain}
|
||||||
m.c.config.writelnHook = proc (s: string) =
|
m.c.config.writelnHook = proc (s: string) =
|
||||||
if errorPrefix == nil: errorPrefix = typeClass.sym.name.s & ":"
|
if errorPrefix.len == 0: errorPrefix = typeClass.sym.name.s & ":"
|
||||||
let msg = s.replace("Error:", errorPrefix)
|
let msg = s.replace("Error:", errorPrefix)
|
||||||
if oldWriteHook != nil: oldWriteHook msg
|
if oldWriteHook != nil: oldWriteHook msg
|
||||||
diagnostics.add msg
|
diagnostics.add msg
|
||||||
|
|
@ -1253,7 +1259,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
|
||||||
result = isNone
|
result = isNone
|
||||||
elif tfNotNil in f.flags and tfNotNil notin a.flags:
|
elif tfNotNil in f.flags and tfNotNil notin a.flags:
|
||||||
result = isNilConversion
|
result = isNilConversion
|
||||||
of tyNil: result = f.allowsNil
|
of tyNil: result = allowsNilDeprecated(c, f)
|
||||||
else: discard
|
else: discard
|
||||||
of tyOrdinal:
|
of tyOrdinal:
|
||||||
if isOrdinalType(a):
|
if isOrdinalType(a):
|
||||||
|
|
@ -1338,7 +1344,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
|
||||||
result = isNilConversion
|
result = isNilConversion
|
||||||
else:
|
else:
|
||||||
result = isEqual
|
result = isEqual
|
||||||
of tyNil: result = f.allowsNil
|
of tyNil: result = allowsNilDeprecated(c, f)
|
||||||
else: discard
|
else: discard
|
||||||
of tyCString:
|
of tyCString:
|
||||||
# conversion from string to cstring is automatic:
|
# conversion from string to cstring is automatic:
|
||||||
|
|
@ -1349,7 +1355,11 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
|
||||||
else:
|
else:
|
||||||
result = isEqual
|
result = isEqual
|
||||||
of tyNil: result = f.allowsNil
|
of tyNil: result = f.allowsNil
|
||||||
of tyString: result = isConvertible
|
of tyString:
|
||||||
|
if optNilSeqs in c.c.config.options or c.magic != mEqCString:
|
||||||
|
result = isConvertible
|
||||||
|
else:
|
||||||
|
result = isNone
|
||||||
of tyPtr:
|
of tyPtr:
|
||||||
# ptr[Tag, char] is not convertible to 'cstring' for now:
|
# ptr[Tag, char] is not convertible to 'cstring' for now:
|
||||||
if a.len == 1:
|
if a.len == 1:
|
||||||
|
|
@ -1612,7 +1622,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
|
||||||
if f.sonsLen == 0:
|
if f.sonsLen == 0:
|
||||||
result = isGeneric
|
result = isGeneric
|
||||||
else:
|
else:
|
||||||
internalAssert c.c.graph.config, a.sons != nil and a.sons.len > 0
|
internalAssert c.c.graph.config, a.len > 0
|
||||||
c.typedescMatched = true
|
c.typedescMatched = true
|
||||||
var aa = a
|
var aa = a
|
||||||
while aa.kind in {tyTypeDesc, tyGenericParam} and aa.len > 0:
|
while aa.kind in {tyTypeDesc, tyGenericParam} and aa.len > 0:
|
||||||
|
|
|
||||||
|
|
@ -428,7 +428,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||||
result = t.sym.name.s & " literal(" & $t.n.intVal & ")"
|
result = t.sym.name.s & " literal(" & $t.n.intVal & ")"
|
||||||
elif prefer in {preferName, preferTypeName} or t.sym.owner.isNil:
|
elif prefer in {preferName, preferTypeName} or t.sym.owner.isNil:
|
||||||
result = t.sym.name.s
|
result = t.sym.name.s
|
||||||
if t.kind == tyGenericParam and t.sons != nil and t.sonsLen > 0:
|
if t.kind == tyGenericParam and t.sonsLen > 0:
|
||||||
result.add ": "
|
result.add ": "
|
||||||
var first = true
|
var first = true
|
||||||
for son in t.sons:
|
for son in t.sons:
|
||||||
|
|
@ -1528,10 +1528,9 @@ proc isCompileTimeOnly*(t: PType): bool {.inline.} =
|
||||||
|
|
||||||
proc containsCompileTimeOnly*(t: PType): bool =
|
proc containsCompileTimeOnly*(t: PType): bool =
|
||||||
if isCompileTimeOnly(t): return true
|
if isCompileTimeOnly(t): return true
|
||||||
if t.sons != nil:
|
for i in 0 ..< t.sonsLen:
|
||||||
for i in 0 ..< t.sonsLen:
|
if t.sons[i] != nil and isCompileTimeOnly(t.sons[i]):
|
||||||
if t.sons[i] != nil and isCompileTimeOnly(t.sons[i]):
|
return true
|
||||||
return true
|
|
||||||
return false
|
return false
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ proc matchOrFind(buf: cstring, pattern: Regex, matches: var openArray[string],
|
||||||
var b = rawMatches[i * 2 + 1]
|
var b = rawMatches[i * 2 + 1]
|
||||||
if a >= 0'i32:
|
if a >= 0'i32:
|
||||||
matches[i-1] = bufSubstr(buf, int(a), int(b))
|
matches[i-1] = bufSubstr(buf, int(a), int(b))
|
||||||
else: matches[i-1] = nil
|
else: matches[i-1] = ""
|
||||||
return rawMatches[1] - rawMatches[0]
|
return rawMatches[1] - rawMatches[0]
|
||||||
|
|
||||||
proc findBounds*(buf: cstring, pattern: Regex, matches: var openArray[string],
|
proc findBounds*(buf: cstring, pattern: Regex, matches: var openArray[string],
|
||||||
|
|
@ -133,7 +133,7 @@ proc findBounds*(buf: cstring, pattern: Regex, matches: var openArray[string],
|
||||||
var a = rawMatches[i * 2]
|
var a = rawMatches[i * 2]
|
||||||
var b = rawMatches[i * 2 + 1]
|
var b = rawMatches[i * 2 + 1]
|
||||||
if a >= 0'i32: matches[i-1] = bufSubstr(buf, int(a), int(b))
|
if a >= 0'i32: matches[i-1] = bufSubstr(buf, int(a), int(b))
|
||||||
else: matches[i-1] = nil
|
else: matches[i-1] = ""
|
||||||
return (rawMatches[0].int, rawMatches[1].int - 1)
|
return (rawMatches[0].int, rawMatches[1].int - 1)
|
||||||
|
|
||||||
proc findBounds*(s: string, pattern: Regex, matches: var openArray[string],
|
proc findBounds*(s: string, pattern: Regex, matches: var openArray[string],
|
||||||
|
|
@ -287,7 +287,7 @@ proc find*(buf: cstring, pattern: Regex, matches: var openArray[string],
|
||||||
var a = rawMatches[i * 2]
|
var a = rawMatches[i * 2]
|
||||||
var b = rawMatches[i * 2 + 1]
|
var b = rawMatches[i * 2 + 1]
|
||||||
if a >= 0'i32: matches[i-1] = bufSubstr(buf, int(a), int(b))
|
if a >= 0'i32: matches[i-1] = bufSubstr(buf, int(a), int(b))
|
||||||
else: matches[i-1] = nil
|
else: matches[i-1] = ""
|
||||||
return rawMatches[0]
|
return rawMatches[0]
|
||||||
|
|
||||||
proc find*(s: string, pattern: Regex, matches: var openArray[string],
|
proc find*(s: string, pattern: Regex, matches: var openArray[string],
|
||||||
|
|
@ -456,8 +456,6 @@ proc replacef*(s: string, sub: Regex, by: string): string =
|
||||||
while true:
|
while true:
|
||||||
var match = findBounds(s, sub, caps, prev)
|
var match = findBounds(s, sub, caps, prev)
|
||||||
if match.first < 0: break
|
if match.first < 0: break
|
||||||
assert result != nil
|
|
||||||
assert s != nil
|
|
||||||
add(result, substr(s, prev, match.first-1))
|
add(result, substr(s, prev, match.first-1))
|
||||||
addf(result, by, caps)
|
addf(result, by, caps)
|
||||||
prev = match.last + 1
|
prev = match.last + 1
|
||||||
|
|
|
||||||
|
|
@ -293,9 +293,9 @@ proc renderRstToJsonNode(node: PRstNode): JsonNode =
|
||||||
(key: "kind", val: %($node.kind)),
|
(key: "kind", val: %($node.kind)),
|
||||||
(key: "level", val: %BiggestInt(node.level))
|
(key: "level", val: %BiggestInt(node.level))
|
||||||
]
|
]
|
||||||
if node.text != nil:
|
if node.text.len > 0:
|
||||||
result.add("text", %node.text)
|
result.add("text", %node.text)
|
||||||
if node.sons != nil and len(node.sons) > 0:
|
if len(node.sons) > 0:
|
||||||
var accm = newSeq[JsonNode](len(node.sons))
|
var accm = newSeq[JsonNode](len(node.sons))
|
||||||
for i, son in node.sons:
|
for i, son in node.sons:
|
||||||
accm[i] = renderRstToJsonNode(son)
|
accm[i] = renderRstToJsonNode(son)
|
||||||
|
|
|
||||||
|
|
@ -397,9 +397,9 @@ proc hash(x: IndexEntry): Hash =
|
||||||
proc `<-`(a: var IndexEntry, b: IndexEntry) =
|
proc `<-`(a: var IndexEntry, b: IndexEntry) =
|
||||||
shallowCopy a.keyword, b.keyword
|
shallowCopy a.keyword, b.keyword
|
||||||
shallowCopy a.link, b.link
|
shallowCopy a.link, b.link
|
||||||
if b.linkTitle.isNil: a.linkTitle = nil
|
if b.linkTitle.isNil: a.linkTitle = ""
|
||||||
else: shallowCopy a.linkTitle, b.linkTitle
|
else: shallowCopy a.linkTitle, b.linkTitle
|
||||||
if b.linkDesc.isNil: a.linkDesc = nil
|
if b.linkDesc.isNil: a.linkDesc = ""
|
||||||
else: shallowCopy a.linkDesc, b.linkDesc
|
else: shallowCopy a.linkDesc, b.linkDesc
|
||||||
|
|
||||||
proc sortIndex(a: var openArray[IndexEntry]) =
|
proc sortIndex(a: var openArray[IndexEntry]) =
|
||||||
|
|
@ -607,8 +607,8 @@ proc readIndexDir(dir: string):
|
||||||
fileEntries[F].linkTitle = extraCols[1].unquoteIndexColumn
|
fileEntries[F].linkTitle = extraCols[1].unquoteIndexColumn
|
||||||
fileEntries[F].linkDesc = extraCols[2].unquoteIndexColumn
|
fileEntries[F].linkDesc = extraCols[2].unquoteIndexColumn
|
||||||
else:
|
else:
|
||||||
fileEntries[F].linkTitle = nil
|
fileEntries[F].linkTitle = ""
|
||||||
fileEntries[F].linkDesc = nil
|
fileEntries[F].linkDesc = ""
|
||||||
inc F
|
inc F
|
||||||
# Depending on type add this to the list of symbols or table of APIs.
|
# Depending on type add this to the list of symbols or table of APIs.
|
||||||
if title.keyword.isNil:
|
if title.keyword.isNil:
|
||||||
|
|
@ -656,7 +656,6 @@ proc mergeIndexes*(dir: string): string =
|
||||||
## Returns the merged and sorted indices into a single HTML block which can
|
## Returns the merged and sorted indices into a single HTML block which can
|
||||||
## be further embedded into nimdoc templates.
|
## be further embedded into nimdoc templates.
|
||||||
var (modules, symbols, docs) = readIndexDir(dir)
|
var (modules, symbols, docs) = readIndexDir(dir)
|
||||||
assert(not symbols.isNil)
|
|
||||||
|
|
||||||
result = ""
|
result = ""
|
||||||
# Generate a quick jump list of documents.
|
# Generate a quick jump list of documents.
|
||||||
|
|
|
||||||
|
|
@ -219,10 +219,10 @@ proc getHint(entry: StackTraceEntry): string =
|
||||||
## We try to provide some hints about stack trace entries that the user
|
## We try to provide some hints about stack trace entries that the user
|
||||||
## may not be familiar with, in particular calls inside the stdlib.
|
## may not be familiar with, in particular calls inside the stdlib.
|
||||||
result = ""
|
result = ""
|
||||||
if entry.procname == "processPendingCallbacks":
|
if entry.procname == cstring"processPendingCallbacks":
|
||||||
if cmpIgnoreStyle(entry.filename, "asyncdispatch.nim") == 0:
|
if cmpIgnoreStyle(entry.filename, "asyncdispatch.nim") == 0:
|
||||||
return "Executes pending callbacks"
|
return "Executes pending callbacks"
|
||||||
elif entry.procname == "poll":
|
elif entry.procname == cstring"poll":
|
||||||
if cmpIgnoreStyle(entry.filename, "asyncdispatch.nim") == 0:
|
if cmpIgnoreStyle(entry.filename, "asyncdispatch.nim") == 0:
|
||||||
return "Processes asynchronous completion events"
|
return "Processes asynchronous completion events"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -655,7 +655,7 @@ when defineSsl:
|
||||||
|
|
||||||
proc wrapConnectedSocket*(ctx: SslContext, socket: AsyncSocket,
|
proc wrapConnectedSocket*(ctx: SslContext, socket: AsyncSocket,
|
||||||
handshake: SslHandshakeType,
|
handshake: SslHandshakeType,
|
||||||
hostname: string = nil) =
|
hostname: string = "") =
|
||||||
## Wraps a connected socket in an SSL context. This function effectively
|
## Wraps a connected socket in an SSL context. This function effectively
|
||||||
## turns ``socket`` into an SSL socket.
|
## turns ``socket`` into an SSL socket.
|
||||||
## ``hostname`` should be specified so that the client knows which hostname
|
## ``hostname`` should be specified so that the client knows which hostname
|
||||||
|
|
@ -670,7 +670,7 @@ when defineSsl:
|
||||||
|
|
||||||
case handshake
|
case handshake
|
||||||
of handshakeAsClient:
|
of handshakeAsClient:
|
||||||
if not hostname.isNil and not isIpAddress(hostname):
|
if hostname.len > 0 and not isIpAddress(hostname):
|
||||||
# Set the SNI address for this connection. This call can fail if
|
# Set the SNI address for this connection. This call can fail if
|
||||||
# we're not using TLSv1+.
|
# we're not using TLSv1+.
|
||||||
discard SSL_set_tlsext_host_name(socket.sslHandle, hostname)
|
discard SSL_set_tlsext_host_name(socket.sslHandle, hostname)
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,7 @@ proc missingOrExcl*(s: var IntSet, key: int) : bool =
|
||||||
## `key` is removed from `s` and false is returned.
|
## `key` is removed from `s` and false is returned.
|
||||||
var count = s.elems
|
var count = s.elems
|
||||||
exclImpl(s, key)
|
exclImpl(s, key)
|
||||||
result = count == s.elems
|
result = count == s.elems
|
||||||
|
|
||||||
proc containsOrIncl*(s: var IntSet, key: int): bool =
|
proc containsOrIncl*(s: var IntSet, key: int): bool =
|
||||||
## returns true if `s` contains `key`, otherwise `key` is included in `s`
|
## returns true if `s` contains `key`, otherwise `key` is included in `s`
|
||||||
|
|
@ -212,7 +212,10 @@ proc initIntSet*: IntSet =
|
||||||
|
|
||||||
#newSeq(result.data, InitIntSetSize)
|
#newSeq(result.data, InitIntSetSize)
|
||||||
#result.max = InitIntSetSize-1
|
#result.max = InitIntSetSize-1
|
||||||
result.data = nil
|
when defined(nimNoNilSeqs):
|
||||||
|
result.data = @[]
|
||||||
|
else:
|
||||||
|
result.data = nil
|
||||||
result.max = 0
|
result.max = 0
|
||||||
result.counter = 0
|
result.counter = 0
|
||||||
result.head = nil
|
result.head = nil
|
||||||
|
|
@ -222,7 +225,10 @@ proc clear*(result: var IntSet) =
|
||||||
#setLen(result.data, InitIntSetSize)
|
#setLen(result.data, InitIntSetSize)
|
||||||
#for i in 0..InitIntSetSize-1: result.data[i] = nil
|
#for i in 0..InitIntSetSize-1: result.data[i] = nil
|
||||||
#result.max = InitIntSetSize-1
|
#result.max = InitIntSetSize-1
|
||||||
result.data = nil
|
when defined(nimNoNilSeqs):
|
||||||
|
result.data = @[]
|
||||||
|
else:
|
||||||
|
result.data = nil
|
||||||
result.max = 0
|
result.max = 0
|
||||||
result.counter = 0
|
result.counter = 0
|
||||||
result.head = nil
|
result.head = nil
|
||||||
|
|
@ -234,7 +240,10 @@ proc assign*(dest: var IntSet, src: IntSet) =
|
||||||
## copies `src` to `dest`. `dest` does not need to be initialized by
|
## copies `src` to `dest`. `dest` does not need to be initialized by
|
||||||
## `initIntSet`.
|
## `initIntSet`.
|
||||||
if src.elems <= src.a.len:
|
if src.elems <= src.a.len:
|
||||||
dest.data = nil
|
when defined(nimNoNilSeqs):
|
||||||
|
dest.data = @[]
|
||||||
|
else:
|
||||||
|
dest.data = nil
|
||||||
dest.max = 0
|
dest.max = 0
|
||||||
dest.counter = src.counter
|
dest.counter = src.counter
|
||||||
dest.head = nil
|
dest.head = nil
|
||||||
|
|
@ -247,11 +256,9 @@ proc assign*(dest: var IntSet, src: IntSet) =
|
||||||
|
|
||||||
var it = src.head
|
var it = src.head
|
||||||
while it != nil:
|
while it != nil:
|
||||||
|
|
||||||
var h = it.key and dest.max
|
var h = it.key and dest.max
|
||||||
while dest.data[h] != nil: h = nextTry(h, dest.max)
|
while dest.data[h] != nil: h = nextTry(h, dest.max)
|
||||||
assert(dest.data[h] == nil)
|
assert(dest.data[h] == nil)
|
||||||
|
|
||||||
var n: PTrunk
|
var n: PTrunk
|
||||||
new(n)
|
new(n)
|
||||||
n.next = dest.head
|
n.next = dest.head
|
||||||
|
|
@ -259,7 +266,6 @@ proc assign*(dest: var IntSet, src: IntSet) =
|
||||||
n.bits = it.bits
|
n.bits = it.bits
|
||||||
dest.head = n
|
dest.head = n
|
||||||
dest.data[h] = n
|
dest.data[h] = n
|
||||||
|
|
||||||
it = it.next
|
it = it.next
|
||||||
|
|
||||||
proc union*(s1, s2: IntSet): IntSet =
|
proc union*(s1, s2: IntSet): IntSet =
|
||||||
|
|
@ -315,7 +321,7 @@ proc len*(s: IntSet): int {.inline.} =
|
||||||
for _ in s:
|
for _ in s:
|
||||||
inc(result)
|
inc(result)
|
||||||
|
|
||||||
proc card*(s: IntSet): int {.inline.} =
|
proc card*(s: IntSet): int {.inline.} =
|
||||||
## alias for `len() <#len>` _.
|
## alias for `len() <#len>` _.
|
||||||
result = s.len()
|
result = s.len()
|
||||||
|
|
||||||
|
|
@ -361,7 +367,7 @@ when isMainModule:
|
||||||
x.incl(1056)
|
x.incl(1056)
|
||||||
|
|
||||||
x.incl(1044)
|
x.incl(1044)
|
||||||
x.excl(1044)
|
x.excl(1044)
|
||||||
|
|
||||||
assert x.containsOrIncl(888) == false
|
assert x.containsOrIncl(888) == false
|
||||||
assert 888 in x
|
assert 888 in x
|
||||||
|
|
|
||||||
|
|
@ -231,7 +231,7 @@ proc newSocket*(domain: Domain = AF_INET, sockType: SockType = SOCK_STREAM,
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
result = newSocket(fd, domain, sockType, protocol, buffered)
|
result = newSocket(fd, domain, sockType, protocol, buffered)
|
||||||
|
|
||||||
proc parseIPv4Address(address_str: string): IpAddress =
|
proc parseIPv4Address(addressStr: string): IpAddress =
|
||||||
## Parses IPv4 adresses
|
## Parses IPv4 adresses
|
||||||
## Raises EInvalidValue on errors
|
## Raises EInvalidValue on errors
|
||||||
var
|
var
|
||||||
|
|
@ -241,15 +241,15 @@ proc parseIPv4Address(address_str: string): IpAddress =
|
||||||
|
|
||||||
result.family = IpAddressFamily.IPv4
|
result.family = IpAddressFamily.IPv4
|
||||||
|
|
||||||
for i in 0 .. high(address_str):
|
for i in 0 .. high(addressStr):
|
||||||
if address_str[i] in strutils.Digits: # Character is a number
|
if addressStr[i] in strutils.Digits: # Character is a number
|
||||||
currentByte = currentByte * 10 +
|
currentByte = currentByte * 10 +
|
||||||
cast[uint16](ord(address_str[i]) - ord('0'))
|
cast[uint16](ord(addressStr[i]) - ord('0'))
|
||||||
if currentByte > 255'u16:
|
if currentByte > 255'u16:
|
||||||
raise newException(ValueError,
|
raise newException(ValueError,
|
||||||
"Invalid IP Address. Value is out of range")
|
"Invalid IP Address. Value is out of range")
|
||||||
seperatorValid = true
|
seperatorValid = true
|
||||||
elif address_str[i] == '.': # IPv4 address separator
|
elif addressStr[i] == '.': # IPv4 address separator
|
||||||
if not seperatorValid or byteCount >= 3:
|
if not seperatorValid or byteCount >= 3:
|
||||||
raise newException(ValueError,
|
raise newException(ValueError,
|
||||||
"Invalid IP Address. The address consists of too many groups")
|
"Invalid IP Address. The address consists of too many groups")
|
||||||
|
|
@ -265,11 +265,11 @@ proc parseIPv4Address(address_str: string): IpAddress =
|
||||||
raise newException(ValueError, "Invalid IP Address")
|
raise newException(ValueError, "Invalid IP Address")
|
||||||
result.address_v4[byteCount] = cast[uint8](currentByte)
|
result.address_v4[byteCount] = cast[uint8](currentByte)
|
||||||
|
|
||||||
proc parseIPv6Address(address_str: string): IpAddress =
|
proc parseIPv6Address(addressStr: string): IpAddress =
|
||||||
## Parses IPv6 adresses
|
## Parses IPv6 adresses
|
||||||
## Raises EInvalidValue on errors
|
## Raises EInvalidValue on errors
|
||||||
result.family = IpAddressFamily.IPv6
|
result.family = IpAddressFamily.IPv6
|
||||||
if address_str.len < 2:
|
if addressStr.len < 2:
|
||||||
raise newException(ValueError, "Invalid IP Address")
|
raise newException(ValueError, "Invalid IP Address")
|
||||||
|
|
||||||
var
|
var
|
||||||
|
|
@ -282,7 +282,7 @@ proc parseIPv6Address(address_str: string): IpAddress =
|
||||||
v4StartPos = -1
|
v4StartPos = -1
|
||||||
byteCount = 0
|
byteCount = 0
|
||||||
|
|
||||||
for i,c in address_str:
|
for i,c in addressStr:
|
||||||
if c == ':':
|
if c == ':':
|
||||||
if not seperatorValid:
|
if not seperatorValid:
|
||||||
raise newException(ValueError,
|
raise newException(ValueError,
|
||||||
|
|
@ -293,7 +293,7 @@ proc parseIPv6Address(address_str: string): IpAddress =
|
||||||
"Invalid IP Address. Address contains more than one \"::\" seperator")
|
"Invalid IP Address. Address contains more than one \"::\" seperator")
|
||||||
dualColonGroup = groupCount
|
dualColonGroup = groupCount
|
||||||
seperatorValid = false
|
seperatorValid = false
|
||||||
elif i != 0 and i != high(address_str):
|
elif i != 0 and i != high(addressStr):
|
||||||
if groupCount >= 8:
|
if groupCount >= 8:
|
||||||
raise newException(ValueError,
|
raise newException(ValueError,
|
||||||
"Invalid IP Address. The address consists of too many groups")
|
"Invalid IP Address. The address consists of too many groups")
|
||||||
|
|
@ -303,11 +303,11 @@ proc parseIPv6Address(address_str: string): IpAddress =
|
||||||
groupCount.inc()
|
groupCount.inc()
|
||||||
if dualColonGroup != -1: seperatorValid = false
|
if dualColonGroup != -1: seperatorValid = false
|
||||||
elif i == 0: # only valid if address starts with ::
|
elif i == 0: # only valid if address starts with ::
|
||||||
if address_str[1] != ':':
|
if addressStr[1] != ':':
|
||||||
raise newException(ValueError,
|
raise newException(ValueError,
|
||||||
"Invalid IP Address. Address may not start with \":\"")
|
"Invalid IP Address. Address may not start with \":\"")
|
||||||
else: # i == high(address_str) - only valid if address ends with ::
|
else: # i == high(addressStr) - only valid if address ends with ::
|
||||||
if address_str[high(address_str)-1] != ':':
|
if addressStr[high(addressStr)-1] != ':':
|
||||||
raise newException(ValueError,
|
raise newException(ValueError,
|
||||||
"Invalid IP Address. Address may not end with \":\"")
|
"Invalid IP Address. Address may not end with \":\"")
|
||||||
lastWasColon = true
|
lastWasColon = true
|
||||||
|
|
@ -345,7 +345,7 @@ proc parseIPv6Address(address_str: string): IpAddress =
|
||||||
result.address_v6[groupCount*2+1] = cast[uint8](currentShort and 0xFF)
|
result.address_v6[groupCount*2+1] = cast[uint8](currentShort and 0xFF)
|
||||||
groupCount.inc()
|
groupCount.inc()
|
||||||
else: # Must parse IPv4 address
|
else: # Must parse IPv4 address
|
||||||
for i,c in address_str[v4StartPos..high(address_str)]:
|
for i,c in addressStr[v4StartPos..high(addressStr)]:
|
||||||
if c in strutils.Digits: # Character is a number
|
if c in strutils.Digits: # Character is a number
|
||||||
currentShort = currentShort * 10 + cast[uint32](ord(c) - ord('0'))
|
currentShort = currentShort * 10 + cast[uint32](ord(c) - ord('0'))
|
||||||
if currentShort > 255'u32:
|
if currentShort > 255'u32:
|
||||||
|
|
@ -386,21 +386,21 @@ proc parseIPv6Address(address_str: string): IpAddress =
|
||||||
raise newException(ValueError,
|
raise newException(ValueError,
|
||||||
"Invalid IP Address. The address consists of too many groups")
|
"Invalid IP Address. The address consists of too many groups")
|
||||||
|
|
||||||
proc parseIpAddress*(address_str: string): IpAddress =
|
proc parseIpAddress*(addressStr: string): IpAddress =
|
||||||
## Parses an IP address
|
## Parses an IP address
|
||||||
## Raises EInvalidValue on error
|
## Raises EInvalidValue on error
|
||||||
if address_str == nil:
|
if addressStr.len == 0:
|
||||||
raise newException(ValueError, "IP Address string is nil")
|
raise newException(ValueError, "IP Address string is empty")
|
||||||
if address_str.contains(':'):
|
if addressStr.contains(':'):
|
||||||
return parseIPv6Address(address_str)
|
return parseIPv6Address(addressStr)
|
||||||
else:
|
else:
|
||||||
return parseIPv4Address(address_str)
|
return parseIPv4Address(addressStr)
|
||||||
|
|
||||||
proc isIpAddress*(address_str: string): bool {.tags: [].} =
|
proc isIpAddress*(addressStr: string): bool {.tags: [].} =
|
||||||
## Checks if a string is an IP address
|
## Checks if a string is an IP address
|
||||||
## Returns true if it is, false otherwise
|
## Returns true if it is, false otherwise
|
||||||
try:
|
try:
|
||||||
discard parseIpAddress(address_str)
|
discard parseIpAddress(addressStr)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return false
|
return false
|
||||||
return true
|
return true
|
||||||
|
|
@ -587,7 +587,7 @@ when defineSsl:
|
||||||
proc pskClientCallback(ssl: SslPtr; hint: cstring; identity: cstring; max_identity_len: cuint; psk: ptr cuchar;
|
proc pskClientCallback(ssl: SslPtr; hint: cstring; identity: cstring; max_identity_len: cuint; psk: ptr cuchar;
|
||||||
max_psk_len: cuint): cuint {.cdecl.} =
|
max_psk_len: cuint): cuint {.cdecl.} =
|
||||||
let ctx = SSLContext(context: ssl.SSL_get_SSL_CTX)
|
let ctx = SSLContext(context: ssl.SSL_get_SSL_CTX)
|
||||||
let hintString = if hint == nil: nil else: $hint
|
let hintString = if hint == nil: "" else: $hint
|
||||||
let (identityString, pskString) = (ctx.clientGetPskFunc)(hintString)
|
let (identityString, pskString) = (ctx.clientGetPskFunc)(hintString)
|
||||||
if psk.len.cuint > max_psk_len:
|
if psk.len.cuint > max_psk_len:
|
||||||
return 0
|
return 0
|
||||||
|
|
@ -657,7 +657,7 @@ when defineSsl:
|
||||||
|
|
||||||
proc wrapConnectedSocket*(ctx: SSLContext, socket: Socket,
|
proc wrapConnectedSocket*(ctx: SSLContext, socket: Socket,
|
||||||
handshake: SslHandshakeType,
|
handshake: SslHandshakeType,
|
||||||
hostname: string = nil) =
|
hostname: string = "") =
|
||||||
## Wraps a connected socket in an SSL context. This function effectively
|
## Wraps a connected socket in an SSL context. This function effectively
|
||||||
## turns ``socket`` into an SSL socket.
|
## turns ``socket`` into an SSL socket.
|
||||||
## ``hostname`` should be specified so that the client knows which hostname
|
## ``hostname`` should be specified so that the client knows which hostname
|
||||||
|
|
@ -671,7 +671,7 @@ when defineSsl:
|
||||||
wrapSocket(ctx, socket)
|
wrapSocket(ctx, socket)
|
||||||
case handshake
|
case handshake
|
||||||
of handshakeAsClient:
|
of handshakeAsClient:
|
||||||
if not hostname.isNil and not isIpAddress(hostname):
|
if hostname.len > 0 and not isIpAddress(hostname):
|
||||||
# Discard result in case OpenSSL version doesn't support SNI, or we're
|
# Discard result in case OpenSSL version doesn't support SNI, or we're
|
||||||
# not using TLSv1+
|
# not using TLSv1+
|
||||||
discard SSL_set_tlsext_host_name(socket.sslHandle, hostname)
|
discard SSL_set_tlsext_host_name(socket.sslHandle, hostname)
|
||||||
|
|
|
||||||
|
|
@ -44,10 +44,10 @@ type
|
||||||
proc initOptParser*(cmdline: seq[string]): OptParser {.rtl.} =
|
proc initOptParser*(cmdline: seq[string]): OptParser {.rtl.} =
|
||||||
## Initalizes option parses with cmdline. cmdline should not contain
|
## Initalizes option parses with cmdline. cmdline should not contain
|
||||||
## argument 0 - program name.
|
## argument 0 - program name.
|
||||||
## If cmdline == nil default to current command line arguments.
|
## If cmdline.len == 0 default to current command line arguments.
|
||||||
result.remainingShortOptions = ""
|
result.remainingShortOptions = ""
|
||||||
when not defined(createNimRtl):
|
when not defined(createNimRtl):
|
||||||
if cmdline == nil:
|
if cmdline.len == 0:
|
||||||
result.cmd = commandLineParams()
|
result.cmd = commandLineParams()
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
|
|
@ -60,7 +60,7 @@ proc initOptParser*(cmdline: string): OptParser {.rtl, deprecated.} =
|
||||||
## and calls initOptParser(openarray[string])
|
## and calls initOptParser(openarray[string])
|
||||||
## Do not use.
|
## Do not use.
|
||||||
if cmdline == "": # backward compatibility
|
if cmdline == "": # backward compatibility
|
||||||
return initOptParser(seq[string](nil))
|
return initOptParser(@[])
|
||||||
else:
|
else:
|
||||||
return initOptParser(cmdline.split)
|
return initOptParser(cmdline.split)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,7 @@ type
|
||||||
kind: XmlEventKind
|
kind: XmlEventKind
|
||||||
err: XmlErrorKind
|
err: XmlErrorKind
|
||||||
state: ParserState
|
state: ParserState
|
||||||
|
cIsEmpty: bool
|
||||||
filename: string
|
filename: string
|
||||||
options: set[XmlParseOption]
|
options: set[XmlParseOption]
|
||||||
|
|
||||||
|
|
@ -125,7 +126,8 @@ proc open*(my: var XmlParser, input: Stream, filename: string,
|
||||||
my.kind = xmlError
|
my.kind = xmlError
|
||||||
my.a = ""
|
my.a = ""
|
||||||
my.b = ""
|
my.b = ""
|
||||||
my.c = nil
|
my.c = ""
|
||||||
|
my.cIsEmpty = true
|
||||||
my.options = options
|
my.options = options
|
||||||
|
|
||||||
proc close*(my: var XmlParser) {.inline.} =
|
proc close*(my: var XmlParser) {.inline.} =
|
||||||
|
|
@ -482,6 +484,7 @@ proc parseTag(my: var XmlParser) =
|
||||||
my.kind = xmlElementOpen
|
my.kind = xmlElementOpen
|
||||||
my.state = stateAttr
|
my.state = stateAttr
|
||||||
my.c = my.a # save for later
|
my.c = my.a # save for later
|
||||||
|
my.cIsEmpty = false
|
||||||
else:
|
else:
|
||||||
my.kind = xmlElementStart
|
my.kind = xmlElementStart
|
||||||
let slash = my.buf[my.bufpos] == '/'
|
let slash = my.buf[my.bufpos] == '/'
|
||||||
|
|
@ -490,7 +493,8 @@ proc parseTag(my: var XmlParser) =
|
||||||
if slash and my.buf[my.bufpos] == '>':
|
if slash and my.buf[my.bufpos] == '>':
|
||||||
inc(my.bufpos)
|
inc(my.bufpos)
|
||||||
my.state = stateEmptyElementTag
|
my.state = stateEmptyElementTag
|
||||||
my.c = nil
|
my.c = ""
|
||||||
|
my.cIsEmpty = true
|
||||||
elif my.buf[my.bufpos] == '>':
|
elif my.buf[my.bufpos] == '>':
|
||||||
inc(my.bufpos)
|
inc(my.bufpos)
|
||||||
else:
|
else:
|
||||||
|
|
@ -678,7 +682,7 @@ proc next*(my: var XmlParser) =
|
||||||
of stateEmptyElementTag:
|
of stateEmptyElementTag:
|
||||||
my.state = stateNormal
|
my.state = stateNormal
|
||||||
my.kind = xmlElementEnd
|
my.kind = xmlElementEnd
|
||||||
if not my.c.isNil:
|
if not my.cIsEmpty:
|
||||||
my.a = my.c
|
my.a = my.c
|
||||||
of stateError:
|
of stateError:
|
||||||
my.kind = xmlError
|
my.kind = xmlError
|
||||||
|
|
|
||||||
|
|
@ -765,7 +765,7 @@ template fillMatches(s, caps, c) =
|
||||||
if startIdx != -1:
|
if startIdx != -1:
|
||||||
caps[k] = substr(s, startIdx, endIdx)
|
caps[k] = substr(s, startIdx, endIdx)
|
||||||
else:
|
else:
|
||||||
caps[k] = nil
|
caps[k] = ""
|
||||||
|
|
||||||
proc matchLen*(s: string, pattern: Peg, matches: var openArray[string],
|
proc matchLen*(s: string, pattern: Peg, matches: var openArray[string],
|
||||||
start = 0): int {.nosideEffect, rtl, extern: "npegs$1Capture".} =
|
start = 0): int {.nosideEffect, rtl, extern: "npegs$1Capture".} =
|
||||||
|
|
|
||||||
|
|
@ -377,7 +377,10 @@ when not defined(js):
|
||||||
|
|
||||||
proc ssClose(s: Stream) =
|
proc ssClose(s: Stream) =
|
||||||
var s = StringStream(s)
|
var s = StringStream(s)
|
||||||
s.data = nil
|
when defined(nimNoNilSeqs):
|
||||||
|
s.data = ""
|
||||||
|
else:
|
||||||
|
s.data = nil
|
||||||
|
|
||||||
proc newStringStream*(s: string = ""): StringStream =
|
proc newStringStream*(s: string = ""): StringStream =
|
||||||
## creates a new stream from the string `s`.
|
## creates a new stream from the string `s`.
|
||||||
|
|
|
||||||
|
|
@ -176,10 +176,7 @@ method suiteEnded*(formatter: OutputFormatter) {.base, gcsafe.} =
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc addOutputFormatter*(formatter: OutputFormatter) =
|
proc addOutputFormatter*(formatter: OutputFormatter) =
|
||||||
if formatters == nil:
|
formatters.add(formatter)
|
||||||
formatters = @[formatter]
|
|
||||||
else:
|
|
||||||
formatters.add(formatter)
|
|
||||||
|
|
||||||
proc newConsoleOutputFormatter*(outputLevel: OutputLevel = PRINT_ALL,
|
proc newConsoleOutputFormatter*(outputLevel: OutputLevel = PRINT_ALL,
|
||||||
colorOutput = true): ConsoleOutputFormatter =
|
colorOutput = true): ConsoleOutputFormatter =
|
||||||
|
|
@ -225,7 +222,7 @@ method testStarted*(formatter: ConsoleOutputFormatter, testName: string) =
|
||||||
formatter.isInTest = true
|
formatter.isInTest = true
|
||||||
|
|
||||||
method failureOccurred*(formatter: ConsoleOutputFormatter, checkpoints: seq[string], stackTrace: string) =
|
method failureOccurred*(formatter: ConsoleOutputFormatter, checkpoints: seq[string], stackTrace: string) =
|
||||||
if stackTrace != nil:
|
if stackTrace.len > 0:
|
||||||
echo stackTrace
|
echo stackTrace
|
||||||
let prefix = if formatter.isInSuite: " " else: ""
|
let prefix = if formatter.isInSuite: " " else: ""
|
||||||
for msg in items(checkpoints):
|
for msg in items(checkpoints):
|
||||||
|
|
@ -236,7 +233,7 @@ method testEnded*(formatter: ConsoleOutputFormatter, testResult: TestResult) =
|
||||||
|
|
||||||
if formatter.outputLevel != PRINT_NONE and
|
if formatter.outputLevel != PRINT_NONE and
|
||||||
(formatter.outputLevel == PRINT_ALL or testResult.status == FAILED):
|
(formatter.outputLevel == PRINT_ALL or testResult.status == FAILED):
|
||||||
let prefix = if testResult.suiteName != nil: " " else: ""
|
let prefix = if testResult.suiteName.len > 0: " " else: ""
|
||||||
template rawPrint() = echo(prefix, "[", $testResult.status, "] ", testResult.testName)
|
template rawPrint() = echo(prefix, "[", $testResult.status, "] ", testResult.testName)
|
||||||
when not defined(ECMAScript):
|
when not defined(ECMAScript):
|
||||||
if formatter.colorOutput and not defined(ECMAScript):
|
if formatter.colorOutput and not defined(ECMAScript):
|
||||||
|
|
@ -301,7 +298,7 @@ method failureOccurred*(formatter: JUnitOutputFormatter, checkpoints: seq[string
|
||||||
## ``stackTrace`` is provided only if the failure occurred due to an exception.
|
## ``stackTrace`` is provided only if the failure occurred due to an exception.
|
||||||
## ``checkpoints`` is never ``nil``.
|
## ``checkpoints`` is never ``nil``.
|
||||||
formatter.testErrors.add(checkpoints)
|
formatter.testErrors.add(checkpoints)
|
||||||
if stackTrace != nil:
|
if stackTrace.len > 0:
|
||||||
formatter.testStackTrace = stackTrace
|
formatter.testStackTrace = stackTrace
|
||||||
|
|
||||||
method testEnded*(formatter: JUnitOutputFormatter, testResult: TestResult) =
|
method testEnded*(formatter: JUnitOutputFormatter, testResult: TestResult) =
|
||||||
|
|
@ -392,7 +389,7 @@ proc shouldRun(currentSuiteName, testName: string): bool =
|
||||||
return false
|
return false
|
||||||
|
|
||||||
proc ensureInitialized() =
|
proc ensureInitialized() =
|
||||||
if formatters == nil:
|
if formatters.len == 0:
|
||||||
formatters = @[OutputFormatter(defaultConsoleFormatter())]
|
formatters = @[OutputFormatter(defaultConsoleFormatter())]
|
||||||
|
|
||||||
if not disabledParamFiltering and not testsFilters.isValid:
|
if not disabledParamFiltering and not testsFilters.isValid:
|
||||||
|
|
|
||||||
|
|
@ -217,9 +217,9 @@ proc createAttribute*(doc: PDocument, name: string): PAttr =
|
||||||
new(attrNode)
|
new(attrNode)
|
||||||
attrNode.fName = name
|
attrNode.fName = name
|
||||||
attrNode.fNodeName = name
|
attrNode.fNodeName = name
|
||||||
attrNode.fLocalName = nil
|
attrNode.fLocalName = ""
|
||||||
attrNode.prefix = nil
|
attrNode.prefix = ""
|
||||||
attrNode.fNamespaceURI = nil
|
attrNode.fNamespaceURI = ""
|
||||||
attrNode.value = ""
|
attrNode.value = ""
|
||||||
attrNode.fSpecified = false
|
attrNode.fSpecified = false
|
||||||
return attrNode
|
return attrNode
|
||||||
|
|
@ -254,7 +254,7 @@ proc createAttributeNS*(doc: PDocument, namespaceURI: string, qualifiedName: str
|
||||||
attrNode.prefix = qualifiedName.split(':')[0]
|
attrNode.prefix = qualifiedName.split(':')[0]
|
||||||
attrNode.fLocalName = qualifiedName.split(':')[1]
|
attrNode.fLocalName = qualifiedName.split(':')[1]
|
||||||
else:
|
else:
|
||||||
attrNode.prefix = nil
|
attrNode.prefix = ""
|
||||||
attrNode.fLocalName = qualifiedName
|
attrNode.fLocalName = qualifiedName
|
||||||
attrNode.value = ""
|
attrNode.value = ""
|
||||||
|
|
||||||
|
|
@ -298,9 +298,9 @@ proc createElement*(doc: PDocument, tagName: string): PElement =
|
||||||
new(elNode)
|
new(elNode)
|
||||||
elNode.fTagName = tagName
|
elNode.fTagName = tagName
|
||||||
elNode.fNodeName = tagName
|
elNode.fNodeName = tagName
|
||||||
elNode.fLocalName = nil
|
elNode.fLocalName = ""
|
||||||
elNode.prefix = nil
|
elNode.prefix = ""
|
||||||
elNode.fNamespaceURI = nil
|
elNode.fNamespaceURI = ""
|
||||||
elNode.childNodes = @[]
|
elNode.childNodes = @[]
|
||||||
elNode.attributes = @[]
|
elNode.attributes = @[]
|
||||||
|
|
||||||
|
|
@ -332,7 +332,7 @@ proc createElementNS*(doc: PDocument, namespaceURI: string, qualifiedName: strin
|
||||||
elNode.prefix = qualifiedName.split(':')[0]
|
elNode.prefix = qualifiedName.split(':')[0]
|
||||||
elNode.fLocalName = qualifiedName.split(':')[1]
|
elNode.fLocalName = qualifiedName.split(':')[1]
|
||||||
else:
|
else:
|
||||||
elNode.prefix = nil
|
elNode.prefix = ""
|
||||||
elNode.fLocalName = qualifiedName
|
elNode.fLocalName = qualifiedName
|
||||||
elNode.fNamespaceURI = namespaceURI
|
elNode.fNamespaceURI = namespaceURI
|
||||||
elNode.childNodes = @[]
|
elNode.childNodes = @[]
|
||||||
|
|
@ -893,22 +893,22 @@ proc tagName*(el: PElement): string =
|
||||||
proc getAttribute*(el: PNode, name: string): string =
|
proc getAttribute*(el: PNode, name: string): string =
|
||||||
## Retrieves an attribute value by ``name``
|
## Retrieves an attribute value by ``name``
|
||||||
if isNil(el.attributes):
|
if isNil(el.attributes):
|
||||||
return nil
|
return ""
|
||||||
var attribute = el.attributes.getNamedItem(name)
|
var attribute = el.attributes.getNamedItem(name)
|
||||||
if not isNil(attribute):
|
if not isNil(attribute):
|
||||||
return attribute.value
|
return attribute.value
|
||||||
else:
|
else:
|
||||||
return nil
|
return ""
|
||||||
|
|
||||||
proc getAttributeNS*(el: PNode, namespaceURI: string, localName: string): string =
|
proc getAttributeNS*(el: PNode, namespaceURI: string, localName: string): string =
|
||||||
## Retrieves an attribute value by ``localName`` and ``namespaceURI``
|
## Retrieves an attribute value by ``localName`` and ``namespaceURI``
|
||||||
if isNil(el.attributes):
|
if isNil(el.attributes):
|
||||||
return nil
|
return ""
|
||||||
var attribute = el.attributes.getNamedItemNS(namespaceURI, localName)
|
var attribute = el.attributes.getNamedItemNS(namespaceURI, localName)
|
||||||
if not isNil(attribute):
|
if not isNil(attribute):
|
||||||
return attribute.value
|
return attribute.value
|
||||||
else:
|
else:
|
||||||
return nil
|
return ""
|
||||||
|
|
||||||
proc getAttributeNode*(el: PElement, name: string): PAttr =
|
proc getAttributeNode*(el: PElement, name: string): PAttr =
|
||||||
## Retrieves an attribute node by ``name``
|
## Retrieves an attribute node by ``name``
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ proc loadXMLStream*(stream: Stream): PDocument =
|
||||||
## a ``PDocument``
|
## a ``PDocument``
|
||||||
|
|
||||||
var x: XmlParser
|
var x: XmlParser
|
||||||
open(x, stream, nil, {reportComments})
|
open(x, stream, "", {reportComments})
|
||||||
|
|
||||||
var xmlDoc: PDocument
|
var xmlDoc: PDocument
|
||||||
var dom: PDOMImplementation = getDOM()
|
var dom: PDOMImplementation = getDOM()
|
||||||
|
|
@ -161,7 +161,7 @@ when not defined(testing) and isMainModule:
|
||||||
#echo(xml.getElementsByTagName("bla:test")[0].namespaceURI)
|
#echo(xml.getElementsByTagName("bla:test")[0].namespaceURI)
|
||||||
#echo(xml.getElementsByTagName("test")[0].namespaceURI)
|
#echo(xml.getElementsByTagName("test")[0].namespaceURI)
|
||||||
for i in items(xml.getElementsByTagName("*")):
|
for i in items(xml.getElementsByTagName("*")):
|
||||||
if i.namespaceURI != nil:
|
if i.namespaceURI.len > 0:
|
||||||
echo(i.nodeName, "=", i.namespaceURI)
|
echo(i.nodeName, "=", i.namespaceURI)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3963,19 +3963,28 @@ when hasAlloc:
|
||||||
proc safeAdd*[T](x: var seq[T], y: T) {.noSideEffect, deprecated.} =
|
proc safeAdd*[T](x: var seq[T], y: T) {.noSideEffect, deprecated.} =
|
||||||
## Adds ``y`` to ``x`` unless ``x`` is not yet initialized; in that case,
|
## Adds ``y`` to ``x`` unless ``x`` is not yet initialized; in that case,
|
||||||
## ``x`` becomes ``@[y]``
|
## ``x`` becomes ``@[y]``
|
||||||
if x == nil: x = @[y]
|
when defined(nimNoNilSeqs):
|
||||||
else: x.add(y)
|
x.add(y)
|
||||||
|
else:
|
||||||
|
if x == nil: x = @[y]
|
||||||
|
else: x.add(y)
|
||||||
|
|
||||||
proc safeAdd*(x: var string, y: char) {.noSideEffect, deprecated.} =
|
proc safeAdd*(x: var string, y: char) {.noSideEffect, deprecated.} =
|
||||||
## Adds ``y`` to ``x``. If ``x`` is ``nil`` it is initialized to ``""``
|
## Adds ``y`` to ``x``. If ``x`` is ``nil`` it is initialized to ``""``
|
||||||
if x == nil: x = ""
|
when defined(nimNoNilSeqs):
|
||||||
x.add(y)
|
x.add(y)
|
||||||
|
else:
|
||||||
|
if x == nil: x = ""
|
||||||
|
x.add(y)
|
||||||
|
|
||||||
proc safeAdd*(x: var string, y: string) {.noSideEffect, deprecated.} =
|
proc safeAdd*(x: var string, y: string) {.noSideEffect, deprecated.} =
|
||||||
## Adds ``y`` to ``x`` unless ``x`` is not yet initalized; in that
|
## Adds ``y`` to ``x`` unless ``x`` is not yet initalized; in that
|
||||||
## case, ``x`` becomes ``y``
|
## case, ``x`` becomes ``y``
|
||||||
if x == nil: x = y
|
when defined(nimNoNilSeqs):
|
||||||
else: x.add(y)
|
x.add(y)
|
||||||
|
else:
|
||||||
|
if x == nil: x = y
|
||||||
|
else: x.add(y)
|
||||||
|
|
||||||
proc locals*(): RootObj {.magic: "Plugin", noSideEffect.} =
|
proc locals*(): RootObj {.magic: "Plugin", noSideEffect.} =
|
||||||
## generates a tuple constructor expression listing all the local variables
|
## generates a tuple constructor expression listing all the local variables
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,7 @@ block: #8399
|
||||||
case line[0]
|
case line[0]
|
||||||
of '+', '-': @[]
|
of '+', '-': @[]
|
||||||
of '$': (let x = await bar(); @[""])
|
of '$': (let x = await bar(); @[""])
|
||||||
else:
|
else: @[]
|
||||||
nil
|
|
||||||
|
|
||||||
doAssert(res == @[""])
|
doAssert(res == @[""])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,11 @@ when defined(ssl):
|
||||||
var clientCount = 0
|
var clientCount = 0
|
||||||
|
|
||||||
proc sendMessages(client: AsyncSocket) {.async.} =
|
proc sendMessages(client: AsyncSocket) {.async.} =
|
||||||
for i in 0 .. <messagesToSend:
|
for i in 0 ..< messagesToSend:
|
||||||
await send(client, "Message " & $i & "\c\L")
|
await send(client, "Message " & $i & "\c\L")
|
||||||
|
|
||||||
proc launchSwarm(port: Port) {.async.} =
|
proc launchSwarm(port: Port) {.async.} =
|
||||||
for i in 0 .. <swarmSize:
|
for i in 0 ..< swarmSize:
|
||||||
var sock = newAsyncSocket()
|
var sock = newAsyncSocket()
|
||||||
var clientContext = newContext(verifyMode = CVerifyNone)
|
var clientContext = newContext(verifyMode = CVerifyNone)
|
||||||
clientContext.wrapSocket(sock)
|
clientContext.wrapSocket(sock)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue