github.com/go-eden/common@v0.1.15-0.20210617133546-059099253264/efmt/efmt_printer.go (about) 1 package efmt 2 3 import ( 4 "fmt" 5 "reflect" 6 "unicode/utf8" 7 ) 8 9 // pp is used to store a printer's state and is reused with sync.Pool to avoid allocations. 10 type pp struct { 11 buf buffer 12 13 // arg holds the current item, as an interface{}. 14 arg interface{} 15 16 // value is used instead of arg for reflect values. 17 value reflect.Value 18 19 // fmt is used to format basic items such as integers or strings. 20 fmt formatter 21 22 // reordered records whether the format string used argument reordering. 23 reordered bool 24 // goodArgNum records whether the most recent reordering directive was valid. 25 goodArgNum bool 26 // panicking is set by catchPanic to avoid infinite panic, recover, panic, ... recursion. 27 panicking bool 28 // erroring is set when printing an error string to guard against calling handleMethods. 29 erroring bool 30 // wrapErrs is set when the format string may contain a %w verb. 31 wrapErrs bool 32 // wrappedErr records the target of the %w verb. 33 wrappedErr error 34 } 35 36 // free saves used pp structs in ppFree; avoids an allocation per invocation. 37 func (p *pp) free() { 38 p.buf = p.buf[:0] 39 p.arg = nil 40 p.value = reflect.Value{} 41 p.wrappedErr = nil 42 } 43 44 func (p *pp) Width() (wid int, ok bool) { return p.fmt.wid, p.fmt.widPresent } 45 46 func (p *pp) Precision() (prec int, ok bool) { return p.fmt.prec, p.fmt.precPresent } 47 48 func (p *pp) Flag(b int) bool { 49 switch b { 50 case '-': 51 return p.fmt.minus 52 case '+': 53 return p.fmt.plus || p.fmt.plusV 54 case '#': 55 return p.fmt.sharp || p.fmt.sharpV 56 case ' ': 57 return p.fmt.space 58 case '0': 59 return p.fmt.zero 60 } 61 return false 62 } 63 64 // Implement Write so we can call Fprintf on a pp (through State), for 65 // recursive use in custom verbs. 66 func (p *pp) Write(b []byte) (ret int, err error) { 67 p.buf.write(b) 68 return len(b), nil 69 } 70 71 // getField gets the i'th field of the struct value. 72 // If the field is itself is an interface, return a value for 73 // the thing inside the interface, not the interface itself. 74 func getField(v reflect.Value, i int) reflect.Value { 75 val := v.Field(i) 76 if val.Kind() == reflect.Interface && !val.IsNil() { 77 val = val.Elem() 78 } 79 return val 80 } 81 82 // tooLarge reports whether the magnitude of the integer is 83 // too large to be used as a formatting width or precision. 84 func tooLarge(x int) bool { 85 const max int = 1e6 86 return x > max || x < -max 87 } 88 89 // parsenum converts ASCII to integer. num is 0 (and isnum is false) if no number present. 90 func parsenum(s string, start, end int) (num int, isnum bool, newi int) { 91 if start >= end { 92 return 0, false, end 93 } 94 for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++ { 95 if tooLarge(num) { 96 return 0, false, end // Overflow; crazy long number most likely. 97 } 98 num = num*10 + int(s[newi]-'0') 99 isnum = true 100 } 101 return 102 } 103 104 func (p *pp) unknownType(v reflect.Value) { 105 if !v.IsValid() { 106 p.buf.writeString(nilAngleString) 107 return 108 } 109 p.buf.writeByte('?') 110 p.buf.writeString(v.Type().String()) 111 p.buf.writeByte('?') 112 } 113 114 func (p *pp) badVerb(verb rune) { 115 p.erroring = true 116 p.buf.writeString(percentBangString) 117 p.buf.writeRune(verb) 118 p.buf.writeByte('(') 119 switch { 120 case p.arg != nil: 121 p.buf.writeString(reflect.TypeOf(p.arg).String()) 122 p.buf.writeByte('=') 123 p.printArg(p.arg, 'v') 124 case p.value.IsValid(): 125 p.buf.writeString(p.value.Type().String()) 126 p.buf.writeByte('=') 127 p.printValue(p.value, 'v', 0) 128 default: 129 p.buf.writeString(nilAngleString) 130 } 131 p.buf.writeByte(')') 132 p.erroring = false 133 } 134 135 func (p *pp) fmtBool(v bool, verb rune) { 136 switch verb { 137 case 't', 'v': 138 p.fmt.fmtBoolean(v) 139 default: 140 p.badVerb(verb) 141 } 142 } 143 144 // fmt0x64 formats a uint64 in hexadecimal and prefixes it with 0x or 145 // not, as requested, by temporarily setting the sharp flag. 146 func (p *pp) fmt0x64(v uint64, leading0x bool) { 147 sharp := p.fmt.sharp 148 p.fmt.sharp = leading0x 149 p.fmt.fmtInteger(v, 16, unsigned, 'v', ldigits) 150 p.fmt.sharp = sharp 151 } 152 153 // fmtInteger formats a signed or unsigned integer. 154 func (p *pp) fmtInteger(v uint64, isSigned bool, verb rune) { 155 switch verb { 156 case 'v': 157 if p.fmt.sharpV && !isSigned { 158 p.fmt0x64(v, true) 159 } else { 160 p.fmt.fmtInteger(v, 10, isSigned, verb, ldigits) 161 } 162 case 'd': 163 p.fmt.fmtInteger(v, 10, isSigned, verb, ldigits) 164 case 'b': 165 p.fmt.fmtInteger(v, 2, isSigned, verb, ldigits) 166 case 'o', 'O': 167 p.fmt.fmtInteger(v, 8, isSigned, verb, ldigits) 168 case 'x': 169 p.fmt.fmtInteger(v, 16, isSigned, verb, ldigits) 170 case 'X': 171 p.fmt.fmtInteger(v, 16, isSigned, verb, udigits) 172 case 'c': 173 p.fmt.fmtC(v) 174 case 'q': 175 p.fmt.fmtQc(v) 176 case 'U': 177 p.fmt.fmtUnicode(v) 178 default: 179 p.badVerb(verb) 180 } 181 } 182 183 // fmtFloat formats a float. The default precision for each verb 184 // is specified as last argument in the call to fmt_float. 185 func (p *pp) fmtFloat(v float64, size int, verb rune) { 186 switch verb { 187 case 'v': 188 p.fmt.fmtFloat(v, size, 'g', -1) 189 case 'b', 'g', 'G', 'x', 'X': 190 p.fmt.fmtFloat(v, size, verb, -1) 191 case 'f', 'e', 'E': 192 p.fmt.fmtFloat(v, size, verb, 6) 193 case 'F': 194 p.fmt.fmtFloat(v, size, 'f', 6) 195 default: 196 p.badVerb(verb) 197 } 198 } 199 200 // fmtComplex formats a complex number v with 201 // r = real(v) and j = imag(v) as (r+ji) using 202 // fmtFloat for r and j formatting. 203 func (p *pp) fmtComplex(v complex128, size int, verb rune) { 204 // Make sure any unsupported verbs are found before the 205 // calls to fmtFloat to not generate an incorrect error string. 206 switch verb { 207 case 'v', 'b', 'g', 'G', 'x', 'X', 'f', 'F', 'e', 'E': 208 oldPlus := p.fmt.plus 209 p.buf.writeByte('(') 210 p.fmtFloat(real(v), size/2, verb) 211 // Imaginary part always has a sign. 212 p.fmt.plus = true 213 p.fmtFloat(imag(v), size/2, verb) 214 p.buf.writeString("i)") 215 p.fmt.plus = oldPlus 216 default: 217 p.badVerb(verb) 218 } 219 } 220 221 func (p *pp) fmtString(v string, verb rune) { 222 switch verb { 223 case 'v': 224 if p.fmt.sharpV { 225 p.fmt.fmtQ(v) 226 } else { 227 p.fmt.fmtS(v) 228 } 229 case 's': 230 p.fmt.fmtS(v) 231 case 'x': 232 p.fmt.fmtSx(v, ldigits) 233 case 'X': 234 p.fmt.fmtSx(v, udigits) 235 case 'q': 236 p.fmt.fmtQ(v) 237 default: 238 p.badVerb(verb) 239 } 240 } 241 242 func (p *pp) fmtBytes(v []byte, verb rune, typeString string) { 243 switch verb { 244 case 'v', 'd': 245 if p.fmt.sharpV { 246 p.buf.writeString(typeString) 247 if v == nil { 248 p.buf.writeString(nilParenString) 249 return 250 } 251 p.buf.writeByte('{') 252 for i, c := range v { 253 if i > 0 { 254 p.buf.writeString(commaSpaceString) 255 } 256 p.fmt0x64(uint64(c), true) 257 } 258 p.buf.writeByte('}') 259 } else { 260 p.buf.writeByte('[') 261 for i, c := range v { 262 if i > 0 { 263 p.buf.writeByte(' ') 264 } 265 p.fmt.fmtInteger(uint64(c), 10, unsigned, verb, ldigits) 266 } 267 p.buf.writeByte(']') 268 } 269 case 's': 270 p.fmt.fmtBs(v) 271 case 'x': 272 p.fmt.fmtBx(v, ldigits) 273 case 'X': 274 p.fmt.fmtBx(v, udigits) 275 case 'q': 276 p.fmt.fmtQ(string(v)) 277 default: 278 p.printValue(reflect.ValueOf(v), verb, 0) 279 } 280 } 281 282 func (p *pp) fmtPointer(value reflect.Value, verb rune) { 283 var u uintptr 284 switch value.Kind() { 285 case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer: 286 u = value.Pointer() 287 default: 288 p.badVerb(verb) 289 return 290 } 291 292 switch verb { 293 case 'v': 294 if p.fmt.sharpV { 295 p.buf.writeByte('(') 296 p.buf.writeString(value.Type().String()) 297 p.buf.writeString(")(") 298 if u == 0 { 299 p.buf.writeString(nilString) 300 } else { 301 p.fmt0x64(uint64(u), true) 302 } 303 p.buf.writeByte(')') 304 } else { 305 if u == 0 { 306 p.fmt.padString(nilAngleString) 307 } else { 308 p.fmt0x64(uint64(u), !p.fmt.sharp) 309 } 310 } 311 case 'p': 312 p.fmt0x64(uint64(u), !p.fmt.sharp) 313 case 'b', 'o', 'd', 'x', 'X': 314 p.fmtInteger(uint64(u), unsigned, verb) 315 default: 316 p.badVerb(verb) 317 } 318 } 319 320 func (p *pp) catchPanic(arg interface{}, verb rune, method string) { 321 if err := recover(); err != nil { 322 // If it's a nil pointer, just say "<nil>". The likeliest causes are a 323 // Stringer that fails to guard against nil or a nil pointer for a 324 // value receiver, and in either case, "<nil>" is a nice result. 325 if v := reflect.ValueOf(arg); v.Kind() == reflect.Ptr && v.IsNil() { 326 p.buf.writeString(nilAngleString) 327 return 328 } 329 // Otherwise print a concise panic message. Most of the time the panic 330 // value will print itself nicely. 331 if p.panicking { 332 // Nested panics; the recursion in printArg cannot succeed. 333 panic(err) 334 } 335 336 oldFlags := p.fmt.formatFlags 337 // For this output we want default behavior. 338 p.fmt.clearflags() 339 340 p.buf.writeString(percentBangString) 341 p.buf.writeRune(verb) 342 p.buf.writeString(panicString) 343 p.buf.writeString(method) 344 p.buf.writeString(" method: ") 345 p.panicking = true 346 p.printArg(err, 'v') 347 p.panicking = false 348 p.buf.writeByte(')') 349 350 p.fmt.formatFlags = oldFlags 351 } 352 } 353 354 func (p *pp) handleMethods(verb rune) (handled bool) { 355 if p.erroring { 356 return 357 } 358 if verb == 'w' { 359 // It is invalid to use %w other than with Errorf, more than once, 360 // or with a non-error arg. 361 err, ok := p.arg.(error) 362 if !ok || !p.wrapErrs || p.wrappedErr != nil { 363 p.wrappedErr = nil 364 p.wrapErrs = false 365 p.badVerb(verb) 366 return true 367 } 368 p.wrappedErr = err 369 // If the arg is a Formatter, pass 'v' as the verb to it. 370 verb = 'v' 371 } 372 373 // Is it a Formatter? 374 if formatter, ok := p.arg.(fmt.Formatter); ok { 375 handled = true 376 defer p.catchPanic(p.arg, verb, "Format") 377 formatter.Format(p, verb) 378 return 379 } 380 381 // If we're doing Go syntax and the argument knows how to supply it, take care of it now. 382 if p.fmt.sharpV { 383 if stringer, ok := p.arg.(fmt.GoStringer); ok { 384 handled = true 385 defer p.catchPanic(p.arg, verb, "GoString") 386 // Print the result of GoString unadorned. 387 p.fmt.fmtS(stringer.GoString()) 388 return 389 } 390 } else { 391 // If a string is acceptable according to the format, see if 392 // the value satisfies one of the string-valued interfaces. 393 // Println etc. set verb to %v, which is "stringable". 394 switch verb { 395 case 'v', 's', 'x', 'X', 'q': 396 // Is it an error or Stringer? 397 // The duplication in the bodies is necessary: 398 // setting handled and deferring catchPanic 399 // must happen before calling the method. 400 switch v := p.arg.(type) { 401 case error: 402 handled = true 403 defer p.catchPanic(p.arg, verb, "Error") 404 p.fmtString(v.Error(), verb) 405 return 406 407 case fmt.Stringer: 408 handled = true 409 defer p.catchPanic(p.arg, verb, "String") 410 p.fmtString(v.String(), verb) 411 return 412 } 413 } 414 } 415 return false 416 } 417 418 func (p *pp) printArg(arg interface{}, verb rune) { 419 p.arg = arg 420 p.value = reflect.Value{} 421 422 if arg == nil { 423 switch verb { 424 case 'T', 'v': 425 p.fmt.padString(nilAngleString) 426 default: 427 p.badVerb(verb) 428 } 429 return 430 } 431 432 // Special processing considerations. 433 // %T (the value's type) and %p (its address) are special; we always do them first. 434 switch verb { 435 case 'T': 436 p.fmt.fmtS(reflect.TypeOf(arg).String()) 437 return 438 case 'p': 439 p.fmtPointer(reflect.ValueOf(arg), 'p') 440 return 441 } 442 443 // Some types can be done without reflection. 444 switch f := arg.(type) { 445 case bool: 446 p.fmtBool(f, verb) 447 case float32: 448 p.fmtFloat(float64(f), 32, verb) 449 case float64: 450 p.fmtFloat(f, 64, verb) 451 case complex64: 452 p.fmtComplex(complex128(f), 64, verb) 453 case complex128: 454 p.fmtComplex(f, 128, verb) 455 case int: 456 p.fmtInteger(uint64(f), signed, verb) 457 case int8: 458 p.fmtInteger(uint64(f), signed, verb) 459 case int16: 460 p.fmtInteger(uint64(f), signed, verb) 461 case int32: 462 p.fmtInteger(uint64(f), signed, verb) 463 case int64: 464 p.fmtInteger(uint64(f), signed, verb) 465 case uint: 466 p.fmtInteger(uint64(f), unsigned, verb) 467 case uint8: 468 p.fmtInteger(uint64(f), unsigned, verb) 469 case uint16: 470 p.fmtInteger(uint64(f), unsigned, verb) 471 case uint32: 472 p.fmtInteger(uint64(f), unsigned, verb) 473 case uint64: 474 p.fmtInteger(f, unsigned, verb) 475 case uintptr: 476 p.fmtInteger(uint64(f), unsigned, verb) 477 case string: 478 p.fmtString(f, verb) 479 case []byte: 480 p.fmtBytes(f, verb, "[]byte") 481 case reflect.Value: 482 // Handle extractable values with special methods 483 // since printValue does not handle them at depth 0. 484 if f.IsValid() && f.CanInterface() { 485 p.arg = f.Interface() 486 if p.handleMethods(verb) { 487 return 488 } 489 } 490 p.printValue(f, verb, 0) 491 default: 492 // If the type is not simple, it might have methods. 493 if !p.handleMethods(verb) { 494 // Need to use reflection, since the type had no 495 // interface methods that could be used for formatting. 496 p.printValue(reflect.ValueOf(f), verb, 0) 497 } 498 } 499 } 500 501 // printValue is similar to printArg but starts with a reflect value, not an interface{} value. 502 // It does not handle 'p' and 'T' verbs because these should have been already handled by printArg. 503 func (p *pp) printValue(value reflect.Value, verb rune, depth int) { 504 // Handle values with special methods if not already handled by printArg (depth == 0). 505 if depth > 0 && value.IsValid() && value.CanInterface() { 506 p.arg = value.Interface() 507 if p.handleMethods(verb) { 508 return 509 } 510 } 511 p.arg = nil 512 p.value = value 513 514 switch f := value; value.Kind() { 515 case reflect.Invalid: 516 if depth == 0 { 517 p.buf.writeString(invReflectString) 518 } else { 519 switch verb { 520 case 'v': 521 p.buf.writeString(nilAngleString) 522 default: 523 p.badVerb(verb) 524 } 525 } 526 case reflect.Bool: 527 p.fmtBool(f.Bool(), verb) 528 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 529 p.fmtInteger(uint64(f.Int()), signed, verb) 530 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 531 p.fmtInteger(f.Uint(), unsigned, verb) 532 case reflect.Float32: 533 p.fmtFloat(f.Float(), 32, verb) 534 case reflect.Float64: 535 p.fmtFloat(f.Float(), 64, verb) 536 case reflect.Complex64: 537 p.fmtComplex(f.Complex(), 64, verb) 538 case reflect.Complex128: 539 p.fmtComplex(f.Complex(), 128, verb) 540 case reflect.String: 541 p.fmtString(f.String(), verb) 542 case reflect.Map: 543 if p.fmt.sharpV { 544 p.buf.writeString(f.Type().String()) 545 if f.IsNil() { 546 p.buf.writeString(nilParenString) 547 return 548 } 549 p.buf.writeByte('{') 550 } else { 551 p.buf.writeString(mapString) 552 } 553 iter := f.MapRange() 554 for i := 0; iter.Next(); i++ { 555 if i > 0 { 556 if p.fmt.sharpV { 557 p.buf.writeString(commaSpaceString) 558 } else { 559 p.buf.writeByte(' ') 560 } 561 } 562 p.printValue(iter.Key(), verb, depth+1) 563 p.buf.writeByte(':') 564 p.printValue(iter.Value(), verb, depth+1) 565 } 566 if p.fmt.sharpV { 567 p.buf.writeByte('}') 568 } else { 569 p.buf.writeByte(']') 570 } 571 case reflect.Struct: 572 if p.fmt.sharpV { 573 p.buf.writeString(f.Type().String()) 574 } 575 p.buf.writeByte('{') 576 for i := 0; i < f.NumField(); i++ { 577 if i > 0 { 578 if p.fmt.sharpV { 579 p.buf.writeString(commaSpaceString) 580 } else { 581 p.buf.writeByte(' ') 582 } 583 } 584 if p.fmt.plusV || p.fmt.sharpV { 585 if name := f.Type().Field(i).Name; name != "" { 586 p.buf.writeString(name) 587 p.buf.writeByte(':') 588 } 589 } 590 p.printValue(getField(f, i), verb, depth+1) 591 } 592 p.buf.writeByte('}') 593 case reflect.Interface: 594 value := f.Elem() 595 if !value.IsValid() { 596 if p.fmt.sharpV { 597 p.buf.writeString(f.Type().String()) 598 p.buf.writeString(nilParenString) 599 } else { 600 p.buf.writeString(nilAngleString) 601 } 602 } else { 603 p.printValue(value, verb, depth+1) 604 } 605 case reflect.Array, reflect.Slice: 606 switch verb { 607 case 's', 'q', 'x', 'X': 608 // Handle byte and uint8 slices and arrays special for the above verbs. 609 t := f.Type() 610 if t.Elem().Kind() == reflect.Uint8 { 611 var bytes []byte 612 if f.Kind() == reflect.Slice { 613 bytes = f.Bytes() 614 } else if f.CanAddr() { 615 bytes = f.Slice(0, f.Len()).Bytes() 616 } else { 617 // We have an array, but we cannot Slice() a non-addressable array, 618 // so we build a slice by hand. This is a rare case but it would be nice 619 // if reflection could help a little more. 620 bytes = make([]byte, f.Len()) 621 for i := range bytes { 622 bytes[i] = byte(f.Index(i).Uint()) 623 } 624 } 625 p.fmtBytes(bytes, verb, t.String()) 626 return 627 } 628 } 629 if p.fmt.sharpV { 630 p.buf.writeString(f.Type().String()) 631 if f.Kind() == reflect.Slice && f.IsNil() { 632 p.buf.writeString(nilParenString) 633 return 634 } 635 p.buf.writeByte('{') 636 for i := 0; i < f.Len(); i++ { 637 if i > 0 { 638 p.buf.writeString(commaSpaceString) 639 } 640 p.printValue(f.Index(i), verb, depth+1) 641 } 642 p.buf.writeByte('}') 643 } else { 644 p.buf.writeByte('[') 645 for i := 0; i < f.Len(); i++ { 646 if i > 0 { 647 p.buf.writeByte(' ') 648 } 649 p.printValue(f.Index(i), verb, depth+1) 650 } 651 p.buf.writeByte(']') 652 } 653 case reflect.Ptr: 654 // pointer to array or slice or struct? ok at top level 655 // but not embedded (avoid loops) 656 if depth == 0 && f.Pointer() != 0 { 657 switch a := f.Elem(); a.Kind() { 658 case reflect.Array, reflect.Slice, reflect.Struct, reflect.Map: 659 p.buf.writeByte('&') 660 p.printValue(a, verb, depth+1) 661 return 662 } 663 } 664 fallthrough 665 case reflect.Chan, reflect.Func, reflect.UnsafePointer: 666 p.fmtPointer(f, verb) 667 default: 668 p.unknownType(f) 669 } 670 } 671 672 // intFromArg gets the argNumth element of a. On return, isInt reports whether the argument has integer type. 673 func intFromArg(a []interface{}, argNum int) (num int, isInt bool, newArgNum int) { 674 newArgNum = argNum 675 if argNum < len(a) { 676 num, isInt = a[argNum].(int) // Almost always OK. 677 if !isInt { 678 // Work harder. 679 switch v := reflect.ValueOf(a[argNum]); v.Kind() { 680 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 681 n := v.Int() 682 if int64(int(n)) == n { 683 num = int(n) 684 isInt = true 685 } 686 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 687 n := v.Uint() 688 if int64(n) >= 0 && uint64(int(n)) == n { 689 num = int(n) 690 isInt = true 691 } 692 default: 693 // Already 0, false. 694 } 695 } 696 newArgNum = argNum + 1 697 if tooLarge(num) { 698 num = 0 699 isInt = false 700 } 701 } 702 return 703 } 704 705 // parseArgNumber returns the value of the bracketed number, minus 1 706 // (explicit argument numbers are one-indexed but we want zero-indexed). 707 // The opening bracket is known to be present at format[0]. 708 // The returned values are the index, the number of bytes to consume 709 // up to the closing paren, if present, and whether the number parsed 710 // ok. The bytes to consume will be 1 if no closing paren is present. 711 func parseArgNumber(format string) (index int, wid int, ok bool) { 712 // There must be at least 3 bytes: [n]. 713 if len(format) < 3 { 714 return 0, 1, false 715 } 716 717 // Find closing bracket. 718 for i := 1; i < len(format); i++ { 719 if format[i] == ']' { 720 width, ok, newi := parsenum(format, 1, i) 721 if !ok || newi != i { 722 return 0, i + 1, false 723 } 724 return width - 1, i + 1, true // arg numbers are one-indexed and skip paren. 725 } 726 } 727 return 0, 1, false 728 } 729 730 // argNumber returns the next argument to evaluate, which is either the value of the passed-in 731 // argNum or the value of the bracketed integer that begins format[i:]. It also returns 732 // the new value of i, that is, the index of the next byte of the format to process. 733 func (p *pp) argNumber(argNum int, format string, i int, numArgs int) (newArgNum, newi int, found bool) { 734 if len(format) <= i || format[i] != '[' { 735 return argNum, i, false 736 } 737 p.reordered = true 738 index, wid, ok := parseArgNumber(format[i:]) 739 if ok && 0 <= index && index < numArgs { 740 return index, i + wid, true 741 } 742 p.goodArgNum = false 743 return argNum, i + wid, ok 744 } 745 746 func (p *pp) badArgNum(verb rune) { 747 p.buf.writeString(percentBangString) 748 p.buf.writeRune(verb) 749 p.buf.writeString(badIndexString) 750 } 751 752 func (p *pp) missingArg(verb rune) { 753 p.buf.writeString(percentBangString) 754 p.buf.writeRune(verb) 755 p.buf.writeString(missingString) 756 } 757 758 func (p *pp) doPrintf(format string, a []interface{}) { 759 end := len(format) 760 argNum := 0 // we process one argument per non-trivial format 761 afterIndex := false // previous item in format was an index like [3]. 762 p.reordered = false 763 formatLoop: 764 for i := 0; i < end; { 765 p.goodArgNum = true 766 lasti := i 767 for i < end && format[i] != '%' { 768 i++ 769 } 770 if i > lasti { 771 p.buf.writeString(format[lasti:i]) 772 } 773 if i >= end { 774 // done processing format string 775 break 776 } 777 778 // Process one verb 779 i++ 780 781 // Do we have flags? 782 p.fmt.clearflags() 783 simpleFormat: 784 for ; i < end; i++ { 785 c := format[i] 786 switch c { 787 case '#': 788 p.fmt.sharp = true 789 case '0': 790 p.fmt.zero = !p.fmt.minus // Only allow zero padding to the left. 791 case '+': 792 p.fmt.plus = true 793 case '-': 794 p.fmt.minus = true 795 p.fmt.zero = false // Do not pad with zeros to the right. 796 case ' ': 797 p.fmt.space = true 798 default: 799 // Fast path for common case of ascii lower case simple verbs 800 // without precision or width or argument indices. 801 if 'a' <= c && c <= 'z' && argNum < len(a) { 802 if c == 'v' { 803 // Go syntax 804 p.fmt.sharpV = p.fmt.sharp 805 p.fmt.sharp = false 806 // Struct-field syntax 807 p.fmt.plusV = p.fmt.plus 808 p.fmt.plus = false 809 } 810 p.printArg(a[argNum], rune(c)) 811 argNum++ 812 i++ 813 continue formatLoop 814 } 815 // Format is more complex than simple flags and a verb or is malformed. 816 break simpleFormat 817 } 818 } 819 820 // Do we have an explicit argument index? 821 argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a)) 822 823 // Do we have width? 824 if i < end && format[i] == '*' { 825 i++ 826 p.fmt.wid, p.fmt.widPresent, argNum = intFromArg(a, argNum) 827 828 if !p.fmt.widPresent { 829 p.buf.writeString(badWidthString) 830 } 831 832 // We have a negative width, so take its value and ensure 833 // that the minus flag is set 834 if p.fmt.wid < 0 { 835 p.fmt.wid = -p.fmt.wid 836 p.fmt.minus = true 837 p.fmt.zero = false // Do not pad with zeros to the right. 838 } 839 afterIndex = false 840 } else { 841 p.fmt.wid, p.fmt.widPresent, i = parsenum(format, i, end) 842 if afterIndex && p.fmt.widPresent { // "%[3]2d" 843 p.goodArgNum = false 844 } 845 } 846 847 // Do we have precision? 848 if i+1 < end && format[i] == '.' { 849 i++ 850 if afterIndex { // "%[3].2d" 851 p.goodArgNum = false 852 } 853 argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a)) 854 if i < end && format[i] == '*' { 855 i++ 856 p.fmt.prec, p.fmt.precPresent, argNum = intFromArg(a, argNum) 857 // Negative precision arguments don't make sense 858 if p.fmt.prec < 0 { 859 p.fmt.prec = 0 860 p.fmt.precPresent = false 861 } 862 if !p.fmt.precPresent { 863 p.buf.writeString(badPrecString) 864 } 865 afterIndex = false 866 } else { 867 p.fmt.prec, p.fmt.precPresent, i = parsenum(format, i, end) 868 if !p.fmt.precPresent { 869 p.fmt.prec = 0 870 p.fmt.precPresent = true 871 } 872 } 873 } 874 875 if !afterIndex { 876 argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a)) 877 } 878 879 if i >= end { 880 p.buf.writeString(noVerbString) 881 break 882 } 883 884 verb, size := rune(format[i]), 1 885 if verb >= utf8.RuneSelf { 886 verb, size = utf8.DecodeRuneInString(format[i:]) 887 } 888 i += size 889 890 switch { 891 case verb == '%': // Percent does not absorb operands and ignores f.wid and f.prec. 892 p.buf.writeByte('%') 893 case !p.goodArgNum: 894 p.badArgNum(verb) 895 case argNum >= len(a): // No argument left over to print for the current verb. 896 p.missingArg(verb) 897 case verb == 'v': 898 // Go syntax 899 p.fmt.sharpV = p.fmt.sharp 900 p.fmt.sharp = false 901 // Struct-field syntax 902 p.fmt.plusV = p.fmt.plus 903 p.fmt.plus = false 904 fallthrough 905 default: 906 p.printArg(a[argNum], verb) 907 argNum++ 908 } 909 } 910 911 // Check for extra arguments unless the call accessed the arguments 912 // out of order, in which case it's too expensive to detect if they've all 913 // been used and arguably OK if they're not. 914 if !p.reordered && argNum < len(a) { 915 p.fmt.clearflags() 916 p.buf.writeString(extraString) 917 for i, arg := range a[argNum:] { 918 if i > 0 { 919 p.buf.writeString(commaSpaceString) 920 } 921 if arg == nil { 922 p.buf.writeString(nilAngleString) 923 } else { 924 p.buf.writeString(reflect.TypeOf(arg).String()) 925 p.buf.writeByte('=') 926 p.printArg(arg, 'v') 927 } 928 } 929 p.buf.writeByte(')') 930 } 931 } 932 933 func (p *pp) doPrint(a []interface{}) { 934 prevString := false 935 for argNum, arg := range a { 936 isString := arg != nil && reflect.TypeOf(arg).Kind() == reflect.String 937 // Add a space between two non-string arguments. 938 if argNum > 0 && !isString && !prevString { 939 p.buf.writeByte(' ') 940 } 941 p.printArg(arg, 'v') 942 prevString = isString 943 } 944 }