%o base 8
%x base 16, with lower-case letters for a-f
%X base 16, with upper-case letters for A-F
+ %U unicode format: U+1234; same as "U+%x" with 4 digits default
Floating-point and complex constituents:
%e scientific notation, e.g. -1234.456e+78
%E scientific notation, e.g. -1234.456E+78
{"% d", 0, " 0"},
{"% d", 12345, " 12345"},
+ // unicode format
+ {"%U", 0x1, "U+0001"},
+ {"%.8U", 0x2, "U+00000002"},
+ {"%U", 0x1234, "U+1234"},
+ {"%U", 0x12345, "U+12345"},
+ {"%10.6U", 0xABC, " U+000ABC"},
+ {"%-10.6U", 0xABC, "U+000ABC "},
+
// floats
{"%+.3e", 0.0, "+0.000e+00"},
{"%+.3e", 1.0, "+1.000e+00"},
plus bool
sharp bool
space bool
+ unicode bool
zero bool
}
f.plus = false
f.sharp = false
f.space = false
+ f.unicode = false
f.zero = false
}
buf[i] = '0'
}
}
+ if f.unicode {
+ i--
+ buf[i] = '+'
+ i--
+ buf[i] = 'U'
+ }
if negative {
i--
p.fmt.integer(v, 8, signed, ldigits)
case 'x':
p.fmt.integer(v, 16, signed, ldigits)
+ case 'U':
+ p.fmtUnicode(v)
case 'X':
p.fmt.integer(v, 16, signed, udigits)
default:
}
}
-// fmt_sharpHex64 formats a uint64 in hexadecimal and prefixes it with 0x by
+// fmt0x64 formats a uint64 in hexadecimal and prefixes it with 0x by
// temporarily turning on the sharp flag.
func (p *pp) fmt0x64(v uint64) {
sharp := p.fmt.sharp
p.fmt.sharp = sharp
}
+// fmtUnicode formats a uint64 in U+1234 form by
+// temporarily turning on the unicode flag and tweaking the precision.
+func (p *pp) fmtUnicode(v int64) {
+ precPresent := p.fmt.precPresent
+ prec := p.fmt.prec
+ if !precPresent {
+ // If prec is already set, leave it alone; otherwise 4 is minimum.
+ p.fmt.prec = 4
+ p.fmt.precPresent = true
+ }
+ p.fmt.unicode = true // turn on U+
+ p.fmt.integer(int64(v), 16, unsigned, udigits)
+ p.fmt.unicode = false
+ p.fmt.prec = prec
+ p.fmt.precPresent = precPresent
+}
+
func (p *pp) fmtUint64(v uint64, verb int, goSyntax bool, value interface{}) {
switch verb {
case 'b':
var complexError = os.ErrorString("syntax error scanning complex number")
var boolError = os.ErrorString("syntax error scanning boolean")
-// accepts checks the next rune in the input. If it's a byte (sic) in the string, it puts it in the
-// buffer and returns true. Otherwise it return false.
-func (s *ss) accept(ok string) bool {
+// consume reads the next rune in the input and reports whether it is in the ok string.
+// If accept is true, it puts the character into the input token.
+func (s *ss) consume(ok string, accept bool) bool {
if s.wid >= s.maxWid {
return false
}
}
for i := 0; i < len(ok); i++ {
if int(ok[i]) == rune {
- s.buf.WriteRune(rune)
- s.wid++
+ if accept {
+ s.buf.WriteRune(rune)
+ s.wid++
+ }
return true
}
}
- if rune != EOF {
+ if rune != EOF && accept {
s.UngetRune()
}
return false
}
+// accept checks the next rune in the input. If it's a byte (sic) in the string, it puts it in the
+// buffer and returns true. Otherwise it return false.
+func (s *ss) accept(ok string) bool {
+ return s.consume(ok, true)
+}
+
// okVerb verifies that the verb is present in the list, setting s.err appropriately if not.
func (s *ss) okVerb(verb int, okVerbs, typ string) bool {
for _, v := range okVerbs {
// getBase returns the numeric base represented by the verb and its digit string.
func (s *ss) getBase(verb int) (base int, digits string) {
- s.okVerb(verb, "bdoxXv", "integer") // sets s.err
+ s.okVerb(verb, "bdoUxXv", "integer") // sets s.err
base = 10
digits = decimalDigits
switch verb {
case 'o':
base = 8
digits = octalDigits
- case 'x', 'X':
+ case 'x', 'X', 'U':
base = 16
digits = hexadecimalDigits
}
}
base, digits := s.getBase(verb)
s.skipSpace(false)
- s.accept(sign) // If there's a sign, it will be left in the token buffer.
+ if verb == 'U' {
+ if !s.consume("U", false) || !s.consume("+", false) {
+ s.errorString("bad unicode format ")
+ }
+ } else {
+ s.accept(sign) // If there's a sign, it will be left in the token buffer.
+ }
tok := s.scanNumber(digits)
i, err := strconv.Btoi64(tok, base)
if err != nil {
}
base, digits := s.getBase(verb)
s.skipSpace(false)
+ if verb == 'U' {
+ if !s.consume("U", false) || !s.consume("+", false) {
+ s.errorString("bad unicode format ")
+ }
+ }
tok := s.scanNumber(digits)
i, err := strconv.Btoui64(tok, base)
if err != nil {
{"%o", "075\n", &uintVal, uint(075)},
{"%x", "a75\n", &uintVal, uint(0xa75)},
{"%x", "A75\n", &uintVal, uint(0xa75)},
+ {"%U", "U+1234\n", &intVal, int(0x1234)},
+ {"%U", "U+4567\n", &uintVal, uint(0x4567)},
// Strings
{"%s", "using-%s\n", &stringVal, "using-%s"},