summary refs log tree commit diff stats
path: root/tests/macros
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2016-04-03 23:38:29 +0200
committerAndreas Rumpf <rumpf_a@web.de>2016-04-03 23:38:29 +0200
commitcb3a38afa2de4401af55fbb7b6050f499b182bf4 (patch)
tree7cb34d8933480dedcab82281a39f491fbf545368 /tests/macros
parent6e53300f83dc7646fbad834c494c34470a393885 (diff)
downloadNim-cb3a38afa2de4401af55fbb7b6050f499b182bf4.tar.gz
fixes #1152
Diffstat (limited to 'tests/macros')
-rw-r--r--tests/macros/typesafeprintf.nim48
1 files changed, 48 insertions, 0 deletions
diff --git a/tests/macros/typesafeprintf.nim b/tests/macros/typesafeprintf.nim
new file mode 100644
index 000000000..2f4622f3e
--- /dev/null
+++ b/tests/macros/typesafeprintf.nim
@@ -0,0 +1,48 @@
+discard """
+  output: '''test 10'''
+"""
+
+# bug #1152
+
+import macros, typetraits
+proc printfImpl(formatstr: cstring) {.importc: "printf", varargs.}
+
+iterator tokenize(format: string): char =
+  var i = 0
+  while true:
+    case format[i]
+    of '%':
+      case format[i+1]
+      of '\0': break
+      else: yield format[i+1]
+      i.inc
+    of '\0': break
+    else: discard
+    i.inc
+
+macro printf(formatString: string{lit}, args: varargs[typed]): untyped =
+  var i = 0
+  let err = getType(bindSym"ValueError")
+  for c in tokenize(formatString.strVal):
+    var expectedType = case c
+      of 'c': getType(bindSym"char")
+      of 'd', 'i', 'x', 'X': getType(bindSym"int")
+      of 'f', 'e', 'E', 'g', 'G': getType(bindSym"float")
+      of 's': getType(bindSym"string")
+      of 'p': getType(bindSym"pointer")
+      else: err
+
+    var actualType = getType(args[i])
+    inc i
+
+    if sameType(expectedType, err):
+      error c & " is not a valid format character"
+    elif not sameType(expectedType, actualType):
+      error "type mismatch for argument " & $i & ". expected type: " &
+            $expectedType & ", actual type: " & $actualType
+
+  # keep the original callsite, but use cprintf instead
+  result = callsite()
+  result[0] = bindSym"printfImpl"
+
+printf("test %d\n", 10)