summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/pragmas.nim55
-rw-r--r--doc/manual/ffi.txt26
-rw-r--r--lib/deprecated/pure/ftpclient.nim4
-rw-r--r--lib/pure/algorithm.nim2
-rw-r--r--lib/pure/collections/sequtils.nim16
-rw-r--r--lib/pure/oids.nim3
-rw-r--r--lib/system.nim4
7 files changed, 62 insertions, 48 deletions
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index 1f93f5317..db5f8e727 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -90,43 +90,38 @@ proc pragmaAsm*(c: PContext, n: PNode): char =
       else:
         invalidPragma(it)
 
-proc setExternName(s: PSym, extname: string) =
-  s.loc.r = rope(extname % s.name.s)
+proc setExternName(s: PSym, extname: string, info: TLineInfo) =
+  # special cases to improve performance:
+  if extname == "$1":
+    s.loc.r = rope(s.name.s)
+  elif '$' notin extname:
+    s.loc.r = rope(extname)
+  else:
+    try:
+      s.loc.r = rope(extname % s.name.s)
+    except ValueError:
+      localError(info, "invalid extern name: '" & extname & "'. (Forgot to escape '$'?)")
   if gCmd == cmdPretty and '$' notin extname:
     # note that '{.importc.}' is transformed into '{.importc: "$1".}'
     s.loc.flags.incl(lfFullExternalName)
 
-proc makeExternImport(s: PSym, extname: string) =
-  setExternName(s, extname)
+proc makeExternImport(s: PSym, extname: string, info: TLineInfo) =
+  setExternName(s, extname, info)
   incl(s.flags, sfImportc)
   excl(s.flags, sfForward)
 
-proc validateExternCName(s: PSym, info: TLineInfo) =
-  ## Validates that the symbol name in s.loc.r is a valid C identifier.
-  ##
-  ## Valid identifiers are those alphanumeric including the underscore not
-  ## starting with a number. If the check fails, a generic error will be
-  ## displayed to the user.
-  let target = $s.loc.r
-  if target.len < 1 or target[0] notin IdentStartChars or
-      not target.allCharsInSet(IdentChars):
-    localError(info, errGenerated, "invalid exported symbol")
-
 proc makeExternExport(s: PSym, extname: string, info: TLineInfo) =
-  setExternName(s, extname)
-  # XXX to fix make it work with nimrtl.
-  #if gCmd in {cmdCompileToC, cmdCompileToCpp, cmdCompileToOC}:
-  #  validateExternCName(s, info)
+  setExternName(s, extname, info)
   incl(s.flags, sfExportc)
 
-proc processImportCompilerProc(s: PSym, extname: string) =
-  setExternName(s, extname)
+proc processImportCompilerProc(s: PSym, extname: string, info: TLineInfo) =
+  setExternName(s, extname, info)
   incl(s.flags, sfImportc)
   excl(s.flags, sfForward)
   incl(s.loc.flags, lfImportCompilerProc)
 
-proc processImportCpp(s: PSym, extname: string) =
-  setExternName(s, extname)
+proc processImportCpp(s: PSym, extname: string, info: TLineInfo) =
+  setExternName(s, extname, info)
   incl(s.flags, sfImportc)
   incl(s.flags, sfInfixCall)
   excl(s.flags, sfForward)
@@ -134,8 +129,8 @@ proc processImportCpp(s: PSym, extname: string) =
   incl(m.flags, sfCompileToCpp)
   extccomp.gMixedMode = true
 
-proc processImportObjC(s: PSym, extname: string) =
-  setExternName(s, extname)
+proc processImportObjC(s: PSym, extname: string, info: TLineInfo) =
+  setExternName(s, extname, info)
   incl(s.flags, sfImportc)
   incl(s.flags, sfNamedParamCall)
   excl(s.flags, sfForward)
@@ -623,10 +618,10 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
       of wExportc:
         makeExternExport(sym, getOptionalStr(c, it, "$1"), it.info)
         incl(sym.flags, sfUsed) # avoid wrong hints
-      of wImportc: makeExternImport(sym, getOptionalStr(c, it, "$1"))
+      of wImportc: makeExternImport(sym, getOptionalStr(c, it, "$1"), it.info)
       of wImportCompilerProc:
-        processImportCompilerProc(sym, getOptionalStr(c, it, "$1"))
-      of wExtern: setExternName(sym, expectStrLit(c, it))
+        processImportCompilerProc(sym, getOptionalStr(c, it, "$1"), it.info)
+      of wExtern: setExternName(sym, expectStrLit(c, it), it.info)
       of wImmediate:
         if sym.kind in {skTemplate, skMacro}:
           incl(sym.flags, sfImmediate)
