taldir

Directory service to resolve wallet mailboxes by messenger addresses
Log | Files | Refs | Submodules | README | LICENSE

print.go (23802B)


      1 // Copyright 2017 The Go 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 
      5 package message
      6 
      7 import (
      8 	"bytes"
      9 	"fmt" // TODO: consider copying interfaces from package fmt to avoid dependency.
     10 	"math"
     11 	"reflect"
     12 	"sync"
     13 	"unicode/utf8"
     14 
     15 	"golang.org/x/text/internal/format"
     16 	"golang.org/x/text/internal/number"
     17 	"golang.org/x/text/language"
     18 	"golang.org/x/text/message/catalog"
     19 )
     20 
     21 // Strings for use with buffer.WriteString.
     22 // This is less overhead than using buffer.Write with byte arrays.
     23 const (
     24 	commaSpaceString  = ", "
     25 	nilAngleString    = "<nil>"
     26 	nilParenString    = "(nil)"
     27 	nilString         = "nil"
     28 	mapString         = "map["
     29 	percentBangString = "%!"
     30 	missingString     = "(MISSING)"
     31 	badIndexString    = "(BADINDEX)"
     32 	panicString       = "(PANIC="
     33 	extraString       = "%!(EXTRA "
     34 	badWidthString    = "%!(BADWIDTH)"
     35 	badPrecString     = "%!(BADPREC)"
     36 	noVerbString      = "%!(NOVERB)"
     37 
     38 	invReflectString = "<invalid reflect.Value>"
     39 )
     40 
     41 var printerPool = sync.Pool{
     42 	New: func() interface{} { return new(printer) },
     43 }
     44 
     45 // newPrinter allocates a new printer struct or grabs a cached one.
     46 func newPrinter(pp *Printer) *printer {
     47 	p := printerPool.Get().(*printer)
     48 	p.Printer = *pp
     49 	// TODO: cache most of the following call.
     50 	p.catContext = pp.cat.Context(pp.tag, p)
     51 
     52 	p.panicking = false
     53 	p.erroring = false
     54 	p.fmt.init(&p.Buffer)
     55 	return p
     56 }
     57 
     58 // free saves used printer structs in printerFree; avoids an allocation per invocation.
     59 func (p *printer) free() {
     60 	p.Buffer.Reset()
     61 	p.arg = nil
     62 	p.value = reflect.Value{}
     63 	printerPool.Put(p)
     64 }
     65 
     66 // printer is used to store a printer's state.
     67 // It implements "golang.org/x/text/internal/format".State.
     68 type printer struct {
     69 	Printer
     70 
     71 	// the context for looking up message translations
     72 	catContext *catalog.Context
     73 
     74 	// buffer for accumulating output.
     75 	bytes.Buffer
     76 
     77 	// arg holds the current item, as an interface{}.
     78 	arg interface{}
     79 	// value is used instead of arg for reflect values.
     80 	value reflect.Value
     81 
     82 	// fmt is used to format basic items such as integers or strings.
     83 	fmt formatInfo
     84 
     85 	// panicking is set by catchPanic to avoid infinite panic, recover, panic, ... recursion.
     86 	panicking bool
     87 	// erroring is set when printing an error string to guard against calling handleMethods.
     88 	erroring bool
     89 }
     90 
     91 // Language implements "golang.org/x/text/internal/format".State.
     92 func (p *printer) Language() language.Tag { return p.tag }
     93 
     94 func (p *printer) Width() (wid int, ok bool) { return p.fmt.Width, p.fmt.WidthPresent }
     95 
     96 func (p *printer) Precision() (prec int, ok bool) { return p.fmt.Prec, p.fmt.PrecPresent }
     97 
     98 func (p *printer) Flag(b int) bool {
     99 	switch b {
    100 	case '-':
    101 		return p.fmt.Minus
    102 	case '+':
    103 		return p.fmt.Plus || p.fmt.PlusV
    104 	case '#':
    105 		return p.fmt.Sharp || p.fmt.SharpV
    106 	case ' ':
    107 		return p.fmt.Space
    108 	case '0':
    109 		return p.fmt.Zero
    110 	}
    111 	return false
    112 }
    113 
    114 // getField gets the i'th field of the struct value.
    115 // If the field is itself is an interface, return a value for
    116 // the thing inside the interface, not the interface itself.
    117 func getField(v reflect.Value, i int) reflect.Value {
    118 	val := v.Field(i)
    119 	if val.Kind() == reflect.Interface && !val.IsNil() {
    120 		val = val.Elem()
    121 	}
    122 	return val
    123 }
    124 
    125 func (p *printer) unknownType(v reflect.Value) {
    126 	if !v.IsValid() {
    127 		p.WriteString(nilAngleString)
    128 		return
    129 	}
    130 	p.WriteByte('?')
    131 	p.WriteString(v.Type().String())
    132 	p.WriteByte('?')
    133 }
    134 
    135 func (p *printer) badVerb(verb rune) {
    136 	p.erroring = true
    137 	p.WriteString(percentBangString)
    138 	p.WriteRune(verb)
    139 	p.WriteByte('(')
    140 	switch {
    141 	case p.arg != nil:
    142 		p.WriteString(reflect.TypeOf(p.arg).String())
    143 		p.WriteByte('=')
    144 		p.printArg(p.arg, 'v')
    145 	case p.value.IsValid():
    146 		p.WriteString(p.value.Type().String())
    147 		p.WriteByte('=')
    148 		p.printValue(p.value, 'v', 0)
    149 	default:
    150 		p.WriteString(nilAngleString)
    151 	}
    152 	p.WriteByte(')')
    153 	p.erroring = false
    154 }
    155 
    156 func (p *printer) fmtBool(v bool, verb rune) {
    157 	switch verb {
    158 	case 't', 'v':
    159 		p.fmt.fmt_boolean(v)
    160 	default:
    161 		p.badVerb(verb)
    162 	}
    163 }
    164 
    165 // fmt0x64 formats a uint64 in hexadecimal and prefixes it with 0x or
    166 // not, as requested, by temporarily setting the sharp flag.
    167 func (p *printer) fmt0x64(v uint64, leading0x bool) {
    168 	sharp := p.fmt.Sharp
    169 	p.fmt.Sharp = leading0x
    170 	p.fmt.fmt_integer(v, 16, unsigned, ldigits)
    171 	p.fmt.Sharp = sharp
    172 }
    173 
    174 // fmtInteger formats a signed or unsigned integer.
    175 func (p *printer) fmtInteger(v uint64, isSigned bool, verb rune) {
    176 	switch verb {
    177 	case 'v':
    178 		if p.fmt.SharpV && !isSigned {
    179 			p.fmt0x64(v, true)
    180 			return
    181 		}
    182 		fallthrough
    183 	case 'd':
    184 		if p.fmt.Sharp || p.fmt.SharpV {
    185 			p.fmt.fmt_integer(v, 10, isSigned, ldigits)
    186 		} else {
    187 			p.fmtDecimalInt(v, isSigned)
    188 		}
    189 	case 'b':
    190 		p.fmt.fmt_integer(v, 2, isSigned, ldigits)
    191 	case 'o':
    192 		p.fmt.fmt_integer(v, 8, isSigned, ldigits)
    193 	case 'x':
    194 		p.fmt.fmt_integer(v, 16, isSigned, ldigits)
    195 	case 'X':
    196 		p.fmt.fmt_integer(v, 16, isSigned, udigits)
    197 	case 'c':
    198 		p.fmt.fmt_c(v)
    199 	case 'q':
    200 		if v <= utf8.MaxRune {
    201 			p.fmt.fmt_qc(v)
    202 		} else {
    203 			p.badVerb(verb)
    204 		}
    205 	case 'U':
    206 		p.fmt.fmt_unicode(v)
    207 	default:
    208 		p.badVerb(verb)
    209 	}
    210 }
    211 
    212 // fmtFloat formats a float. The default precision for each verb
    213 // is specified as last argument in the call to fmt_float.
    214 func (p *printer) fmtFloat(v float64, size int, verb rune) {
    215 	switch verb {
    216 	case 'b':
    217 		p.fmt.fmt_float(v, size, verb, -1)
    218 	case 'v':
    219 		verb = 'g'
    220 		fallthrough
    221 	case 'g', 'G':
    222 		if p.fmt.Sharp || p.fmt.SharpV {
    223 			p.fmt.fmt_float(v, size, verb, -1)
    224 		} else {
    225 			p.fmtVariableFloat(v, size)
    226 		}
    227 	case 'e', 'E':
    228 		if p.fmt.Sharp || p.fmt.SharpV {
    229 			p.fmt.fmt_float(v, size, verb, 6)
    230 		} else {
    231 			p.fmtScientific(v, size, 6)
    232 		}
    233 	case 'f', 'F':
    234 		if p.fmt.Sharp || p.fmt.SharpV {
    235 			p.fmt.fmt_float(v, size, verb, 6)
    236 		} else {
    237 			p.fmtDecimalFloat(v, size, 6)
    238 		}
    239 	default:
    240 		p.badVerb(verb)
    241 	}
    242 }
    243 
    244 func (p *printer) setFlags(f *number.Formatter) {
    245 	f.Flags &^= number.ElideSign
    246 	if p.fmt.Plus || p.fmt.Space {
    247 		f.Flags |= number.AlwaysSign
    248 		if !p.fmt.Plus {
    249 			f.Flags |= number.ElideSign
    250 		}
    251 	} else {
    252 		f.Flags &^= number.AlwaysSign
    253 	}
    254 }
    255 
    256 func (p *printer) updatePadding(f *number.Formatter) {
    257 	f.Flags &^= number.PadMask
    258 	if p.fmt.Minus {
    259 		f.Flags |= number.PadAfterSuffix
    260 	} else {
    261 		f.Flags |= number.PadBeforePrefix
    262 	}
    263 	f.PadRune = ' '
    264 	f.FormatWidth = uint16(p.fmt.Width)
    265 }
    266 
    267 func (p *printer) initDecimal(minFrac, maxFrac int) {
    268 	f := &p.toDecimal
    269 	f.MinIntegerDigits = 1
    270 	f.MaxIntegerDigits = 0
    271 	f.MinFractionDigits = uint8(minFrac)
    272 	f.MaxFractionDigits = int16(maxFrac)
    273 	p.setFlags(f)
    274 	f.PadRune = 0
    275 	if p.fmt.WidthPresent {
    276 		if p.fmt.Zero {
    277 			wid := p.fmt.Width
    278 			// Use significant integers for this.
    279 			// TODO: this is not the same as width, but so be it.
    280 			if f.MinFractionDigits > 0 {
    281 				wid -= 1 + int(f.MinFractionDigits)
    282 			}
    283 			if p.fmt.Plus || p.fmt.Space {
    284 				wid--
    285 			}
    286 			if wid > 0 && wid > int(f.MinIntegerDigits) {
    287 				f.MinIntegerDigits = uint8(wid)
    288 			}
    289 		}
    290 		p.updatePadding(f)
    291 	}
    292 }
    293 
    294 func (p *printer) initScientific(minFrac, maxFrac int) {
    295 	f := &p.toScientific
    296 	if maxFrac < 0 {
    297 		f.SetPrecision(maxFrac)
    298 	} else {
    299 		f.SetPrecision(maxFrac + 1)
    300 		f.MinFractionDigits = uint8(minFrac)
    301 		f.MaxFractionDigits = int16(maxFrac)
    302 	}
    303 	f.MinExponentDigits = 2
    304 	p.setFlags(f)
    305 	f.PadRune = 0
    306 	if p.fmt.WidthPresent {
    307 		f.Flags &^= number.PadMask
    308 		if p.fmt.Zero {
    309 			f.PadRune = f.Digit(0)
    310 			f.Flags |= number.PadAfterPrefix
    311 		} else {
    312 			f.PadRune = ' '
    313 			f.Flags |= number.PadBeforePrefix
    314 		}
    315 		p.updatePadding(f)
    316 	}
    317 }
    318 
    319 func (p *printer) fmtDecimalInt(v uint64, isSigned bool) {
    320 	var d number.Decimal
    321 
    322 	f := &p.toDecimal
    323 	if p.fmt.PrecPresent {
    324 		p.setFlags(f)
    325 		f.MinIntegerDigits = uint8(p.fmt.Prec)
    326 		f.MaxIntegerDigits = 0
    327 		f.MinFractionDigits = 0
    328 		f.MaxFractionDigits = 0
    329 		if p.fmt.WidthPresent {
    330 			p.updatePadding(f)
    331 		}
    332 	} else {
    333 		p.initDecimal(0, 0)
    334 	}
    335 	d.ConvertInt(p.toDecimal.RoundingContext, isSigned, v)
    336 
    337 	out := p.toDecimal.Format([]byte(nil), &d)
    338 	p.Buffer.Write(out)
    339 }
    340 
    341 func (p *printer) fmtDecimalFloat(v float64, size, prec int) {
    342 	var d number.Decimal
    343 	if p.fmt.PrecPresent {
    344 		prec = p.fmt.Prec
    345 	}
    346 	p.initDecimal(prec, prec)
    347 	d.ConvertFloat(p.toDecimal.RoundingContext, v, size)
    348 
    349 	out := p.toDecimal.Format([]byte(nil), &d)
    350 	p.Buffer.Write(out)
    351 }
    352 
    353 func (p *printer) fmtVariableFloat(v float64, size int) {
    354 	prec := -1
    355 	if p.fmt.PrecPresent {
    356 		prec = p.fmt.Prec
    357 	}
    358 	var d number.Decimal
    359 	p.initScientific(0, prec)
    360 	d.ConvertFloat(p.toScientific.RoundingContext, v, size)
    361 
    362 	// Copy logic of 'g' formatting from strconv. It is simplified a bit as
    363 	// we don't have to mind having prec > len(d.Digits).
    364 	shortest := prec < 0
    365 	ePrec := prec
    366 	if shortest {
    367 		prec = len(d.Digits)
    368 		ePrec = 6
    369 	} else if prec == 0 {
    370 		prec = 1
    371 		ePrec = 1
    372 	}
    373 	exp := int(d.Exp) - 1
    374 	if exp < -4 || exp >= ePrec {
    375 		p.initScientific(0, prec)
    376 
    377 		out := p.toScientific.Format([]byte(nil), &d)
    378 		p.Buffer.Write(out)
    379 	} else {
    380 		if prec > int(d.Exp) {
    381 			prec = len(d.Digits)
    382 		}
    383 		if prec -= int(d.Exp); prec < 0 {
    384 			prec = 0
    385 		}
    386 		p.initDecimal(0, prec)
    387 
    388 		out := p.toDecimal.Format([]byte(nil), &d)
    389 		p.Buffer.Write(out)
    390 	}
    391 }
    392 
    393 func (p *printer) fmtScientific(v float64, size, prec int) {
    394 	var d number.Decimal
    395 	if p.fmt.PrecPresent {
    396 		prec = p.fmt.Prec
    397 	}
    398 	p.initScientific(prec, prec)
    399 	rc := p.toScientific.RoundingContext
    400 	d.ConvertFloat(rc, v, size)
    401 
    402 	out := p.toScientific.Format([]byte(nil), &d)
    403 	p.Buffer.Write(out)
    404 
    405 }
    406 
    407 // fmtComplex formats a complex number v with
    408 // r = real(v) and j = imag(v) as (r+ji) using
    409 // fmtFloat for r and j formatting.
    410 func (p *printer) fmtComplex(v complex128, size int, verb rune) {
    411 	// Make sure any unsupported verbs are found before the
    412 	// calls to fmtFloat to not generate an incorrect error string.
    413 	switch verb {
    414 	case 'v', 'b', 'g', 'G', 'f', 'F', 'e', 'E':
    415 		p.WriteByte('(')
    416 		p.fmtFloat(real(v), size/2, verb)
    417 		// Imaginary part always has a sign.
    418 		if math.IsNaN(imag(v)) {
    419 			// By CLDR's rules, NaNs do not use patterns or signs. As this code
    420 			// relies on AlwaysSign working for imaginary parts, we need to
    421 			// manually handle NaNs.
    422 			f := &p.toScientific
    423 			p.setFlags(f)
    424 			p.updatePadding(f)
    425 			p.setFlags(f)
    426 			nan := f.Symbol(number.SymNan)
    427 			extra := 0
    428 			if w, ok := p.Width(); ok {
    429 				extra = w - utf8.RuneCountInString(nan) - 1
    430 			}
    431 			if f.Flags&number.PadAfterNumber == 0 {
    432 				for ; extra > 0; extra-- {
    433 					p.WriteRune(f.PadRune)
    434 				}
    435 			}
    436 			p.WriteString(f.Symbol(number.SymPlusSign))
    437 			p.WriteString(nan)
    438 			for ; extra > 0; extra-- {
    439 				p.WriteRune(f.PadRune)
    440 			}
    441 			p.WriteString("i)")
    442 			return
    443 		}
    444 		oldPlus := p.fmt.Plus
    445 		p.fmt.Plus = true
    446 		p.fmtFloat(imag(v), size/2, verb)
    447 		p.WriteString("i)") // TODO: use symbol?
    448 		p.fmt.Plus = oldPlus
    449 	default:
    450 		p.badVerb(verb)
    451 	}
    452 }
    453 
    454 func (p *printer) fmtString(v string, verb rune) {
    455 	switch verb {
    456 	case 'v':
    457 		if p.fmt.SharpV {
    458 			p.fmt.fmt_q(v)
    459 		} else {
    460 			p.fmt.fmt_s(v)
    461 		}
    462 	case 's':
    463 		p.fmt.fmt_s(v)
    464 	case 'x':
    465 		p.fmt.fmt_sx(v, ldigits)
    466 	case 'X':
    467 		p.fmt.fmt_sx(v, udigits)
    468 	case 'q':
    469 		p.fmt.fmt_q(v)
    470 	case 'm':
    471 		ctx := p.cat.Context(p.tag, rawPrinter{p})
    472 		if ctx.Execute(v) == catalog.ErrNotFound {
    473 			p.WriteString(v)
    474 		}
    475 	default:
    476 		p.badVerb(verb)
    477 	}
    478 }
    479 
    480 func (p *printer) fmtBytes(v []byte, verb rune, typeString string) {
    481 	switch verb {
    482 	case 'v', 'd':
    483 		if p.fmt.SharpV {
    484 			p.WriteString(typeString)
    485 			if v == nil {
    486 				p.WriteString(nilParenString)
    487 				return
    488 			}
    489 			p.WriteByte('{')
    490 			for i, c := range v {
    491 				if i > 0 {
    492 					p.WriteString(commaSpaceString)
    493 				}
    494 				p.fmt0x64(uint64(c), true)
    495 			}
    496 			p.WriteByte('}')
    497 		} else {
    498 			p.WriteByte('[')
    499 			for i, c := range v {
    500 				if i > 0 {
    501 					p.WriteByte(' ')
    502 				}
    503 				p.fmt.fmt_integer(uint64(c), 10, unsigned, ldigits)
    504 			}
    505 			p.WriteByte(']')
    506 		}
    507 	case 's':
    508 		p.fmt.fmt_s(string(v))
    509 	case 'x':
    510 		p.fmt.fmt_bx(v, ldigits)
    511 	case 'X':
    512 		p.fmt.fmt_bx(v, udigits)
    513 	case 'q':
    514 		p.fmt.fmt_q(string(v))
    515 	default:
    516 		p.printValue(reflect.ValueOf(v), verb, 0)
    517 	}
    518 }
    519 
    520 func (p *printer) fmtPointer(value reflect.Value, verb rune) {
    521 	var u uintptr
    522 	switch value.Kind() {
    523 	case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
    524 		u = value.Pointer()
    525 	default:
    526 		p.badVerb(verb)
    527 		return
    528 	}
    529 
    530 	switch verb {
    531 	case 'v':
    532 		if p.fmt.SharpV {
    533 			p.WriteByte('(')
    534 			p.WriteString(value.Type().String())
    535 			p.WriteString(")(")
    536 			if u == 0 {
    537 				p.WriteString(nilString)
    538 			} else {
    539 				p.fmt0x64(uint64(u), true)
    540 			}
    541 			p.WriteByte(')')
    542 		} else {
    543 			if u == 0 {
    544 				p.fmt.padString(nilAngleString)
    545 			} else {
    546 				p.fmt0x64(uint64(u), !p.fmt.Sharp)
    547 			}
    548 		}
    549 	case 'p':
    550 		p.fmt0x64(uint64(u), !p.fmt.Sharp)
    551 	case 'b', 'o', 'd', 'x', 'X':
    552 		if verb == 'd' {
    553 			p.fmt.Sharp = true // Print as standard go. TODO: does this make sense?
    554 		}
    555 		p.fmtInteger(uint64(u), unsigned, verb)
    556 	default:
    557 		p.badVerb(verb)
    558 	}
    559 }
    560 
    561 func (p *printer) catchPanic(arg interface{}, verb rune) {
    562 	if err := recover(); err != nil {
    563 		// If it's a nil pointer, just say "<nil>". The likeliest causes are a
    564 		// Stringer that fails to guard against nil or a nil pointer for a
    565 		// value receiver, and in either case, "<nil>" is a nice result.
    566 		if v := reflect.ValueOf(arg); v.Kind() == reflect.Ptr && v.IsNil() {
    567 			p.WriteString(nilAngleString)
    568 			return
    569 		}
    570 		// Otherwise print a concise panic message. Most of the time the panic
    571 		// value will print itself nicely.
    572 		if p.panicking {
    573 			// Nested panics; the recursion in printArg cannot succeed.
    574 			panic(err)
    575 		}
    576 
    577 		oldFlags := p.fmt.Parser
    578 		// For this output we want default behavior.
    579 		p.fmt.ClearFlags()
    580 
    581 		p.WriteString(percentBangString)
    582 		p.WriteRune(verb)
    583 		p.WriteString(panicString)
    584 		p.panicking = true
    585 		p.printArg(err, 'v')
    586 		p.panicking = false
    587 		p.WriteByte(')')
    588 
    589 		p.fmt.Parser = oldFlags
    590 	}
    591 }
    592 
    593 func (p *printer) handleMethods(verb rune) (handled bool) {
    594 	if p.erroring {
    595 		return
    596 	}
    597 	// Is it a Formatter?
    598 	if formatter, ok := p.arg.(format.Formatter); ok {
    599 		handled = true
    600 		defer p.catchPanic(p.arg, verb)
    601 		formatter.Format(p, verb)
    602 		return
    603 	}
    604 	if formatter, ok := p.arg.(fmt.Formatter); ok {
    605 		handled = true
    606 		defer p.catchPanic(p.arg, verb)
    607 		formatter.Format(p, verb)
    608 		return
    609 	}
    610 
    611 	// If we're doing Go syntax and the argument knows how to supply it, take care of it now.
    612 	if p.fmt.SharpV {
    613 		if stringer, ok := p.arg.(fmt.GoStringer); ok {
    614 			handled = true
    615 			defer p.catchPanic(p.arg, verb)
    616 			// Print the result of GoString unadorned.
    617 			p.fmt.fmt_s(stringer.GoString())
    618 			return
    619 		}
    620 	} else {
    621 		// If a string is acceptable according to the format, see if
    622 		// the value satisfies one of the string-valued interfaces.
    623 		// Println etc. set verb to %v, which is "stringable".
    624 		switch verb {
    625 		case 'v', 's', 'x', 'X', 'q':
    626 			// Is it an error or Stringer?
    627 			// The duplication in the bodies is necessary:
    628 			// setting handled and deferring catchPanic
    629 			// must happen before calling the method.
    630 			switch v := p.arg.(type) {
    631 			case error:
    632 				handled = true
    633 				defer p.catchPanic(p.arg, verb)
    634 				p.fmtString(v.Error(), verb)
    635 				return
    636 
    637 			case fmt.Stringer:
    638 				handled = true
    639 				defer p.catchPanic(p.arg, verb)
    640 				p.fmtString(v.String(), verb)
    641 				return
    642 			}
    643 		}
    644 	}
    645 	return false
    646 }
    647 
    648 func (p *printer) printArg(arg interface{}, verb rune) {
    649 	p.arg = arg
    650 	p.value = reflect.Value{}
    651 
    652 	if arg == nil {
    653 		switch verb {
    654 		case 'T', 'v':
    655 			p.fmt.padString(nilAngleString)
    656 		default:
    657 			p.badVerb(verb)
    658 		}
    659 		return
    660 	}
    661 
    662 	// Special processing considerations.
    663 	// %T (the value's type) and %p (its address) are special; we always do them first.
    664 	switch verb {
    665 	case 'T':
    666 		p.fmt.fmt_s(reflect.TypeOf(arg).String())
    667 		return
    668 	case 'p':
    669 		p.fmtPointer(reflect.ValueOf(arg), 'p')
    670 		return
    671 	}
    672 
    673 	// Some types can be done without reflection.
    674 	switch f := arg.(type) {
    675 	case bool:
    676 		p.fmtBool(f, verb)
    677 	case float32:
    678 		p.fmtFloat(float64(f), 32, verb)
    679 	case float64:
    680 		p.fmtFloat(f, 64, verb)
    681 	case complex64:
    682 		p.fmtComplex(complex128(f), 64, verb)
    683 	case complex128:
    684 		p.fmtComplex(f, 128, verb)
    685 	case int:
    686 		p.fmtInteger(uint64(f), signed, verb)
    687 	case int8:
    688 		p.fmtInteger(uint64(f), signed, verb)
    689 	case int16:
    690 		p.fmtInteger(uint64(f), signed, verb)
    691 	case int32:
    692 		p.fmtInteger(uint64(f), signed, verb)
    693 	case int64:
    694 		p.fmtInteger(uint64(f), signed, verb)
    695 	case uint:
    696 		p.fmtInteger(uint64(f), unsigned, verb)
    697 	case uint8:
    698 		p.fmtInteger(uint64(f), unsigned, verb)
    699 	case uint16:
    700 		p.fmtInteger(uint64(f), unsigned, verb)
    701 	case uint32:
    702 		p.fmtInteger(uint64(f), unsigned, verb)
    703 	case uint64:
    704 		p.fmtInteger(f, unsigned, verb)
    705 	case uintptr:
    706 		p.fmtInteger(uint64(f), unsigned, verb)
    707 	case string:
    708 		p.fmtString(f, verb)
    709 	case []byte:
    710 		p.fmtBytes(f, verb, "[]byte")
    711 	case reflect.Value:
    712 		// Handle extractable values with special methods
    713 		// since printValue does not handle them at depth 0.
    714 		if f.IsValid() && f.CanInterface() {
    715 			p.arg = f.Interface()
    716 			if p.handleMethods(verb) {
    717 				return
    718 			}
    719 		}
    720 		p.printValue(f, verb, 0)
    721 	default:
    722 		// If the type is not simple, it might have methods.
    723 		if !p.handleMethods(verb) {
    724 			// Need to use reflection, since the type had no
    725 			// interface methods that could be used for formatting.
    726 			p.printValue(reflect.ValueOf(f), verb, 0)
    727 		}
    728 	}
    729 }
    730 
    731 // printValue is similar to printArg but starts with a reflect value, not an interface{} value.
    732 // It does not handle 'p' and 'T' verbs because these should have been already handled by printArg.
    733 func (p *printer) printValue(value reflect.Value, verb rune, depth int) {
    734 	// Handle values with special methods if not already handled by printArg (depth == 0).
    735 	if depth > 0 && value.IsValid() && value.CanInterface() {
    736 		p.arg = value.Interface()
    737 		if p.handleMethods(verb) {
    738 			return
    739 		}
    740 	}
    741 	p.arg = nil
    742 	p.value = value
    743 
    744 	switch f := value; value.Kind() {
    745 	case reflect.Invalid:
    746 		if depth == 0 {
    747 			p.WriteString(invReflectString)
    748 		} else {
    749 			switch verb {
    750 			case 'v':
    751 				p.WriteString(nilAngleString)
    752 			default:
    753 				p.badVerb(verb)
    754 			}
    755 		}
    756 	case reflect.Bool:
    757 		p.fmtBool(f.Bool(), verb)
    758 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
    759 		p.fmtInteger(uint64(f.Int()), signed, verb)
    760 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
    761 		p.fmtInteger(f.Uint(), unsigned, verb)
    762 	case reflect.Float32:
    763 		p.fmtFloat(f.Float(), 32, verb)
    764 	case reflect.Float64:
    765 		p.fmtFloat(f.Float(), 64, verb)
    766 	case reflect.Complex64:
    767 		p.fmtComplex(f.Complex(), 64, verb)
    768 	case reflect.Complex128:
    769 		p.fmtComplex(f.Complex(), 128, verb)
    770 	case reflect.String:
    771 		p.fmtString(f.String(), verb)
    772 	case reflect.Map:
    773 		if p.fmt.SharpV {
    774 			p.WriteString(f.Type().String())
    775 			if f.IsNil() {
    776 				p.WriteString(nilParenString)
    777 				return
    778 			}
    779 			p.WriteByte('{')
    780 		} else {
    781 			p.WriteString(mapString)
    782 		}
    783 		keys := f.MapKeys()
    784 		for i, key := range keys {
    785 			if i > 0 {
    786 				if p.fmt.SharpV {
    787 					p.WriteString(commaSpaceString)
    788 				} else {
    789 					p.WriteByte(' ')
    790 				}
    791 			}
    792 			p.printValue(key, verb, depth+1)
    793 			p.WriteByte(':')
    794 			p.printValue(f.MapIndex(key), verb, depth+1)
    795 		}
    796 		if p.fmt.SharpV {
    797 			p.WriteByte('}')
    798 		} else {
    799 			p.WriteByte(']')
    800 		}
    801 	case reflect.Struct:
    802 		if p.fmt.SharpV {
    803 			p.WriteString(f.Type().String())
    804 		}
    805 		p.WriteByte('{')
    806 		for i := 0; i < f.NumField(); i++ {
    807 			if i > 0 {
    808 				if p.fmt.SharpV {
    809 					p.WriteString(commaSpaceString)
    810 				} else {
    811 					p.WriteByte(' ')
    812 				}
    813 			}
    814 			if p.fmt.PlusV || p.fmt.SharpV {
    815 				if name := f.Type().Field(i).Name; name != "" {
    816 					p.WriteString(name)
    817 					p.WriteByte(':')
    818 				}
    819 			}
    820 			p.printValue(getField(f, i), verb, depth+1)
    821 		}
    822 		p.WriteByte('}')
    823 	case reflect.Interface:
    824 		value := f.Elem()
    825 		if !value.IsValid() {
    826 			if p.fmt.SharpV {
    827 				p.WriteString(f.Type().String())
    828 				p.WriteString(nilParenString)
    829 			} else {
    830 				p.WriteString(nilAngleString)
    831 			}
    832 		} else {
    833 			p.printValue(value, verb, depth+1)
    834 		}
    835 	case reflect.Array, reflect.Slice:
    836 		switch verb {
    837 		case 's', 'q', 'x', 'X':
    838 			// Handle byte and uint8 slices and arrays special for the above verbs.
    839 			t := f.Type()
    840 			if t.Elem().Kind() == reflect.Uint8 {
    841 				var bytes []byte
    842 				if f.Kind() == reflect.Slice {
    843 					bytes = f.Bytes()
    844 				} else if f.CanAddr() {
    845 					bytes = f.Slice(0, f.Len()).Bytes()
    846 				} else {
    847 					// We have an array, but we cannot Slice() a non-addressable array,
    848 					// so we build a slice by hand. This is a rare case but it would be nice
    849 					// if reflection could help a little more.
    850 					bytes = make([]byte, f.Len())
    851 					for i := range bytes {
    852 						bytes[i] = byte(f.Index(i).Uint())
    853 					}
    854 				}
    855 				p.fmtBytes(bytes, verb, t.String())
    856 				return
    857 			}
    858 		}
    859 		if p.fmt.SharpV {
    860 			p.WriteString(f.Type().String())
    861 			if f.Kind() == reflect.Slice && f.IsNil() {
    862 				p.WriteString(nilParenString)
    863 				return
    864 			}
    865 			p.WriteByte('{')
    866 			for i := 0; i < f.Len(); i++ {
    867 				if i > 0 {
    868 					p.WriteString(commaSpaceString)
    869 				}
    870 				p.printValue(f.Index(i), verb, depth+1)
    871 			}
    872 			p.WriteByte('}')
    873 		} else {
    874 			p.WriteByte('[')
    875 			for i := 0; i < f.Len(); i++ {
    876 				if i > 0 {
    877 					p.WriteByte(' ')
    878 				}
    879 				p.printValue(f.Index(i), verb, depth+1)
    880 			}
    881 			p.WriteByte(']')
    882 		}
    883 	case reflect.Ptr:
    884 		// pointer to array or slice or struct?  ok at top level
    885 		// but not embedded (avoid loops)
    886 		if depth == 0 && f.Pointer() != 0 {
    887 			switch a := f.Elem(); a.Kind() {
    888 			case reflect.Array, reflect.Slice, reflect.Struct, reflect.Map:
    889 				p.WriteByte('&')
    890 				p.printValue(a, verb, depth+1)
    891 				return
    892 			}
    893 		}
    894 		fallthrough
    895 	case reflect.Chan, reflect.Func, reflect.UnsafePointer:
    896 		p.fmtPointer(f, verb)
    897 	default:
    898 		p.unknownType(f)
    899 	}
    900 }
    901 
    902 func (p *printer) badArgNum(verb rune) {
    903 	p.WriteString(percentBangString)
    904 	p.WriteRune(verb)
    905 	p.WriteString(badIndexString)
    906 }
    907 
    908 func (p *printer) missingArg(verb rune) {
    909 	p.WriteString(percentBangString)
    910 	p.WriteRune(verb)
    911 	p.WriteString(missingString)
    912 }
    913 
    914 func (p *printer) doPrintf(fmt string) {
    915 	for p.fmt.Parser.SetFormat(fmt); p.fmt.Scan(); {
    916 		switch p.fmt.Status {
    917 		case format.StatusText:
    918 			p.WriteString(p.fmt.Text())
    919 		case format.StatusSubstitution:
    920 			p.printArg(p.Arg(p.fmt.ArgNum), p.fmt.Verb)
    921 		case format.StatusBadWidthSubstitution:
    922 			p.WriteString(badWidthString)
    923 			p.printArg(p.Arg(p.fmt.ArgNum), p.fmt.Verb)
    924 		case format.StatusBadPrecSubstitution:
    925 			p.WriteString(badPrecString)
    926 			p.printArg(p.Arg(p.fmt.ArgNum), p.fmt.Verb)
    927 		case format.StatusNoVerb:
    928 			p.WriteString(noVerbString)
    929 		case format.StatusBadArgNum:
    930 			p.badArgNum(p.fmt.Verb)
    931 		case format.StatusMissingArg:
    932 			p.missingArg(p.fmt.Verb)
    933 		default:
    934 			panic("unreachable")
    935 		}
    936 	}
    937 
    938 	// Check for extra arguments, but only if there was at least one ordered
    939 	// argument. Note that this behavior is necessarily different from fmt:
    940 	// different variants of messages may opt to drop some or all of the
    941 	// arguments.
    942 	if !p.fmt.Reordered && p.fmt.ArgNum < len(p.fmt.Args) && p.fmt.ArgNum != 0 {
    943 		p.fmt.ClearFlags()
    944 		p.WriteString(extraString)
    945 		for i, arg := range p.fmt.Args[p.fmt.ArgNum:] {
    946 			if i > 0 {
    947 				p.WriteString(commaSpaceString)
    948 			}
    949 			if arg == nil {
    950 				p.WriteString(nilAngleString)
    951 			} else {
    952 				p.WriteString(reflect.TypeOf(arg).String())
    953 				p.WriteString("=")
    954 				p.printArg(arg, 'v')
    955 			}
    956 		}
    957 		p.WriteByte(')')
    958 	}
    959 }
    960 
    961 func (p *printer) doPrint(a []interface{}) {
    962 	prevString := false
    963 	for argNum, arg := range a {
    964 		isString := arg != nil && reflect.TypeOf(arg).Kind() == reflect.String
    965 		// Add a space between two non-string arguments.
    966 		if argNum > 0 && !isString && !prevString {
    967 			p.WriteByte(' ')
    968 		}
    969 		p.printArg(arg, 'v')
    970 		prevString = isString
    971 	}
    972 }
    973 
    974 // doPrintln is like doPrint but always adds a space between arguments
    975 // and a newline after the last argument.
    976 func (p *printer) doPrintln(a []interface{}) {
    977 	for argNum, arg := range a {
    978 		if argNum > 0 {
    979 			p.WriteByte(' ')
    980 		}
    981 		p.printArg(arg, 'v')
    982 	}
    983 	p.WriteByte('\n')
    984 }