mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 22:10:33 +00:00
fixes #1152
This commit is contained in:
48
tests/macros/typesafeprintf.nim
Normal file
48
tests/macros/typesafeprintf.nim
Normal file
@@ -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)
|
||||
Reference in New Issue
Block a user