@@ -637,9 +632,9 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
         if sym.kind == skTemplate: incl(sym.flags, sfDirty)
         else: invalidPragma(it)
       of wImportCpp:
-        processImportCpp(sym, getOptionalStr(c, it, "$1"))
+        processImportCpp(sym, getOptionalStr(c, it, "$1"), it.info)
       of wImportObjC:
-        processImportObjC(sym, getOptionalStr(c, it, "$1"))
+        processImportObjC(sym, getOptionalStr(c, it, "$1"), it.info)
       of wAlign:
         if sym.typ == nil: invalidPragma(it)
         var align = expectIntLit(c, it)
diff --git a/doc/manual/ffi.txt b/doc/manual/ffi.txt
index 5055f18af..d7d9596d2 100644
--- a/doc/manual/ffi.txt
+++ b/doc/manual/ffi.txt
@@ -16,12 +16,20 @@ spelled*:
 .. code-block::
   proc printf(formatstr: cstring) {.header: "<stdio.h>", importc: "printf", varargs.}
 
-Note that this pragma is somewhat of a misnomer: Other backends will provide
+Note that this pragma is somewhat of a misnomer: Other backends do provide
 the same feature under the same name. Also, if one is interfacing with C++
 the `ImportCpp pragma <manual.html#implementation-specific-pragmas-importcpp-pragma>`_ and
 interfacing with Objective-C the `ImportObjC pragma
 <manual.html#implementation-specific-pragmas-importobjc-pragma>`_ can be used.
 
+The string literal passed to ``importc`` can be a format string:
+
+.. code-block:: Nim
+  proc p(s: cstring) {.importc: "prefix$1".}
+
+In the example the external name of ``p`` is set to ``prefixp``. Only ``$1``
+is available and a literal dollar sign must be written as ``$$``.
+
 
 Exportc pragma
 --------------
@@ -33,9 +41,19 @@ name is the Nim identifier *exactly as spelled*:
 .. code-block:: Nim
   proc callme(formatstr: cstring) {.exportc: "callMe", varargs.}
 
-Note that this pragma is somewhat of a misnomer: Other backends will provide
+Note that this pragma is somewhat of a misnomer: Other backends do provide
 the same feature under the same name.
 
+The string literal passed to ``exportc`` can be a format string:
+
+.. code-block:: Nim
+  proc p(s: string) {.exportc: "prefix$1".} =
+    echo s
+
+In the example the external name of ``p`` is set to ``prefixp``. Only ``$1``
+is available and a literal dollar sign must be written as ``$$``.
+
+
 
 Extern pragma
 -------------
@@ -46,7 +64,9 @@ mangling. The string literal passed to ``extern`` can be a format string:
   proc p(s: string) {.extern: "prefix$1".} =
     echo s
 
-In the example the external name of ``p`` is set to ``prefixp``.
+In the example the external name of ``p`` is set to ``prefixp``. Only ``$1``
+is available and a literal dollar sign must be written as ``$$``.
+
 
 
 Bycopy pragma
