@@ -376,6 +376,76 @@ proc write*(f: File, r: BiggestFloat) {.tags: [WriteIOEffect], benign.} =
376376proc write * (f: File , c: char ) {.tags : [WriteIOEffect ], benign .} =
377377 discard c_putc (cint (c), f)
378378
379+ proc isNamedTuple (T: typedesc ): bool {.magic : " TypeTrait" .}
380+ # Taken from typetraits.
381+
382+ proc writeEscapedChar (f: File , c: char ) {.inline .} =
383+ # Analogue to `sysetm.addEscapedChar`.
384+ case c
385+ of '\a ' : f.write " \\ a" # \x07
386+ of '\b ' : f.write " \\ b" # \x08
387+ of '\t ' : f.write " \\ t" # \x09
388+ of '\L ' : f.write " \\ n" # \x0A
389+ of '\v ' : f.write " \\ v" # \x0B
390+ of '\f ' : f.write " \\ f" # \x0C
391+ of '\c ' : f.write " \\ c" # \x0D
392+ of '\e ' : f.write " \\ e" # \x1B
393+ of '\\ ' : f.write (" \\\\ " )
394+ of '\' ' : f.write (" \\ '" )
395+ of '\" ' : f.write (" \\\" " )
396+ of {'\32 ' .. '\126 ' } - {'\\ ' , '\' ' , '\" ' }: f.write (c)
397+ else :
398+ f.write (" \\ x" )
399+ const HexChars = " 0123456789ABCDEF"
400+ let n = ord (c)
401+ f.write (HexChars [int ((n and 0x F0 ) shr 4 )])
402+ f.write (HexChars [int (n and 0x F )])
403+
404+ proc writeQuoted [T](f: File , arg: T) =
405+ # analogue to `addQuoted` in `system`
406+ when T is string or T is cstring :
407+ f.write (" \" " )
408+ for c in arg:
409+ # Only ASCII chars are escaped to avoid butchering
410+ # multibyte UTF-8 characters.
411+ if c <= 127 .char :
412+ f.writeEscapedChar (c)
413+ else :
414+ f.write c
415+ f.write (" \" " )
416+ elif T is char :
417+ f.write (" '" )
418+ f.addEscapedChar (x)
419+ f.write (" '" )
420+ # prevent temporary string allocation
421+ else :
422+ f.write (x)
423+
424+ proc write * [T: tuple | object ](f: File ; arg: T) =
425+ f.write " ("
426+ const isNamed = isNamedTuple (T)
427+ var count = 0
428+ for name, value in fieldPairs (arg):
429+ if count != 0 :
430+ f.write (" , " )
431+
432+ when isNamed:
433+ f.write (name, " : " )
434+
435+ when compiles ($ value):
436+ when value isnot string and value isnot seq and compiles (value.isNil):
437+ if value.isNil: result .add " nil"
438+ else : f.writeQuoted (value)
439+ else :
440+ f.writeQuoted (value)
441+ else :
442+ f.write (" ..." )
443+ inc count
444+
445+ if not isNamed and count == 1 :
446+ f.write (" ," ) # one tuple needs post comma, e.g. ``("abc",)``
447+ f.write (" )" )
448+
379449when defined (harmfulOverloadOfWrite):
380450 proc write * (f: File , a: varargs [string , `$`]) {.tags : [WriteIOEffect ], benign .} =
381451 for x in items (a): write (f, x)
0 commit comments