diff options
-rw-r--r-- | compiler/cgen.nim | 27 | ||||
-rw-r--r-- | compiler/commands.nim | 8 | ||||
-rw-r--r-- | compiler/options.nim | 2 | ||||
-rw-r--r-- | compiler/parser.nim | 2 | ||||
-rw-r--r-- | doc/advopt.txt | 4 | ||||
-rw-r--r-- | lib/nimbase.h | 2 | ||||
-rw-r--r-- | lib/posix/posix_other.nim | 2 | ||||
-rw-r--r-- | lib/pure/includes/oserr.nim | 8 | ||||
-rw-r--r-- | lib/pure/net.nim | 4 | ||||
-rw-r--r-- | lib/pure/osproc.nim | 2 | ||||
-rw-r--r-- | lib/pure/strutils.nim | 14 | ||||
-rw-r--r-- | tests/distinct/t7010.nim | 19 | ||||
-rw-r--r-- | tests/errmsgs/t6483.nim | 31 | ||||
-rw-r--r-- | tests/iter/tchainediterators2.nim | 81 | ||||
-rw-r--r-- | tests/stdlib/tstrutil.nim | 15 |
15 files changed, 188 insertions, 33 deletions
diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 7a74d8a9b..2db92bc21 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -679,8 +679,10 @@ proc generateHeaders(m: BModule) = add(m.s[cfsHeaders], "#undef powerpc\L") add(m.s[cfsHeaders], "#undef unix\L") -proc openNamespaceNim(): Rope = - result.add("namespace Nim {\L") +proc openNamespaceNim(namespace: string): Rope = + result.add("namespace ") + result.add(namespace) + result.add(" {\L") proc closeNamespaceNim(): Rope = result.add("}\L") @@ -1036,7 +1038,10 @@ proc addIntTypes(result: var Rope; conf: ConfigRef) {.inline.} = addf(result, "#define NIM_NEW_MANGLING_RULES\L" & "#define NIM_INTBITS $1\L", [ platform.CPU[conf.target.targetCPU].intSize.rope]) - if optUseNimNamespace in conf.globalOptions: result.add("#define USE_NIM_NAMESPACE\L") + if conf.cppCustomNamespace.len > 0: + result.add("#define USE_NIM_NAMESPACE ") + result.add(conf.cppCustomNamespace) + result.add("\L") proc getCopyright(conf: ConfigRef; cfile: Cfile): Rope = if optCompileOnly in conf.globalOptions: @@ -1209,11 +1214,11 @@ proc genMainProc(m: BModule) = appcg(m, m.s[cfsProcs], nimMain, [m.g.mainModInit, initStackBottomCall, rope(m.labels)]) if optNoMain notin m.config.globalOptions: - if optUseNimNamespace in m.config.globalOptions: - m.s[cfsProcs].add closeNamespaceNim() & "using namespace Nim;\L" + if m.config.cppCustomNamespace.len > 0: + m.s[cfsProcs].add closeNamespaceNim() & "using namespace " & m.config.cppCustomNamespace & ";\L" appcg(m, m.s[cfsProcs], otherMain, []) - if optUseNimNamespace in m.config.globalOptions: m.s[cfsProcs].add openNamespaceNim() + if m.config.cppCustomNamespace.len > 0: m.s[cfsProcs].add openNamespaceNim(m.config.cppCustomNamespace) proc getSomeInitName(m: PSym, suffix: string): Rope = assert m.kind == skModule @@ -1335,10 +1340,10 @@ proc genModule(m: BModule, cfile: Cfile): Rope = add(result, genSectionStart(i, m.config)) add(result, m.s[i]) add(result, genSectionEnd(i, m.config)) - if optUseNimNamespace in m.config.globalOptions and i == cfsHeaders: - result.add openNamespaceNim() + if m.config.cppCustomNamespace.len > 0 and i == cfsHeaders: + result.add openNamespaceNim(m.config.cppCustomNamespace) add(result, m.s[cfsInitProc]) - if optUseNimNamespace in m.config.globalOptions: result.add closeNamespaceNim() + if m.config.cppCustomNamespace.len > 0: result.add closeNamespaceNim() proc newPreInitProc(m: BModule): BProc = result = newProc(nil, m) @@ -1469,13 +1474,13 @@ proc writeHeader(m: BModule) = add(result, genSectionStart(i, m.config)) add(result, m.s[i]) add(result, genSectionEnd(i, m.config)) - if optUseNimNamespace in m.config.globalOptions and i == cfsHeaders: result.add openNamespaceNim() + if m.config.cppCustomNamespace.len > 0 and i == cfsHeaders: result.add openNamespaceNim(m.config.cppCustomNamespace) add(result, m.s[cfsInitProc]) if optGenDynLib in m.config.globalOptions: result.add("N_LIB_IMPORT ") result.addf("N_CDECL(void, NimMain)(void);$n", []) - if optUseNimNamespace in m.config.globalOptions: result.add closeNamespaceNim() + if m.config.cppCustomNamespace.len > 0: result.add closeNamespaceNim() result.addf("#endif /* $1 */$n", [guard]) if not writeRope(result, m.filename): rawMessage(m.config, errCannotOpenFile, m.filename.string) diff --git a/compiler/commands.nim b/compiler/commands.nim index fe820a589..39967c4bc 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -735,9 +735,11 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo; of "nep1": processOnOffSwitchG(conf, {optCheckNep1}, arg, pass, info) of "cppcompiletonamespace": - expectNoArg(conf, switch, arg, pass, info) - incl conf.globalOptions, optUseNimNamespace - defineSymbol(conf.symbols, "cppCompileToNamespace") + if arg.len > 0: + conf.cppCustomNamespace = arg + else: + conf.cppCustomNamespace = "Nim" + defineSymbol(conf.symbols, "cppCompileToNamespace", conf.cppCustomNamespace) else: if strutils.find(switch, '.') >= 0: options.setConfigVar(conf, switch, arg) else: invalidCmdLineOption(conf, pass, switch, info) diff --git a/compiler/options.nim b/compiler/options.nim index a95d9930a..b4d2bb64e 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -78,7 +78,6 @@ type # please make sure we have under 32 options optListFullPaths optNoNimblePath optDynlibOverrideAll - optUseNimNamespace TGlobalOptions* = set[TGlobalOption] @@ -242,6 +241,7 @@ type writelnHook*: proc (output: string) {.closure.} structuredErrorHook*: proc (config: ConfigRef; info: TLineInfo; msg: string; severity: Severity) {.closure.} + cppCustomNamespace*: string template depConfigFields*(fn) {.dirty.} = fn(target) diff --git a/compiler/parser.nim b/compiler/parser.nim index 7667d3a0e..69e372e4e 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -1517,7 +1517,7 @@ proc parseCase(p: var TParser): PNode = #| | IND{=} ofBranches) var b: PNode - inElif= false + inElif = false wasIndented = false result = newNodeP(nkCaseStmt, p) getTok(p) diff --git a/doc/advopt.txt b/doc/advopt.txt index 150025509..a1b709f04 100644 --- a/doc/advopt.txt +++ b/doc/advopt.txt @@ -81,7 +81,9 @@ Advanced options: --NimblePath:PATH add a path for Nimble support --noNimblePath deactivate the Nimble path --noCppExceptions use default exception handling with C++ backend - --cppCompileToNamespace use namespace "Nim" for the generated C++ code + --cppCompileToNamespace:namespace + use the provided namespace for the generated C++ code, + if no namespace is provided "Nim" will be used --excludePath:PATH exclude a path from the list of search paths --dynlibOverride:SYMBOL marks SYMBOL so that dynlib:SYMBOL has no effect and can be statically linked instead; diff --git a/lib/nimbase.h b/lib/nimbase.h index 507108712..c04d378c5 100644 --- a/lib/nimbase.h +++ b/lib/nimbase.h @@ -268,7 +268,7 @@ __clang__ /* wrap all Nim typedefs into namespace Nim */ #ifdef USE_NIM_NAMESPACE -namespace Nim { +namespace USE_NIM_NAMESPACE { #endif /* bool types (C++ has it): */ diff --git a/lib/posix/posix_other.nim b/lib/posix/posix_other.nim index 99d67824e..ba1dd89ed 100644 --- a/lib/posix/posix_other.nim +++ b/lib/posix/posix_other.nim @@ -410,7 +410,7 @@ else: type Socklen* {.importc: "socklen_t", header: "<sys/socket.h>".} = cuint - TSa_Family* {.importc: "sa_family_t", header: "<sys/socket.h>".} = cint + TSa_Family* {.importc: "sa_family_t", header: "<sys/socket.h>".} = cushort SockAddr* {.importc: "struct sockaddr", header: "<sys/socket.h>", pure, final.} = object ## struct sockaddr diff --git a/lib/pure/includes/oserr.nim b/lib/pure/includes/oserr.nim index 493e8e174..31212d0d1 100644 --- a/lib/pure/includes/oserr.nim +++ b/lib/pure/includes/oserr.nim @@ -57,10 +57,10 @@ proc raiseOSError*(errorCode: OSErrorCode; additionalInfo = "") {.noinline.} = ## the message ``unknown OS error`` will be used. var e: ref OSError; new(e) e.errorCode = errorCode.int32 - if additionalInfo.len == 0: - e.msg = osErrorMsg(errorCode) - else: - e.msg = osErrorMsg(errorCode) & "\nAdditional info: '" & additionalInfo & "'" + e.msg = osErrorMsg(errorCode) + if additionalInfo.len > 0: + e.msg.add "; Additional info: " + e.msg.addQuoted additionalInfo if e.msg == "": e.msg = "unknown OS error" raise e diff --git a/lib/pure/net.nim b/lib/pure/net.nim index a60137dab..67cb95e2f 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -964,7 +964,7 @@ when defined(posix) or defined(nimdoc): when not defined(nimdoc): var socketAddr = makeUnixAddr(path) if socket.fd.connect(cast[ptr SockAddr](addr socketAddr), - sizeof(socketAddr).Socklen) != 0'i32: + (sizeof(socketAddr.sun_family) + path.len).Socklen) != 0'i32: raiseOSError(osLastError()) proc bindUnix*(socket: Socket, path: string) = @@ -973,7 +973,7 @@ when defined(posix) or defined(nimdoc): when not defined(nimdoc): var socketAddr = makeUnixAddr(path) if socket.fd.bindAddr(cast[ptr SockAddr](addr socketAddr), - sizeof(socketAddr).Socklen) != 0'i32: + (sizeof(socketAddr.sun_family) + path.len).Socklen) != 0'i32: raiseOSError(osLastError()) when defined(ssl): diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index faeb01407..d7b734dda 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -902,7 +902,7 @@ elif not defined(useNimRtl): discard posix_spawn_file_actions_destroy(fops) discard posix_spawnattr_destroy(attr) - if res != 0'i32: raiseOSError(OSErrorCode(res)) + if res != 0'i32: raiseOSError(OSErrorCode(res), data.sysCommand) return pid else: diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 396f14972..c9a577b13 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -1325,7 +1325,7 @@ proc initSkipTable*(a: var SkipTable, sub: string) for i in 0 ..< m - 1: a[sub[i]] = m - 1 - i -proc find*(a: SkipTable, s, sub: string, start: Natural = 0, last: Natural = 0): int +proc find*(a: SkipTable, s, sub: string, start: Natural = 0, last = 0): int {.noSideEffect, rtl, extern: "nsuFindStrA".} = ## Searches for `sub` in `s` inside range `start`..`last` using preprocessed table `a`. ## If `last` is unspecified, it defaults to `s.high`. @@ -1363,7 +1363,7 @@ when not (defined(js) or defined(nimdoc) or defined(nimscript)): else: const hasCStringBuiltin = false -proc find*(s: string, sub: char, start: Natural = 0, last: Natural = 0): int {.noSideEffect, +proc find*(s: string, sub: char, start: Natural = 0, last = 0): int {.noSideEffect, rtl, extern: "nsuFindChar".} = ## Searches for `sub` in `s` inside range `start`..`last`. ## If `last` is unspecified, it defaults to `s.high`. @@ -1371,7 +1371,7 @@ proc find*(s: string, sub: char, start: Natural = 0, last: Natural = 0): int {.n ## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned. let last = if last==0: s.high else: last when nimvm: - for i in start..last: + for i in int(start)..last: if sub == s[i]: return i else: when hasCStringBuiltin: @@ -1381,11 +1381,11 @@ proc find*(s: string, sub: char, start: Natural = 0, last: Natural = 0): int {.n if not found.isNil: return cast[ByteAddress](found) -% cast[ByteAddress](s.cstring) else: - for i in start..last: + for i in int(start)..last: if sub == s[i]: return i return -1 -proc find*(s, sub: string, start: Natural = 0, last: Natural = 0): int {.noSideEffect, +proc find*(s, sub: string, start: Natural = 0, last = 0): int {.noSideEffect, rtl, extern: "nsuFindStr".} = ## Searches for `sub` in `s` inside range `start`..`last`. ## If `last` is unspecified, it defaults to `s.high`. @@ -1397,14 +1397,14 @@ proc find*(s, sub: string, start: Natural = 0, last: Natural = 0): int {.noSideE initSkipTable(a, sub) result = find(a, s, sub, start, last) -proc find*(s: string, chars: set[char], start: Natural = 0, last: Natural = 0): int {.noSideEffect, +proc find*(s: string, chars: set[char], start: Natural = 0, last = 0): int {.noSideEffect, rtl, extern: "nsuFindCharSet".} = ## Searches for `chars` in `s` inside range `start`..`last`. ## If `last` is unspecified, it defaults to `s.high`. ## ## If `s` contains none of the characters in `chars`, -1 is returned. let last = if last==0: s.high else: last - for i in start..last: + for i in int(start)..last: if s[i] in chars: return i return -1 diff --git a/tests/distinct/t7010.nim b/tests/distinct/t7010.nim new file mode 100644 index 000000000..0cae002be --- /dev/null +++ b/tests/distinct/t7010.nim @@ -0,0 +1,19 @@ +discard """ + exitcode: 0 + output: '''''' +""" + +# Snippet not defined as ```nim + +type MyInt* = distinct int + +proc `+`*(x: MyInt, y: MyInt): MyInt {.borrow.} +proc `+=`*(x: var MyInt, y: MyInt) {.borrow.} +proc `=`*(x: var MyInt, y: MyInt) {.borrow.} + +var next: MyInt + +proc getNext*() : MyInt = + result = next + next += 1.MyInt + next = next + 1.MyInt \ No newline at end of file diff --git a/tests/errmsgs/t6483.nim b/tests/errmsgs/t6483.nim new file mode 100644 index 000000000..59ea6d7e2 --- /dev/null +++ b/tests/errmsgs/t6483.nim @@ -0,0 +1,31 @@ +discard """ + errormsg: "request to generate code for .compileTime proc: newSeq" + line: 21 +""" + +type + VarItem = object + onode: NimNode + nnode: NimNode + suffix: string + + VarState = object + scopes: seq[VarScope] + + VarScope = object + variables: seq[VarItem] + children: seq[VarScope] + +when isMainModule: + var scope1 = VarScope( + variables: newSeq[VarItem](), + children: newSeq[VarScope]() + ) + var scope2 = VarScope( + variables: newSeq[VarItem](), + children: newSeq[VarScope]() + ) + var state = VarState(scopes: newSeq[VarScope]()) + state.scopes.add(scope1) + state.scopes[0].children.add(scope2) + echo($state.scopes) \ No newline at end of file diff --git a/tests/iter/tchainediterators2.nim b/tests/iter/tchainediterators2.nim new file mode 100644 index 000000000..c2e5e6170 --- /dev/null +++ b/tests/iter/tchainediterators2.nim @@ -0,0 +1,81 @@ +discard """ + output: '''start +false +0 +1 +2 +end +@[2, 4, 6, 8, 10] +@[4, 8, 12, 16, 20]''' +""" + +# bug #3837 + +proc iter1(): (iterator: int) = + let coll = [0,1,2] + result = iterator: int {.closure.} = + for i in coll: + yield i + +proc iter2(it: (iterator: int)): (iterator: int) = + result = iterator: int {.closure.} = + echo finished(it) + for i in it(): + yield i + +echo "start" +let myiter1 = iter1() +let myiter2 = iter2(myiter1) +for i in myiter2(): + echo i +echo "end" +# start +# false +# end + + +from sequtils import toSeq + +type Iterable*[T] = (iterator: T) | Slice[T] + ## Everything that can be iterated over, iterators and slices so far. + +proc toIter*[T](s: Slice[T]): iterator: T = + ## Iterate over a slice. + iterator it: T {.closure.} = + for x in s.a..s.b: + yield x + return it + +proc toIter*[T](i: iterator: T): iterator: T = + ## Nop + i + +iterator map*[T,S](i: Iterable[T], f: proc(x: T): S): S = + let i = toIter(i) + for x in i(): + yield f(x) + +proc filter*[T](i: Iterable[T], f: proc(x: T): bool): iterator: T = + ## Iterates through an iterator and yields every item that fulfills the + ## predicate `f`. + ## + ## .. code-block:: nim + ## for x in filter(1..11, proc(x): bool = x mod 2 == 0): + ## echo x + let i = toIter(i) + iterator it: T {.closure.} = + for x in i(): + if f(x): + yield x + result = it + +iterator filter*[T](i: Iterable[T], f: proc(x: T): bool): T = + let i = toIter(i) + for x in i(): + if f(x): + yield x + +var it = toSeq(filter(2..10, proc(x: int): bool = x mod 2 == 0)) +echo it # @[2, 4, 6, 8, 10] +it = toSeq(map(filter(2..10, proc(x: int): bool = x mod 2 == 0), proc(x: int): int = x * 2)) +echo it # Expected output: @[4, 8, 12, 16, 20], Actual output: @[] diff --git a/tests/stdlib/tstrutil.nim b/tests/stdlib/tstrutil.nim index f0ee755f7..64b8f8ecc 100644 --- a/tests/stdlib/tstrutil.nim +++ b/tests/stdlib/tstrutil.nim @@ -309,5 +309,20 @@ assert(' '.repeat(0) == "") assert(" ".repeat(0) == "") assert(spaces(0) == "") +# bug #8911 +when true: + static: + let a = "" + let a2 = a.replace("\n", "\\n") + +when true: + static: + let b = "b" + let b2 = b.replace("\n", "\\n") + +when true: + let c = "" + let c2 = c.replace("\n", "\\n") + main() #OUT ha/home/a1xyz/usr/bin |