diff --git a/lib/deprecated/pure/ftpclient.nim b/lib/deprecated/pure/ftpclient.nim
index 1188c0795..ed2f14450 100644
--- a/lib/deprecated/pure/ftpclient.nim
+++ b/lib/deprecated/pure/ftpclient.nim
@@ -129,10 +129,10 @@ proc ftpClient*(address: string, port = Port(21),
   result.csock = socket()
   if result.csock == invalidSocket: raiseOSError(osLastError())
 
-template blockingOperation(sock: Socket, body: stmt) {.immediate.} =
+template blockingOperation(sock: Socket, body: untyped) =
   body
 
-template blockingOperation(sock: asyncio.AsyncSocket, body: stmt) {.immediate.} =
+template blockingOperation(sock: asyncio.AsyncSocket, body: untyped) =
   sock.setBlocking(true)
   body
   sock.setBlocking(false)
diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim
index eee4fab22..b83daf245 100644
--- a/lib/pure/algorithm.nim
+++ b/lib/pure/algorithm.nim
@@ -231,7 +231,7 @@ template sortedByIt*(seq1, op: untyped): untyped =
   ##
   ##   echo people.sortedByIt((it.age, it.name))
   ##
-  var result {.gensym.} = sorted(seq1, proc(x, y: type(seq1[0])): int =
+  var result = sorted(seq1, proc(x, y: type(seq1[0])): int =
     var it {.inject.} = x
     let a = op
     it = y
diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim
index e277ee9e8..f458b7636 100644
--- a/lib/pure/collections/sequtils.nim
+++ b/lib/pure/collections/sequtils.nim
@@ -371,7 +371,7 @@ template filterIt*(seq1, pred: untyped): untyped =
   ##      notAcceptable = filterIt(temperatures, it > 50 or it < -10)
   ##    assert acceptable == @[-2.0, 24.5, 44.31]
   ##    assert notAcceptable == @[-272.15, 99.9, -113.44]
-  var result {.gensym.} = newSeq[type(seq1[0])]()
+  var result = newSeq[type(seq1[0])]()
   for it {.inject.} in items(seq1):
     if pred: result.add(it)
   result
@@ -420,7 +420,7 @@ template allIt*(seq1, pred: untyped): bool =
   ##   let numbers = @[1, 4, 5, 8, 9, 7, 4]
   ##   assert allIt(numbers, it < 10) == true
   ##   assert allIt(numbers, it < 9) == false
-  var result {.gensym.} = true
+  var result = true
   for it {.inject.} in items(seq1):
     if not pred:
       result = false
@@ -451,7 +451,7 @@ template anyIt*(seq1, pred: untyped): bool =
   ##   let numbers = @[1, 4, 5, 8, 9, 7, 4]
   ##   assert anyIt(numbers, it > 8) == true
   ##   assert anyIt(numbers, it > 9) == false
-  var result {.gensym.} = false
+  var result = false
   for it {.inject.} in items(seq1):
     if pred:
       result = true
@@ -512,7 +512,7 @@ template foldl*(sequence, operation: untyped): untyped =
   ##   assert concatenation == "nimiscool"
   let s = sequence
   assert s.len > 0, "Can't fold empty sequences"
-  var result {.gensym.}: type(s[0])
+  var result: type(s[0])
   result = s[0]
   for i in 1..<s.len:
     let
@@ -537,7 +537,7 @@ template foldl*(sequence, operation, first): untyped =
   ##     numbers = @[0, 8, 1, 5]
   ##     digits = foldl(numbers, a & (chr(b + ord('0'))), "")
   ##   assert digits == "0815"
-  var result {.gensym.}: type(first)
+  var result: type(first)
   result = first
   for x in items(sequence):
     let
@@ -574,7 +574,7 @@ template foldr*(sequence, operation: untyped): untyped =
   ##   assert concatenation == "nimiscool"
   let s = sequence
   assert s.len > 0, "Can't fold empty sequences"
-  var result {.gensym.}: type(s[0])
+  var result: type(s[0])
   result = sequence[s.len - 1]
   for i in countdown(s.len - 2, 0):
     let
@@ -598,7 +598,7 @@ template mapIt*(seq1, typ, op: untyped): untyped =
   ##   assert strings == @["4", "8", "12", "16"]
   ## **Deprecated since version 0.12.0:** Use the ``mapIt(seq1, op)``
   ##   template instead.
-  var result {.gensym.}: seq[typ] = @[]
+  var result: seq[typ] = @[]
   for it {.inject.} in items(seq1):
     result.add(op)
   result
@@ -662,7 +662,7 @@ template newSeqWith*(len: int, init: untyped): untyped =
   ##   import random
   ##   var seqRand = newSeqWith(20, random(10))
   ##   echo seqRand
-  var result {.gensym.} = newSeq[type(init)](len)
+  var result = newSeq[type(init)](len)
   for i in 0 .. <len:
     result[i] = init
   result
diff --git a/lib/pure/oids.nim b/lib/pure/oids.nim
index fca10dab6..e4c97b260 100644
--- a/lib/pure/oids.nim
+++ b/lib/pure/oids.nim
@@ -74,8 +74,7 @@ proc genOid*(): Oid =
 
   var t = gettime(nil)
 
-  var i = int32(incr)
-  atomicInc(incr)
+  var i = int32(atomicInc(incr))
 
   if fuzz == 0:
     # racy, but fine semantically:
diff --git a/lib/system.nim b/lib/system.nim
index 82980d9da..356248e6c 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -3232,7 +3232,7 @@ proc `[]`*[Idx, T](a: array[Idx, T], x: Slice[int]): seq[T] =
   when low(a) < 0:
     {.error: "Slicing for arrays with negative indices is unsupported.".}
   var L = x.b - x.a + 1
-  newSeq(result, L)
+  result = newSeq[T](L)
   for i in 0.. <L: result[i] = a[i + x.a]
 
 proc `[]=`*[Idx, T](a: var array[Idx, T], x: Slice[int], b: openArray[T]) =
@@ -3681,4 +3681,4 @@ when defined(nimconfig):
 when defined(windows) and appType == "console" and not defined(nimconfig):
   proc setConsoleOutputCP(codepage: cint): cint {.stdcall, dynlib: "kernel32",
     importc: "SetConsoleOutputCP".}
-  discard setConsoleOutputCP(65001) # 65001 - utf-8 codepage
\ No newline at end of file
+  discard setConsoleOutputCP(65001) # 65001 - utf-8 codepage