Merge branch 'devel' into fixes-6223

This commit is contained in:
Andreas Rumpf 2017-11-28 21:56:48 +01:00 • committed by GitHub
commit 5196cc3a54
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 71 additions and 50 deletions

View file

@ -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).

View file

@ -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:

View file

@ -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
]) ])

View file

@ -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))

View file

@ -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

View file

@ -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()