printf.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. // Copyright 2020 The Libc Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. //go:build !(linux && (amd64 || arm64 || loong64 || ppc64le || s390x || riscv64 || 386 || arm))
  5. package libc // import "modernc.org/libc"
  6. import (
  7. "bytes"
  8. "fmt"
  9. "runtime"
  10. "strconv"
  11. "strings"
  12. "unsafe"
  13. )
  14. const (
  15. modNone = iota
  16. modHH
  17. modH
  18. modL
  19. modLL
  20. modLD
  21. modQ
  22. modCapitalL
  23. modJ
  24. modZ
  25. modCapitalZ
  26. modT
  27. mod32
  28. mod64
  29. )
  30. // Format of the format string
  31. //
  32. // The format string is a character string, beginning and ending in its initial
  33. // shift state, if any. The format string is composed of zero or more
  34. // directives: ordinary characters (not %), which are copied unchanged to
  35. // the output stream; and conversion specifications, each of which results in
  36. // fetching zero or more subsequent arguments.
  37. func printf(format, args uintptr) []byte {
  38. // format0 := format
  39. // args0 := args
  40. buf := bytes.NewBuffer(nil)
  41. for {
  42. switch c := *(*byte)(unsafe.Pointer(format)); c {
  43. case '%':
  44. format = printfConversion(buf, format, &args)
  45. case 0:
  46. // if dmesgs {
  47. // dmesg("%v: %q, %#x -> %q", origin(1), GoString(format0), args0, buf.Bytes())
  48. // }
  49. return buf.Bytes()
  50. default:
  51. format++
  52. buf.WriteByte(c)
  53. }
  54. }
  55. }
  56. // Each conversion specification is introduced by the character %, and ends
  57. // with a conversion specifier. In between there may be (in this order) zero
  58. // or more flags, an optional minimum field width, an optional precision and
  59. // an optional length modifier.
  60. func printfConversion(buf *bytes.Buffer, format uintptr, args *uintptr) uintptr {
  61. format++ // '%'
  62. spec := "%"
  63. // Flags characters
  64. //
  65. // The character % is followed by zero or more of the following flags:
  66. flags:
  67. for {
  68. switch c := *(*byte)(unsafe.Pointer(format)); c {
  69. case '#':
  70. // The value should be converted to an "alternate form". For o conversions,
  71. // the first character of the output string is made zero (by prefixing a 0 if
  72. // it was not zero already). For x and X conversions, a nonzero result has
  73. // the string "0x" (or "0X" for X conversions) prepended to it. For a, A, e,
  74. // E, f, F, g, and G conversions, the result will always contain a decimal
  75. // point, even if no digits follow it (normally, a decimal point appears in the
  76. // results of those conversions only if a digit follows). For g and G
  77. // conversions, trailing zeros are not removed from the result as they would
  78. // otherwise be. For other conversions, the result is undefined.
  79. format++
  80. spec += "#"
  81. case '0':
  82. // The value should be zero padded. For d, i, o, u, x, X, a, A, e, E, f, F,
  83. // g, and G conversions, the converted value is padded on the left with zeros
  84. // rather than blanks. If the 0 and - flags both appear, the 0 flag is
  85. // ignored. If a precision is given with a numeric conversion (d, i, o, u, x,
  86. // and X), the 0 flag is ignored. For other conversions, the behav‐ ior is
  87. // undefined.
  88. format++
  89. spec += "0"
  90. case '-':
  91. // The converted value is to be left adjusted on the field boundary. (The
  92. // default is right justification.) The converted value is padded on the right
  93. // with blanks, rather than on the left with blanks or zeros. A - overrides a
  94. // 0 if both are given.
  95. format++
  96. spec += "-"
  97. case ' ':
  98. // A blank should be left before a positive number (or empty string) produced
  99. // by a signed conversion.
  100. format++
  101. spec += " "
  102. case '+':
  103. // A sign (+ or -) should always be placed before a number produced by a signed
  104. // conversion. By default, a sign is used only for negative numbers. A +
  105. // overrides a space if both are used.
  106. format++
  107. spec += "+"
  108. default:
  109. break flags
  110. }
  111. }
  112. format, width, hasWidth := parseFieldWidth(format, args)
  113. if hasWidth {
  114. spec += strconv.Itoa(width)
  115. }
  116. format, prec, hasPrecision := parsePrecision(format, args)
  117. format, mod := parseLengthModifier(format)
  118. var str string
  119. more:
  120. // Conversion specifiers
  121. //
  122. // A character that specifies the type of conversion to be applied. The
  123. // conversion specifiers and their meanings are:
  124. switch c := *(*byte)(unsafe.Pointer(format)); c {
  125. case 'd', 'i':
  126. // The int argument is converted to signed decimal notation. The precision,
  127. // if any, gives the minimum number of digits that must appear; if the
  128. // converted value requires fewer digits, it is padded on the left with zeros.
  129. // The default precision is 1. When 0 is printed with an explicit precision 0,
  130. // the output is empty.
  131. format++
  132. var arg int64
  133. if isWindows && mod == modL {
  134. mod = modNone
  135. }
  136. switch mod {
  137. case modL, modLL, mod64, modJ:
  138. arg = VaInt64(args)
  139. case modH:
  140. arg = int64(int16(VaInt32(args)))
  141. case modHH:
  142. arg = int64(int8(VaInt32(args)))
  143. case mod32, modNone:
  144. arg = int64(VaInt32(args))
  145. case modT:
  146. arg = int64(VaInt64(args))
  147. default:
  148. panic(todo("", mod))
  149. }
  150. if arg == 0 && hasPrecision && prec == 0 {
  151. break
  152. }
  153. if hasPrecision {
  154. panic(todo("", prec))
  155. }
  156. f := spec + "d"
  157. str = fmt.Sprintf(f, arg)
  158. case 'u':
  159. // The unsigned int argument is converted to unsigned decimal notation. The
  160. // precision, if any, gives the minimum number of digits that must appear; if
  161. // the converted value requires fewer digits, it is padded on the left with
  162. // zeros. The default precision is 1. When 0 is printed with an explicit
  163. // precision 0, the output is empty.
  164. format++
  165. var arg uint64
  166. if isWindows && mod == modL {
  167. mod = modNone
  168. }
  169. switch mod {
  170. case modNone:
  171. arg = uint64(VaUint32(args))
  172. case modL, modLL, mod64:
  173. arg = VaUint64(args)
  174. case modH:
  175. arg = uint64(uint16(VaInt32(args)))
  176. case modHH:
  177. arg = uint64(uint8(VaInt32(args)))
  178. case mod32:
  179. arg = uint64(VaInt32(args))
  180. case modZ:
  181. arg = uint64(VaInt64(args))
  182. default:
  183. panic(todo("", mod))
  184. }
  185. if arg == 0 && hasPrecision && prec == 0 {
  186. break
  187. }
  188. if hasPrecision {
  189. panic(todo("", prec))
  190. }
  191. f := spec + "d"
  192. str = fmt.Sprintf(f, arg)
  193. case 'o':
  194. // The unsigned int argument is converted to unsigned octal notation. The
  195. // precision, if any, gives the minimum number of digits that must appear; if
  196. // the converted value requires fewer digits, it is padded on the left with
  197. // zeros. The default precision is 1. When 0 is printed with an explicit
  198. // precision 0, the output is empty.
  199. format++
  200. var arg uint64
  201. if isWindows && mod == modL {
  202. mod = modNone
  203. }
  204. switch mod {
  205. case modNone:
  206. arg = uint64(VaUint32(args))
  207. case modL, modLL, mod64:
  208. arg = VaUint64(args)
  209. case modH:
  210. arg = uint64(uint16(VaInt32(args)))
  211. case modHH:
  212. arg = uint64(uint8(VaInt32(args)))
  213. case mod32:
  214. arg = uint64(VaInt32(args))
  215. default:
  216. panic(todo("", mod))
  217. }
  218. if arg == 0 && hasPrecision && prec == 0 {
  219. break
  220. }
  221. if hasPrecision {
  222. panic(todo("", prec))
  223. }
  224. f := spec + "o"
  225. str = fmt.Sprintf(f, arg)
  226. case 'b':
  227. // Base 2.
  228. format++
  229. var arg uint64
  230. if isWindows && mod == modL {
  231. mod = modNone
  232. }
  233. switch mod {
  234. case modNone:
  235. arg = uint64(VaUint32(args))
  236. case modL, modLL, mod64:
  237. arg = VaUint64(args)
  238. case modH:
  239. arg = uint64(uint16(VaInt32(args)))
  240. case modHH:
  241. arg = uint64(uint8(VaInt32(args)))
  242. case mod32:
  243. arg = uint64(VaInt32(args))
  244. default:
  245. panic(todo("", mod))
  246. }
  247. if arg == 0 && hasPrecision && prec == 0 {
  248. break
  249. }
  250. if hasPrecision {
  251. panic(todo("", prec))
  252. }
  253. f := spec + "b"
  254. str = fmt.Sprintf(f, arg)
  255. case 'I':
  256. if !isWindows {
  257. panic(todo("%#U", c))
  258. }
  259. format++
  260. switch c = *(*byte)(unsafe.Pointer(format)); c {
  261. case 'x', 'X':
  262. // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-wsprintfa
  263. //
  264. // Ix, IX
  265. //
  266. // 64-bit unsigned hexadecimal integer in lowercase or uppercase on 64-bit
  267. // platforms, 32-bit unsigned hexadecimal integer in lowercase or uppercase on
  268. // 32-bit platforms.
  269. if unsafe.Sizeof(int(0)) == 4 {
  270. mod = mod32
  271. }
  272. case '3':
  273. // https://en.wikipedia.org/wiki/Printf_format_string#Length_field
  274. //
  275. // I32 For integer types, causes printf to expect a 32-bit (double word) integer argument.
  276. format++
  277. switch c = *(*byte)(unsafe.Pointer(format)); c {
  278. case '2':
  279. format++
  280. mod = mod32
  281. goto more
  282. default:
  283. panic(todo("%#U", c))
  284. }
  285. case '6':
  286. // https://en.wikipedia.org/wiki/Printf_format_string#Length_field
  287. //
  288. // I64 For integer types, causes printf to expect a 64-bit (quad word) integer argument.
  289. format++
  290. switch c = *(*byte)(unsafe.Pointer(format)); c {
  291. case '4':
  292. format++
  293. mod = mod64
  294. goto more
  295. default:
  296. panic(todo("%#U", c))
  297. }
  298. default:
  299. panic(todo("%#U", c))
  300. }
  301. fallthrough
  302. case 'X':
  303. fallthrough
  304. case 'x':
  305. // The unsigned int argument is converted to unsigned hexadecimal notation.
  306. // The letters abcdef are used for x conversions; the letters ABCDEF are used
  307. // for X conversions. The precision, if any, gives the minimum number of
  308. // digits that must appear; if the converted value requires fewer digits, it is
  309. // padded on the left with zeros. The default precision is 1. When 0 is
  310. // printed with an explicit precision 0, the output is empty.
  311. format++
  312. var arg uint64
  313. if isWindows && mod == modL {
  314. mod = modNone
  315. }
  316. switch mod {
  317. case modNone:
  318. arg = uint64(VaUint32(args))
  319. case modL, modLL, mod64:
  320. arg = VaUint64(args)
  321. case modH:
  322. arg = uint64(uint16(VaInt32(args)))
  323. case modHH:
  324. arg = uint64(uint8(VaInt32(args)))
  325. case mod32:
  326. arg = uint64(VaInt32(args))
  327. case modZ:
  328. arg = uint64(VaInt64(args))
  329. default:
  330. panic(todo("", mod))
  331. }
  332. if arg == 0 && hasPrecision && prec == 0 {
  333. break
  334. }
  335. if strings.Contains(spec, "#") && arg == 0 {
  336. spec = strings.ReplaceAll(spec, "#", "")
  337. }
  338. var f string
  339. switch {
  340. case hasPrecision:
  341. f = fmt.Sprintf("%s.%d%c", spec, prec, c)
  342. default:
  343. f = spec + string(c)
  344. }
  345. str = fmt.Sprintf(f, arg)
  346. case 'e', 'E':
  347. // The double argument is rounded and converted in the style [-]d.ddde±dd where
  348. // there is one digit before the decimal-point character and the number of
  349. // digits after it is equal to the precision; if the precision is missing, it
  350. // is taken as 6; if the precision is zero, no decimal-point character appears.
  351. // An E conversion uses the letter E (rather than e) to intro‐ duce the
  352. // exponent. The exponent always contains at least two digits; if the value is
  353. // zero, the exponent is 00.
  354. format++
  355. arg := VaFloat64(args)
  356. if !hasPrecision {
  357. prec = 6
  358. }
  359. f := fmt.Sprintf("%s.%d%c", spec, prec, c)
  360. str = fmt.Sprintf(f, arg)
  361. case 'f', 'F':
  362. // The double argument is rounded and converted to decimal notation in the
  363. // style [-]ddd.ddd, where the number of digits after the decimal-point
  364. // character is equal to the precision specification. If the precision
  365. // is missing, it is taken as 6; if the precision is explicitly zero, no
  366. // decimal-point character appears. If a decimal point appears, at least one
  367. // digit appears before it.
  368. format++
  369. arg := VaFloat64(args)
  370. if !hasPrecision {
  371. prec = 6
  372. }
  373. f := fmt.Sprintf("%s.%d%c", spec, prec, c)
  374. str = fixNanInf(fmt.Sprintf(f, arg))
  375. case 'G':
  376. fallthrough
  377. case 'g':
  378. // The double argument is converted in style f or e (or F or E for G
  379. // conversions). The precision specifies the number of significant digits. If
  380. // the precision is missing, 6 digits are given; if the precision is zero, it
  381. // is treated as 1. Style e is used if the exponent from its conversion is
  382. // less than -4 or greater than or equal to the precision. Trailing zeros are
  383. // removed from the fractional part of the result; a decimal point appears only
  384. // if it is followed by at least one digit.
  385. format++
  386. arg := VaFloat64(args)
  387. if !hasPrecision {
  388. prec = 6
  389. }
  390. if prec == 0 {
  391. prec = 1
  392. }
  393. f := fmt.Sprintf("%s.%d%c", spec, prec, c)
  394. str = fixNanInf(fmt.Sprintf(f, arg))
  395. case 's':
  396. // If no l modifier is present: the const char * argument is expected to be a
  397. // pointer to an array of character type (pointer to a string). Characters
  398. // from the array are written up to (but not including) a terminating null byte
  399. // ('\0'); if a precision is specified, no more than the number specified are
  400. // written. If a precision is given, no null byte need be present; if
  401. // the precision is not specified, or is greater than the size of the array,
  402. // the array must contain a terminating null byte.
  403. //
  404. // If an l modifier is present: the const wchar_t * argument is expected
  405. // to be a pointer to an array of wide characters. Wide characters from the
  406. // array are converted to multibyte characters (each by a call to the
  407. // wcrtomb(3) function, with a conversion state starting in the initial state
  408. // before the first wide character), up to and including a terminating null
  409. // wide character. The resulting multibyte characters are written up to
  410. // (but not including) the terminating null byte. If a precision is specified,
  411. // no more bytes than the number specified are written, but no partial
  412. // multibyte characters are written. Note that the precision determines the
  413. // number of bytes written, not the number of wide characters or screen
  414. // positions. The array must contain a terminating null wide character,
  415. // unless a precision is given and it is so small that the number of bytes
  416. // written exceeds it before the end of the array is reached.
  417. format++
  418. arg := VaUintptr(args)
  419. switch mod {
  420. case modNone:
  421. var f string
  422. switch {
  423. case hasPrecision:
  424. f = fmt.Sprintf("%s.%ds", spec, prec)
  425. str = fmt.Sprintf(f, GoString(arg))
  426. default:
  427. f = spec + "s"
  428. str = fmt.Sprintf(f, GoString(arg))
  429. }
  430. default:
  431. panic(todo(""))
  432. }
  433. case 'p':
  434. // The void * pointer argument is printed in hexadecimal (as if by %#x or
  435. // %#lx).
  436. format++
  437. switch runtime.GOOS {
  438. case "windows":
  439. switch runtime.GOARCH {
  440. case "386", "arm":
  441. fmt.Fprintf(buf, "%08X", VaUintptr(args))
  442. default:
  443. fmt.Fprintf(buf, "%016X", VaUintptr(args))
  444. }
  445. default:
  446. fmt.Fprintf(buf, "%#0x", VaUintptr(args))
  447. }
  448. case 'c':
  449. // If no l modifier is present, the int argument is converted to an unsigned
  450. // char, and the resulting character is written. If an l modifier is present,
  451. // the wint_t (wide character) ar‐ gument is converted to a multibyte sequence
  452. // by a call to the wcrtomb(3) function, with a conversion state starting in
  453. // the initial state, and the resulting multibyte string is writ‐ ten.
  454. format++
  455. switch mod {
  456. case modNone:
  457. arg := VaInt32(args)
  458. buf.WriteByte(byte(arg))
  459. default:
  460. panic(todo(""))
  461. }
  462. case '%':
  463. // A '%' is written. No argument is converted. The complete conversion
  464. // specification is '%%'.
  465. format++
  466. buf.WriteByte('%')
  467. default:
  468. panic(todo("%#U", c))
  469. }
  470. buf.WriteString(str)
  471. return format
  472. }
  473. // Field width
  474. //
  475. // An optional decimal digit string (with nonzero first digit) specifying a
  476. // minimum field width. If the converted value has fewer characters than the
  477. // field width, it will be padded with spa‐ ces on the left (or right, if the
  478. // left-adjustment flag has been given). Instead of a decimal digit string one
  479. // may write "*" or "*m$" (for some decimal integer m) to specify that the
  480. // field width is given in the next argument, or in the m-th argument,
  481. // respectively, which must be of type int. A negative field width is taken as
  482. // a '-' flag followed by a positive field width. In no case does a
  483. // nonexistent or small field width cause truncation of a field; if the result
  484. // of a conversion is wider than the field width, the field is expanded to
  485. // contain the conversion result.
  486. func parseFieldWidth(format uintptr, args *uintptr) (_ uintptr, n int, ok bool) {
  487. first := true
  488. for {
  489. var digit int
  490. switch c := *(*byte)(unsafe.Pointer(format)); {
  491. case first && c == '0':
  492. return format, n, ok
  493. case first && c == '*':
  494. format++
  495. switch c := *(*byte)(unsafe.Pointer(format)); {
  496. case c >= '0' && c <= '9':
  497. panic(todo(""))
  498. default:
  499. return format, int(VaInt32(args)), true
  500. }
  501. case c >= '0' && c <= '9':
  502. format++
  503. ok = true
  504. first = false
  505. digit = int(c) - '0'
  506. default:
  507. return format, n, ok
  508. }
  509. n0 := n
  510. n = 10*n + digit
  511. if n < n0 {
  512. panic(todo(""))
  513. }
  514. }
  515. }
  516. // Precision
  517. //
  518. // An optional precision, in the form of a period ('.') followed by an
  519. // optional decimal digit string. Instead of a decimal digit string one may
  520. // write "*" or "*m$" (for some decimal integer m) to specify that the
  521. // precision is given in the next argument, or in the m-th argument,
  522. // respectively, which must be of type int. If the precision is given as just
  523. // '.', the precision is taken to be zero. A negative precision is taken
  524. // as if the precision were omitted. This gives the minimum number of digits
  525. // to appear for d, i, o, u, x, and X conversions, the number of digits to
  526. // appear after the radix character for a, A, e, E, f, and F conversions, the
  527. // maximum number of significant digits for g and G conversions, or the maximum
  528. // number of characters to be printed from a string for s and S conversions.
  529. func parsePrecision(format uintptr, args *uintptr) (_ uintptr, n int, ok bool) {
  530. for {
  531. switch c := *(*byte)(unsafe.Pointer(format)); c {
  532. case '.':
  533. format++
  534. first := true
  535. for {
  536. switch c := *(*byte)(unsafe.Pointer(format)); {
  537. case first && c == '*':
  538. format++
  539. n = int(VaInt32(args))
  540. return format, n, true
  541. case c >= '0' && c <= '9':
  542. format++
  543. first = false
  544. n0 := n
  545. n = 10*n + (int(c) - '0')
  546. if n < n0 {
  547. panic(todo(""))
  548. }
  549. default:
  550. return format, n, true
  551. }
  552. }
  553. default:
  554. return format, 0, false
  555. }
  556. }
  557. }
  558. // Length modifier
  559. //
  560. // Here, "integer conversion" stands for d, i, o, u, x, or X conversion.
  561. //
  562. // hh A following integer conversion corresponds to a signed char or
  563. // unsigned char argument, or a following n conversion corresponds to a pointer
  564. // to a signed char argument.
  565. //
  566. // h A following integer conversion corresponds to a short int or unsigned
  567. // short int argument, or a following n conversion corresponds to a pointer to
  568. // a short int argument.
  569. //
  570. // l (ell) A following integer conversion corresponds to a long int or
  571. // unsigned long int argument, or a following n conversion corresponds to a
  572. // pointer to a long int argument, or a fol‐ lowing c conversion corresponds to
  573. // a wint_t argument, or a following s conversion corresponds to a pointer to
  574. // wchar_t argument.
  575. //
  576. // ll (ell-ell). A following integer conversion corresponds to a long long
  577. // int or unsigned long long int argument, or a following n conversion
  578. // corresponds to a pointer to a long long int argument.
  579. //
  580. // q A synonym for ll. This is a nonstandard extension, derived from BSD;
  581. // avoid its use in new code.
  582. //
  583. // L A following a, A, e, E, f, F, g, or G conversion corresponds to a
  584. // long double argument. (C99 allows %LF, but SUSv2 does not.)
  585. //
  586. // j A following integer conversion corresponds to an intmax_t or
  587. // uintmax_t argument, or a following n conversion corresponds to a pointer to
  588. // an intmax_t argument.
  589. //
  590. // z A following integer conversion corresponds to a size_t or ssize_t
  591. // argument, or a following n conversion corresponds to a pointer to a size_t
  592. // argument.
  593. //
  594. // Z A nonstandard synonym for z that predates the appearance of z. Do
  595. // not use in new code.
  596. //
  597. // t A following integer conversion corresponds to a ptrdiff_t argument,
  598. // or a following n conversion corresponds to a pointer to a ptrdiff_t
  599. // argument.
  600. func parseLengthModifier(format uintptr) (_ uintptr, n int) {
  601. switch c := *(*byte)(unsafe.Pointer(format)); c {
  602. case 'h':
  603. format++
  604. n = modH
  605. switch c := *(*byte)(unsafe.Pointer(format)); c {
  606. case 'h':
  607. format++
  608. n = modHH
  609. }
  610. return format, n
  611. case 'l':
  612. format++
  613. n = modL
  614. switch c := *(*byte)(unsafe.Pointer(format)); c {
  615. case 'l':
  616. format++
  617. n = modLL
  618. }
  619. return format, n
  620. case 'q':
  621. panic(todo(""))
  622. case 'L':
  623. format++
  624. n = modLD
  625. return format, n
  626. case 'j':
  627. format++
  628. n = modJ
  629. return format, n
  630. case 'z':
  631. format++
  632. return format, modZ
  633. case 'Z':
  634. format++
  635. return format, modCapitalZ
  636. case 't':
  637. format++
  638. return format, modT
  639. default:
  640. return format, 0
  641. }
  642. }
  643. func fixNanInf(s string) string {
  644. switch s {
  645. case "NaN":
  646. return "nan"
  647. case "+Inf", "-Inf":
  648. return "inf"
  649. default:
  650. return s
  651. }
  652. }