github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/vendor_skip/golang.org/x/text/message/print.go (about) 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 }