Merge branch 'devel' into fixes-6223
This commit is contained in:
commit
5196cc3a54
6 changed files with 71 additions and 50 deletions
|
|
@ -107,4 +107,7 @@ This now needs to be written as:
|
||||||
if true: echo "yes"
|
if true: echo "yes"
|
||||||
- The ``[]`` proc for strings now raises an ``IndexError`` exception when
|
- The ``[]`` proc for strings now raises an ``IndexError`` exception when
|
||||||
the specified slice is out of bounds. See issue
|
the specified slice is out of bounds. See issue
|
||||||
[#6223](https://github.com/nim-lang/Nim/issues/6223) for more details.
|
[#6223](https://github.com/nim-lang/Nim/issues/6223) for more details.
|
||||||
|
- ``strutils.split`` and ``strutils.rsplit`` with an empty string and a
|
||||||
|
separator now returns that empty string.
|
||||||
|
See issue [#4377](https://github.com/nim-lang/Nim/issues/4377).
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ const
|
||||||
wMagic, wNosideeffect, wSideeffect, wNoreturn, wDynlib, wHeader,
|
wMagic, wNosideeffect, wSideeffect, wNoreturn, wDynlib, wHeader,
|
||||||
wCompilerproc, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge,
|
wCompilerproc, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge,
|
||||||
wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC,
|
wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC,
|
||||||
wAsmNoStackFrame, wError, wDiscardable, wNoInit, wDestructor, wCodegenDecl,
|
wAsmNoStackFrame, wError, wDiscardable, wNoInit, wCodegenDecl,
|
||||||
wGensym, wInject, wRaises, wTags, wLocks, wDelegator, wGcSafe,
|
wGensym, wInject, wRaises, wTags, wLocks, wDelegator, wGcSafe,
|
||||||
wOverride, wConstructor, wExportNims, wUsed, wLiftLocals}
|
wOverride, wConstructor, wExportNims, wUsed, wLiftLocals}
|
||||||
converterPragmas* = procPragmas
|
converterPragmas* = procPragmas
|
||||||
|
|
@ -759,10 +759,6 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
|
||||||
incl(sym.loc.flags, lfNoDecl)
|
incl(sym.loc.flags, lfNoDecl)
|
||||||
# implies nodecl, because otherwise header would not make sense
|
# implies nodecl, because otherwise header would not make sense
|
||||||
if sym.loc.r == nil: sym.loc.r = rope(sym.name.s)
|
if sym.loc.r == nil: sym.loc.r = rope(sym.name.s)
|
||||||
of wDestructor:
|
|
||||||
sym.flags.incl sfOverriden
|
|
||||||
if sym.name.s.normalize != "destroy":
|
|
||||||
localError(n.info, errGenerated, "destructor has to be named 'destroy'")
|
|
||||||
of wOverride:
|
of wOverride:
|
||||||
sym.flags.incl sfOverriden
|
sym.flags.incl sfOverriden
|
||||||
of wNosideeffect:
|
of wNosideeffect:
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ new(destructorIsTrivial)
|
||||||
var
|
var
|
||||||
destructorName = getIdent"destroy_"
|
destructorName = getIdent"destroy_"
|
||||||
destructorParam = getIdent"this_"
|
destructorParam = getIdent"this_"
|
||||||
destructorPragma = newIdentNode(getIdent"destructor", unknownLineInfo())
|
|
||||||
|
|
||||||
proc instantiateDestructor(c: PContext, typ: PType): PType
|
proc instantiateDestructor(c: PContext, typ: PType): PType
|
||||||
|
|
||||||
|
|
@ -150,19 +149,19 @@ proc instantiateDestructor(c: PContext, typ: PType): PType =
|
||||||
let generated = generateDestructor(c, t)
|
let generated = generateDestructor(c, t)
|
||||||
if generated != nil:
|
if generated != nil:
|
||||||
internalAssert t.sym != nil
|
internalAssert t.sym != nil
|
||||||
var i = t.sym.info
|
let info = t.sym.info
|
||||||
let fullDef = newNode(nkProcDef, i, @[
|
let fullDef = newNode(nkProcDef, info, @[
|
||||||
newIdentNode(destructorName, i),
|
newIdentNode(destructorName, info),
|
||||||
emptyNode,
|
emptyNode,
|
||||||
emptyNode,
|
emptyNode,
|
||||||
newNode(nkFormalParams, i, @[
|
newNode(nkFormalParams, info, @[
|
||||||
emptyNode,
|
emptyNode,
|
||||||
newNode(nkIdentDefs, i, @[
|
newNode(nkIdentDefs, info, @[
|
||||||
newIdentNode(destructorParam, i),
|
newIdentNode(destructorParam, info),
|
||||||
symNodeFromType(c, makeVarType(c, t), t.sym.info),
|
symNodeFromType(c, makeVarType(c, t), t.sym.info),
|
||||||
emptyNode]),
|
emptyNode]),
|
||||||
]),
|
]),
|
||||||
newNode(nkPragma, i, @[destructorPragma]),
|
emptyNode,
|
||||||
emptyNode,
|
emptyNode,
|
||||||
generated
|
generated
|
||||||
])
|
])
|
||||||
|
|
|
||||||
|
|
@ -59,8 +59,8 @@ proc xmlCheckedTag*(e: NimNode, tag: string, optAttr = "", reqAttr = "",
|
||||||
|
|
||||||
# copy the attributes; when iterating over them these lists
|
# copy the attributes; when iterating over them these lists
|
||||||
# will be modified, so that each attribute is only given one value
|
# will be modified, so that each attribute is only given one value
|
||||||
var req = split(reqAttr)
|
var req = splitWhitespace(reqAttr)
|
||||||
var opt = split(optAttr)
|
var opt = splitWhitespace(optAttr)
|
||||||
result = newNimNode(nnkBracket, e)
|
result = newNimNode(nnkBracket, e)
|
||||||
result.add(newStrLitNode("<"))
|
result.add(newStrLitNode("<"))
|
||||||
result.add(newStrLitNode(tag))
|
result.add(newStrLitNode(tag))
|
||||||
|
|
|
||||||
|
|
@ -491,6 +491,8 @@ const mimes* = {
|
||||||
"vrml": "x-world/x-vrml",
|
"vrml": "x-world/x-vrml",
|
||||||
"wrl": "x-world/x-vrml"}
|
"wrl": "x-world/x-vrml"}
|
||||||
|
|
||||||
|
from strutils import startsWith
|
||||||
|
|
||||||
proc newMimetypes*(): MimeDB =
|
proc newMimetypes*(): MimeDB =
|
||||||
## Creates a new Mimetypes database. The database will contain the most
|
## Creates a new Mimetypes database. The database will contain the most
|
||||||
## common mimetypes.
|
## common mimetypes.
|
||||||
|
|
@ -498,8 +500,11 @@ proc newMimetypes*(): MimeDB =
|
||||||
|
|
||||||
proc getMimetype*(mimedb: MimeDB, ext: string, default = "text/plain"): string =
|
proc getMimetype*(mimedb: MimeDB, ext: string, default = "text/plain"): string =
|
||||||
## Gets mimetype which corresponds to ``ext``. Returns ``default`` if ``ext``
|
## Gets mimetype which corresponds to ``ext``. Returns ``default`` if ``ext``
|
||||||
## could not be found.
|
## could not be found. ``ext`` can start with an optional dot which is ignored.
|
||||||
result = mimedb.mimes.getOrDefault(ext)
|
if ext.startsWith("."):
|
||||||
|
result = mimedb.mimes.getOrDefault(ext.substr(1))
|
||||||
|
else:
|
||||||
|
result = mimedb.mimes.getOrDefault(ext)
|
||||||
if result == "":
|
if result == "":
|
||||||
return default
|
return default
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -502,16 +502,15 @@ template splitCommon(s, sep, maxsplit, sepLen) =
|
||||||
var last = 0
|
var last = 0
|
||||||
var splits = maxsplit
|
var splits = maxsplit
|
||||||
|
|
||||||
if len(s) > 0:
|
while last <= len(s):
|
||||||
while last <= len(s):
|
var first = last
|
||||||
var first = last
|
while last < len(s) and not stringHasSep(s, last, sep):
|
||||||
while last < len(s) and not stringHasSep(s, last, sep):
|
inc(last)
|
||||||
inc(last)
|
if splits == 0: last = len(s)
|
||||||
if splits == 0: last = len(s)
|
yield substr(s, first, last-1)
|
||||||
yield substr(s, first, last-1)
|
if splits == 0: break
|
||||||
if splits == 0: break
|
dec(splits)
|
||||||
dec(splits)
|
inc(last, sepLen)
|
||||||
inc(last, sepLen)
|
|
||||||
|
|
||||||
template oldSplit(s, seps, maxsplit) =
|
template oldSplit(s, seps, maxsplit) =
|
||||||
var last = 0
|
var last = 0
|
||||||
|
|
@ -669,30 +668,29 @@ template rsplitCommon(s, sep, maxsplit, sepLen) =
|
||||||
splits = maxsplit
|
splits = maxsplit
|
||||||
startPos = 0
|
startPos = 0
|
||||||
|
|
||||||
if len(s) > 0:
|
# go to -1 in order to get separators at the beginning
|
||||||
# go to -1 in order to get separators at the beginning
|
while first >= -1:
|
||||||
while first >= -1:
|
while first >= 0 and not stringHasSep(s, first, sep):
|
||||||
while first >= 0 and not stringHasSep(s, first, sep):
|
|
||||||
dec(first)
|
|
||||||
|
|
||||||
if splits == 0:
|
|
||||||
# No more splits means set first to the beginning
|
|
||||||
first = -1
|
|
||||||
|
|
||||||
if first == -1:
|
|
||||||
startPos = 0
|
|
||||||
else:
|
|
||||||
startPos = first + sepLen
|
|
||||||
|
|
||||||
yield substr(s, startPos, last)
|
|
||||||
|
|
||||||
if splits == 0:
|
|
||||||
break
|
|
||||||
|
|
||||||
dec(splits)
|
|
||||||
dec(first)
|
dec(first)
|
||||||
|
|
||||||
last = first
|
if splits == 0:
|
||||||
|
# No more splits means set first to the beginning
|
||||||
|
first = -1
|
||||||
|
|
||||||
|
if first == -1:
|
||||||
|
startPos = 0
|
||||||
|
else:
|
||||||
|
startPos = first + sepLen
|
||||||
|
|
||||||
|
yield substr(s, startPos, last)
|
||||||
|
|
||||||
|
if splits == 0:
|
||||||
|
break
|
||||||
|
|
||||||
|
dec(splits)
|
||||||
|
dec(first)
|
||||||
|
|
||||||
|
last = first
|
||||||
|
|
||||||
iterator rsplit*(s: string, seps: set[char] = Whitespace,
|
iterator rsplit*(s: string, seps: set[char] = Whitespace,
|
||||||
maxsplit: int = -1): string =
|
maxsplit: int = -1): string =
|
||||||
|
|
@ -820,12 +818,18 @@ proc split*(s: string, seps: set[char] = Whitespace, maxsplit: int = -1): seq[st
|
||||||
noSideEffect, rtl, extern: "nsuSplitCharSet".} =
|
noSideEffect, rtl, extern: "nsuSplitCharSet".} =
|
||||||
## The same as the `split iterator <#split.i,string,set[char],int>`_, but is a
|
## The same as the `split iterator <#split.i,string,set[char],int>`_, but is a
|
||||||
## proc that returns a sequence of substrings.
|
## proc that returns a sequence of substrings.
|
||||||
|
runnableExamples:
|
||||||
|
doAssert "a,b;c".split({',', ';'}) == @["a", "b", "c"]
|
||||||
|
doAssert "".split({' '}) == @[""]
|
||||||
accumulateResult(split(s, seps, maxsplit))
|
accumulateResult(split(s, seps, maxsplit))
|
||||||
|
|
||||||
proc split*(s: string, sep: char, maxsplit: int = -1): seq[string] {.noSideEffect,
|
proc split*(s: string, sep: char, maxsplit: int = -1): seq[string] {.noSideEffect,
|
||||||
rtl, extern: "nsuSplitChar".} =
|
rtl, extern: "nsuSplitChar".} =
|
||||||
## The same as the `split iterator <#split.i,string,char,int>`_, but is a proc
|
## The same as the `split iterator <#split.i,string,char,int>`_, but is a proc
|
||||||
## that returns a sequence of substrings.
|
## that returns a sequence of substrings.
|
||||||
|
runnableExamples:
|
||||||
|
doAssert "a,b,c".split(',') == @["a", "b", "c"]
|
||||||
|
doAssert "".split(' ') == @[""]
|
||||||
accumulateResult(split(s, sep, maxsplit))
|
accumulateResult(split(s, sep, maxsplit))
|
||||||
|
|
||||||
proc split*(s: string, sep: string, maxsplit: int = -1): seq[string] {.noSideEffect,
|
proc split*(s: string, sep: string, maxsplit: int = -1): seq[string] {.noSideEffect,
|
||||||
|
|
@ -834,6 +838,13 @@ proc split*(s: string, sep: string, maxsplit: int = -1): seq[string] {.noSideEff
|
||||||
##
|
##
|
||||||
## Substrings are separated by the string `sep`. This is a wrapper around the
|
## Substrings are separated by the string `sep`. This is a wrapper around the
|
||||||
## `split iterator <#split.i,string,string,int>`_.
|
## `split iterator <#split.i,string,string,int>`_.
|
||||||
|
runnableExamples:
|
||||||
|
doAssert "a,b,c".split(",") == @["a", "b", "c"]
|
||||||
|
doAssert "a man a plan a canal panama".split("a ") == @["", "man ", "plan ", "canal panama"]
|
||||||
|
doAssert "".split("Elon Musk") == @[""]
|
||||||
|
doAssert "a largely spaced sentence".split(" ") == @["a", "", "largely", "", "", "", "spaced", "sentence"]
|
||||||
|
|
||||||
|
doAssert "a largely spaced sentence".split(" ", maxsplit=1) == @["a", " largely spaced sentence"]
|
||||||
doAssert(sep.len > 0)
|
doAssert(sep.len > 0)
|
||||||
|
|
||||||
accumulateResult(split(s, sep, maxsplit))
|
accumulateResult(split(s, sep, maxsplit))
|
||||||
|
|
@ -902,6 +913,13 @@ proc rsplit*(s: string, sep: string, maxsplit: int = -1): seq[string]
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
## @["Root#Object#Method", "Index"]
|
## @["Root#Object#Method", "Index"]
|
||||||
##
|
##
|
||||||
|
runnableExamples:
|
||||||
|
doAssert "a largely spaced sentence".rsplit(" ", maxsplit=1) == @["a largely spaced", "sentence"]
|
||||||
|
|
||||||
|
doAssert "a,b,c".rsplit(",") == @["a", "b", "c"]
|
||||||
|
doAssert "a man a plan a canal panama".rsplit("a ") == @["", "man ", "plan ", "canal panama"]
|
||||||
|
doAssert "".rsplit("Elon Musk") == @[""]
|
||||||
|
doAssert "a largely spaced sentence".rsplit(" ") == @["a", "", "largely", "", "", "", "spaced", "sentence"]
|
||||||
accumulateResult(rsplit(s, sep, maxsplit))
|
accumulateResult(rsplit(s, sep, maxsplit))
|
||||||
result.reverse()
|
result.reverse()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue