summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/cgen.nim27
-rw-r--r--compiler/commands.nim8
-rw-r--r--compiler/options.nim2
-rw-r--r--compiler/parser.nim2
-rw-r--r--doc/advopt.txt4
-rw-r--r--lib/nimbase.h2
-rw-r--r--lib/posix/posix_other.nim2
-rw-r--r--lib/pure/includes/oserr.nim8
-rw-r--r--lib/pure/net.nim4
-rw-r--r--lib/pure/osproc.nim2
-rw-r--r--lib/pure/strutils.nim14
-rw-r--r--tests/distinct/t7010.nim19
-rw-r--r--tests/errmsgs/t6483.nim31
-rw-r--r--tests/iter/tchainediterators2.nim81
-rw-r--r--tests/stdlib/tstrutil.nim15
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