The Go Programming Language

Source file src/pkg/fmt/print.go

     1	// Copyright 2009 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 fmt
     6	
     7	import (
     8		"bytes"
     9		"io"
    10		"os"
    11		"reflect"
    12		"unicode"
    13		"utf8"
    14	)
    15	
    16	// Some constants in the form of bytes, to avoid string overhead.
    17	// Needlessly fastidious, I suppose.
    18	var (
    19		commaSpaceBytes = []byte(", ")
    20		nilAngleBytes   = []byte("<nil>")
    21		nilParenBytes   = []byte("(nil)")
    22		nilBytes        = []byte("nil")
    23		mapBytes        = []byte("map[")
    24		missingBytes    = []byte("(MISSING)")
    25		panicBytes      = []byte("(PANIC=")
    26		extraBytes      = []byte("%!(EXTRA ")
    27		irparenBytes    = []byte("i)")
    28		bytesBytes      = []byte("[]byte{")
    29		widthBytes      = []byte("%!(BADWIDTH)")
    30		precBytes       = []byte("%!(BADPREC)")
    31		noVerbBytes     = []byte("%!(NOVERB)")
    32	)
    33	
    34	// State represents the printer state passed to custom formatters.
    35	// It provides access to the io.Writer interface plus information about
    36	// the flags and options for the operand's format specifier.
    37	type State interface {
    38		// Write is the function to call to emit formatted output to be printed.
    39		Write(b []byte) (ret int, err os.Error)
    40		// Width returns the value of the width option and whether it has been set.
    41		Width() (wid int, ok bool)
    42		// Precision returns the value of the precision option and whether it has been set.
    43		Precision() (prec int, ok bool)
    44	
    45		// Flag returns whether the flag c, a character, has been set.
    46		Flag(c int) bool
    47	}
    48	
    49	// Formatter is the interface implemented by values with a custom formatter.
    50	// The implementation of Format may call Sprintf or Fprintf(f) etc.
    51	// to generate its output.
    52	type Formatter interface {
    53		Format(f State, c int)
    54	}
    55	
    56	// Stringer is implemented by any value that has a String method,
    57	// which defines the ``native'' format for that value.
    58	// The String method is used to print values passed as an operand
    59	// to a %s or %v format or to an unformatted printer such as Print.
    60	type Stringer interface {
    61		String() string
    62	}
    63	
    64	// GoStringer is implemented by any value that has a GoString method,
    65	// which defines the Go syntax for that value.
    66	// The GoString method is used to print values passed as an operand
    67	// to a %#v format.
    68	type GoStringer interface {
    69		GoString() string
    70	}
    71	
    72	type pp struct {
    73		n         int
    74		panicking bool
    75		buf       bytes.Buffer
    76		runeBuf   [utf8.UTFMax]byte
    77		fmt       fmt
    78	}
    79	
    80	// A cache holds a set of reusable objects.
    81	// The buffered channel holds the currently available objects.
    82	// If more are needed, the cache creates them by calling new.
    83	type cache struct {
    84		saved chan interface{}
    85		new   func() interface{}
    86	}
    87	
    88	func (c *cache) put(x interface{}) {
    89		select {
    90		case c.saved <- x:
    91			// saved in cache
    92		default:
    93			// discard
    94		}
    95	}
    96	
    97	func (c *cache) get() interface{} {
    98		select {
    99		case x := <-c.saved:
   100			return x // reused from cache
   101		default:
   102			return c.new()
   103		}
   104		panic("not reached")
   105	}
   106	
   107	func newCache(f func() interface{}) *cache {
   108		return &cache{make(chan interface{}, 100), f}
   109	}
   110	
   111	var ppFree = newCache(func() interface{} { return new(pp) })
   112	
   113	// Allocate a new pp struct or grab a cached one.
   114	func newPrinter() *pp {
   115		p := ppFree.get().(*pp)
   116		p.panicking = false
   117		p.fmt.init(&p.buf)
   118		return p
   119	}
   120	
   121	// Save used pp structs in ppFree; avoids an allocation per invocation.
   122	func (p *pp) free() {
   123		// Don't hold on to pp structs with large buffers.
   124		if cap(p.buf.Bytes()) > 1024 {
   125			return
   126		}
   127		p.buf.Reset()
   128		ppFree.put(p)
   129	}
   130	
   131	func (p *pp) Width() (wid int, ok bool) { return p.fmt.wid, p.fmt.widPresent }
   132	
   133	func (p *pp) Precision() (prec int, ok bool) { return p.fmt.prec, p.fmt.precPresent }
   134	
   135	func (p *pp) Flag(b int) bool {
   136		switch b {
   137		case '-':
   138			return p.fmt.minus
   139		case '+':
   140			return p.fmt.plus
   141		case '#':
   142			return p.fmt.sharp
   143		case ' ':
   144			return p.fmt.space
   145		case '0':
   146			return p.fmt.zero
   147		}
   148		return false
   149	}
   150	
   151	func (p *pp) add(c int) {
   152		p.buf.WriteRune(c)
   153	}
   154	
   155	// Implement Write so we can call Fprintf on a pp (through State), for
   156	// recursive use in custom verbs.
   157	func (p *pp) Write(b []byte) (ret int, err os.Error) {
   158		return p.buf.Write(b)
   159	}
   160	
   161	// These routines end in 'f' and take a format string.
   162	
   163	// Fprintf formats according to a format specifier and writes to w.
   164	// It returns the number of bytes written and any write error encountered.
   165	func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err os.Error) {
   166		p := newPrinter()
   167		p.doPrintf(format, a)
   168		n64, err := p.buf.WriteTo(w)
   169		p.free()
   170		return int(n64), err
   171	}
   172	
   173	// Printf formats according to a format specifier and writes to standard output.
   174	// It returns the number of bytes written and any write error encountered.
   175	func Printf(format string, a ...interface{}) (n int, err os.Error) {
   176		return Fprintf(os.Stdout, format, a...)
   177	}
   178	
   179	// Sprintf formats according to a format specifier and returns the resulting string.
   180	func Sprintf(format string, a ...interface{}) string {
   181		p := newPrinter()
   182		p.doPrintf(format, a)
   183		s := p.buf.String()
   184		p.free()
   185		return s
   186	}
   187	
   188	// Errorf formats according to a format specifier and returns the string 
   189	// converted to an os.ErrorString, which satisfies the os.Error interface.
   190	func Errorf(format string, a ...interface{}) os.Error {
   191		return os.NewError(Sprintf(format, a...))
   192	}
   193	
   194	// These routines do not take a format string
   195	
   196	// Fprint formats using the default formats for its operands and writes to w.
   197	// Spaces are added between operands when neither is a string.
   198	// It returns the number of bytes written and any write error encountered.
   199	func Fprint(w io.Writer, a ...interface{}) (n int, err os.Error) {
   200		p := newPrinter()
   201		p.doPrint(a, false, false)
   202		n64, err := p.buf.WriteTo(w)
   203		p.free()
   204		return int(n64), err
   205	}
   206	
   207	// Print formats using the default formats for its operands and writes to standard output.
   208	// Spaces are added between operands when neither is a string.
   209	// It returns the number of bytes written and any write error encountered.
   210	func Print(a ...interface{}) (n int, err os.Error) {
   211		return Fprint(os.Stdout, a...)
   212	}
   213	
   214	// Sprint formats using the default formats for its operands and returns the resulting string.
   215	// Spaces are added between operands when neither is a string.
   216	func Sprint(a ...interface{}) string {
   217		p := newPrinter()
   218		p.doPrint(a, false, false)
   219		s := p.buf.String()
   220		p.free()
   221		return s
   222	}
   223	
   224	// These routines end in 'ln', do not take a format string,
   225	// always add spaces between operands, and add a newline
   226	// after the last operand.
   227	
   228	// Fprintln formats using the default formats for its operands and writes to w.
   229	// Spaces are always added between operands and a newline is appended.
   230	// It returns the number of bytes written and any write error encountered.
   231	func Fprintln(w io.Writer, a ...interface{}) (n int, err os.Error) {
   232		p := newPrinter()
   233		p.doPrint(a, true, true)
   234		n64, err := p.buf.WriteTo(w)
   235		p.free()
   236		return int(n64), err
   237	}
   238	
   239	// Println formats using the default formats for its operands and writes to standard output.
   240	// Spaces are always added between operands and a newline is appended.
   241	// It returns the number of bytes written and any write error encountered.
   242	func Println(a ...interface{}) (n int, err os.Error) {
   243		return Fprintln(os.Stdout, a...)
   244	}
   245	
   246	// Sprintln formats using the default formats for its operands and returns the resulting string.
   247	// Spaces are always added between operands and a newline is appended.
   248	func Sprintln(a ...interface{}) string {
   249		p := newPrinter()
   250		p.doPrint(a, true, true)
   251		s := p.buf.String()
   252		p.free()
   253		return s
   254	}
   255	
   256	// Get the i'th arg of the struct value.
   257	// If the arg itself is an interface, return a value for
   258	// the thing inside the interface, not the interface itself.
   259	func getField(v reflect.Value, i int) reflect.Value {
   260		val := v.Field(i)
   261		if val.Kind() == reflect.Interface && !val.IsNil() {
   262			val = val.Elem()
   263		}
   264		return val
   265	}
   266	
   267	// Convert ASCII to integer.  n is 0 (and got is false) if no number present.
   268	func parsenum(s string, start, end int) (num int, isnum bool, newi int) {
   269		if start >= end {
   270			return 0, false, end
   271		}
   272		for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++ {
   273			num = num*10 + int(s[newi]-'0')
   274			isnum = true
   275		}
   276		return
   277	}
   278	
   279	func (p *pp) unknownType(v interface{}) {
   280		if v == nil {
   281			p.buf.Write(nilAngleBytes)
   282			return
   283		}
   284		p.buf.WriteByte('?')
   285		p.buf.WriteString(reflect.TypeOf(v).String())
   286		p.buf.WriteByte('?')
   287	}
   288	
   289	func (p *pp) badVerb(verb int, val interface{}, val1 reflect.Value) {
   290		p.add('%')
   291		p.add('!')
   292		p.add(verb)
   293		p.add('(')
   294		switch {
   295		case val != nil:
   296			p.buf.WriteString(reflect.TypeOf(val).String())
   297			p.add('=')
   298			p.printField(val, 'v', false, false, 0)
   299		case val1.IsValid():
   300			p.buf.WriteString(val1.Type().String())
   301			p.add('=')
   302			p.printValue(val1, 'v', false, false, 0)
   303		default:
   304			p.buf.Write(nilAngleBytes)
   305		}
   306		p.add(')')
   307	}
   308	
   309	func (p *pp) fmtBool(v bool, verb int, value interface{}, value1 reflect.Value) {
   310		switch verb {
   311		case 't', 'v':
   312			p.fmt.fmt_boolean(v)
   313		default:
   314			p.badVerb(verb, value, value1)
   315		}
   316	}
   317	
   318	// fmtC formats a rune for the 'c' format.
   319	func (p *pp) fmtC(c int64) {
   320		rune := int(c) // Check for overflow.
   321		if int64(rune) != c {
   322			rune = utf8.RuneError
   323		}
   324		w := utf8.EncodeRune(p.runeBuf[0:utf8.UTFMax], rune)
   325		p.fmt.pad(p.runeBuf[0:w])
   326	}
   327	
   328	func (p *pp) fmtInt64(v int64, verb int, value interface{}, value1 reflect.Value) {
   329		switch verb {
   330		case 'b':
   331			p.fmt.integer(v, 2, signed, ldigits)
   332		case 'c':
   333			p.fmtC(v)
   334		case 'd', 'v':
   335			p.fmt.integer(v, 10, signed, ldigits)
   336		case 'o':
   337			p.fmt.integer(v, 8, signed, ldigits)
   338		case 'q':
   339			if 0 <= v && v <= unicode.MaxRune {
   340				p.fmt.fmt_qc(v)
   341			} else {
   342				p.badVerb(verb, value, value1)
   343			}
   344		case 'x':
   345			p.fmt.integer(v, 16, signed, ldigits)
   346		case 'U':
   347			p.fmtUnicode(v)
   348		case 'X':
   349			p.fmt.integer(v, 16, signed, udigits)
   350		default:
   351			p.badVerb(verb, value, value1)
   352		}
   353	}
   354	
   355	// fmt0x64 formats a uint64 in hexadecimal and prefixes it with 0x or
   356	// not, as requested, by temporarily setting the sharp flag.
   357	func (p *pp) fmt0x64(v uint64, leading0x bool) {
   358		sharp := p.fmt.sharp
   359		p.fmt.sharp = leading0x
   360		p.fmt.integer(int64(v), 16, unsigned, ldigits)
   361		p.fmt.sharp = sharp
   362	}
   363	
   364	// fmtUnicode formats a uint64 in U+1234 form by
   365	// temporarily turning on the unicode flag and tweaking the precision.
   366	func (p *pp) fmtUnicode(v int64) {
   367		precPresent := p.fmt.precPresent
   368		sharp := p.fmt.sharp
   369		p.fmt.sharp = false
   370		prec := p.fmt.prec
   371		if !precPresent {
   372			// If prec is already set, leave it alone; otherwise 4 is minimum.
   373			p.fmt.prec = 4
   374			p.fmt.precPresent = true
   375		}
   376		p.fmt.unicode = true // turn on U+
   377		p.fmt.uniQuote = sharp
   378		p.fmt.integer(int64(v), 16, unsigned, udigits)
   379		p.fmt.unicode = false
   380		p.fmt.uniQuote = false
   381		p.fmt.prec = prec
   382		p.fmt.precPresent = precPresent
   383		p.fmt.sharp = sharp
   384	}
   385	
   386	func (p *pp) fmtUint64(v uint64, verb int, goSyntax bool, value interface{}, value1 reflect.Value) {
   387		switch verb {
   388		case 'b':
   389			p.fmt.integer(int64(v), 2, unsigned, ldigits)
   390		case 'c':
   391			p.fmtC(int64(v))
   392		case 'd':
   393			p.fmt.integer(int64(v), 10, unsigned, ldigits)
   394		case 'v':
   395			if goSyntax {
   396				p.fmt0x64(v, true)
   397			} else {
   398				p.fmt.integer(int64(v), 10, unsigned, ldigits)
   399			}
   400		case 'o':
   401			p.fmt.integer(int64(v), 8, unsigned, ldigits)
   402		case 'q':
   403			if 0 <= v && v <= unicode.MaxRune {
   404				p.fmt.fmt_qc(int64(v))
   405			} else {
   406				p.badVerb(verb, value, value1)
   407			}
   408		case 'x':
   409			p.fmt.integer(int64(v), 16, unsigned, ldigits)
   410		case 'X':
   411			p.fmt.integer(int64(v), 16, unsigned, udigits)
   412		case 'U':
   413			p.fmtUnicode(int64(v))
   414		default:
   415			p.badVerb(verb, value, value1)
   416		}
   417	}
   418	
   419	func (p *pp) fmtFloat32(v float32, verb int, value interface{}, value1 reflect.Value) {
   420		switch verb {
   421		case 'b':
   422			p.fmt.fmt_fb32(v)
   423		case 'e':
   424			p.fmt.fmt_e32(v)
   425		case 'E':
   426			p.fmt.fmt_E32(v)
   427		case 'f':
   428			p.fmt.fmt_f32(v)
   429		case 'g', 'v':
   430			p.fmt.fmt_g32(v)
   431		case 'G':
   432			p.fmt.fmt_G32(v)
   433		default:
   434			p.badVerb(verb, value, value1)
   435		}
   436	}
   437	
   438	func (p *pp) fmtFloat64(v float64, verb int, value interface{}, value1 reflect.Value) {
   439		switch verb {
   440		case 'b':
   441			p.fmt.fmt_fb64(v)
   442		case 'e':
   443			p.fmt.fmt_e64(v)
   444		case 'E':
   445			p.fmt.fmt_E64(v)
   446		case 'f':
   447			p.fmt.fmt_f64(v)
   448		case 'g', 'v':
   449			p.fmt.fmt_g64(v)
   450		case 'G':
   451			p.fmt.fmt_G64(v)
   452		default:
   453			p.badVerb(verb, value, value1)
   454		}
   455	}
   456	
   457	func (p *pp) fmtComplex64(v complex64, verb int, value interface{}, value1 reflect.Value) {
   458		switch verb {
   459		case 'e', 'E', 'f', 'F', 'g', 'G':
   460			p.fmt.fmt_c64(v, verb)
   461		case 'v':
   462			p.fmt.fmt_c64(v, 'g')
   463		default:
   464			p.badVerb(verb, value, value1)
   465		}
   466	}
   467	
   468	func (p *pp) fmtComplex128(v complex128, verb int, value interface{}, value1 reflect.Value) {
   469		switch verb {
   470		case 'e', 'E', 'f', 'F', 'g', 'G':
   471			p.fmt.fmt_c128(v, verb)
   472		case 'v':
   473			p.fmt.fmt_c128(v, 'g')
   474		default:
   475			p.badVerb(verb, value, value1)
   476		}
   477	}
   478	
   479	func (p *pp) fmtString(v string, verb int, goSyntax bool, value interface{}, value1 reflect.Value) {
   480		switch verb {
   481		case 'v':
   482			if goSyntax {
   483				p.fmt.fmt_q(v)
   484			} else {
   485				p.fmt.fmt_s(v)
   486			}
   487		case 's':
   488			p.fmt.fmt_s(v)
   489		case 'x':
   490			p.fmt.fmt_sx(v)
   491		case 'X':
   492			p.fmt.fmt_sX(v)
   493		case 'q':
   494			p.fmt.fmt_q(v)
   495		default:
   496			p.badVerb(verb, value, value1)
   497		}
   498	}
   499	
   500	func (p *pp) fmtBytes(v []byte, verb int, goSyntax bool, depth int, value interface{}, value1 reflect.Value) {
   501		if verb == 'v' || verb == 'd' {
   502			if goSyntax {
   503				p.buf.Write(bytesBytes)
   504			} else {
   505				p.buf.WriteByte('[')
   506			}
   507			for i, c := range v {
   508				if i > 0 {
   509					if goSyntax {
   510						p.buf.Write(commaSpaceBytes)
   511					} else {
   512						p.buf.WriteByte(' ')
   513					}
   514				}
   515				p.printField(c, 'v', p.fmt.plus, goSyntax, depth+1)
   516			}
   517			if goSyntax {
   518				p.buf.WriteByte('}')
   519			} else {
   520				p.buf.WriteByte(']')
   521			}
   522			return
   523		}
   524		s := string(v)
   525		switch verb {
   526		case 's':
   527			p.fmt.fmt_s(s)
   528		case 'x':
   529			p.fmt.fmt_sx(s)
   530		case 'X':
   531			p.fmt.fmt_sX(s)
   532		case 'q':
   533			p.fmt.fmt_q(s)
   534		default:
   535			p.badVerb(verb, value, value1)
   536		}
   537	}
   538	
   539	func (p *pp) fmtPointer(field interface{}, value reflect.Value, verb int, goSyntax bool) {
   540		var u uintptr
   541		switch value.Kind() {
   542		case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
   543			u = value.Pointer()
   544		default:
   545			p.badVerb(verb, field, value)
   546			return
   547		}
   548		if goSyntax {
   549			p.add('(')
   550			p.buf.WriteString(value.Type().String())
   551			p.add(')')
   552			p.add('(')
   553			if u == 0 {
   554				p.buf.Write(nilBytes)
   555			} else {
   556				p.fmt0x64(uint64(u), true)
   557			}
   558			p.add(')')
   559		} else {
   560			p.fmt0x64(uint64(u), !p.fmt.sharp)
   561		}
   562	}
   563	
   564	var (
   565		intBits     = reflect.TypeOf(0).Bits()
   566		floatBits   = reflect.TypeOf(0.0).Bits()
   567		complexBits = reflect.TypeOf(1i).Bits()
   568		uintptrBits = reflect.TypeOf(uintptr(0)).Bits()
   569	)
   570	
   571	func (p *pp) catchPanic(val interface{}, verb int) {
   572		if err := recover(); err != nil {
   573			// If it's a nil pointer, just say "<nil>". The likeliest causes are a
   574			// Stringer that fails to guard against nil or a nil pointer for a
   575			// value receiver, and in either case, "<nil>" is a nice result.
   576			if v := reflect.ValueOf(val); v.Kind() == reflect.Ptr && v.IsNil() {
   577				p.buf.Write(nilAngleBytes)
   578				return
   579			}
   580			// Otherwise print a concise panic message. Most of the time the panic
   581			// value will print itself nicely.
   582			if p.panicking {
   583				// Nested panics; the recursion in printField cannot succeed.
   584				panic(err)
   585			}
   586			p.buf.WriteByte('%')
   587			p.add(verb)
   588			p.buf.Write(panicBytes)
   589			p.panicking = true
   590			p.printField(err, 'v', false, false, 0)
   591			p.panicking = false
   592			p.buf.WriteByte(')')
   593		}
   594	}
   595	
   596	func (p *pp) handleMethods(field interface{}, verb int, plus, goSyntax bool, depth int) (wasString, handled bool) {
   597		// Is it a Formatter?
   598		if formatter, ok := field.(Formatter); ok {
   599			handled = true
   600			wasString = false
   601			defer p.catchPanic(field, verb)
   602			formatter.Format(p, verb)
   603			return
   604		}
   605		// Must not touch flags before Formatter looks at them.
   606		if plus {
   607			p.fmt.plus = false
   608		}
   609	
   610		// If we're doing Go syntax and the field knows how to supply it, take care of it now.
   611		if goSyntax {
   612			p.fmt.sharp = false
   613			if stringer, ok := field.(GoStringer); ok {
   614				wasString = false
   615				handled = true
   616				defer p.catchPanic(field, verb)
   617				// Print the result of GoString unadorned.
   618				p.fmtString(stringer.GoString(), 's', false, field, reflect.Value{})
   619				return
   620			}
   621		} else {
   622			// Is it a Stringer?
   623			if stringer, ok := field.(Stringer); ok {
   624				wasString = false
   625				handled = true
   626				defer p.catchPanic(field, verb)
   627				p.printField(stringer.String(), verb, plus, false, depth)
   628				return
   629			}
   630		}
   631		handled = false
   632		return
   633	}
   634	
   635	func (p *pp) printField(field interface{}, verb int, plus, goSyntax bool, depth int) (wasString bool) {
   636		if field == nil {
   637			if verb == 'T' || verb == 'v' {
   638				p.buf.Write(nilAngleBytes)
   639			} else {
   640				p.badVerb(verb, field, reflect.Value{})
   641			}
   642			return false
   643		}
   644	
   645		// Special processing considerations.
   646		// %T (the value's type) and %p (its address) are special; we always do them first.
   647		switch verb {
   648		case 'T':
   649			p.printField(reflect.TypeOf(field).String(), 's', false, false, 0)
   650			return false
   651		case 'p':
   652			p.fmtPointer(field, reflect.ValueOf(field), verb, goSyntax)
   653			return false
   654		}
   655	
   656		if wasString, handled := p.handleMethods(field, verb, plus, goSyntax, depth); handled {
   657			return wasString
   658		}
   659	
   660		// Some types can be done without reflection.
   661		switch f := field.(type) {
   662		case bool:
   663			p.fmtBool(f, verb, field, reflect.Value{})
   664			return false
   665		case float32:
   666			p.fmtFloat32(f, verb, field, reflect.Value{})
   667			return false
   668		case float64:
   669			p.fmtFloat64(f, verb, field, reflect.Value{})
   670			return false
   671		case complex64:
   672			p.fmtComplex64(complex64(f), verb, field, reflect.Value{})
   673			return false
   674		case complex128:
   675			p.fmtComplex128(f, verb, field, reflect.Value{})
   676			return false
   677		case int:
   678			p.fmtInt64(int64(f), verb, field, reflect.Value{})
   679			return false
   680		case int8:
   681			p.fmtInt64(int64(f), verb, field, reflect.Value{})
   682			return false
   683		case int16:
   684			p.fmtInt64(int64(f), verb, field, reflect.Value{})
   685			return false
   686		case int32:
   687			p.fmtInt64(int64(f), verb, field, reflect.Value{})
   688			return false
   689		case int64:
   690			p.fmtInt64(f, verb, field, reflect.Value{})
   691			return false
   692		case uint:
   693			p.fmtUint64(uint64(f), verb, goSyntax, field, reflect.Value{})
   694			return false
   695		case uint8:
   696			p.fmtUint64(uint64(f), verb, goSyntax, field, reflect.Value{})
   697			return false
   698		case uint16:
   699			p.fmtUint64(uint64(f), verb, goSyntax, field, reflect.Value{})
   700			return false
   701		case uint32:
   702			p.fmtUint64(uint64(f), verb, goSyntax, field, reflect.Value{})
   703			return false
   704		case uint64:
   705			p.fmtUint64(f, verb, goSyntax, field, reflect.Value{})
   706			return false
   707		case uintptr:
   708			p.fmtUint64(uint64(f), verb, goSyntax, field, reflect.Value{})
   709			return false
   710		case string:
   711			p.fmtString(f, verb, goSyntax, field, reflect.Value{})
   712			return verb == 's' || verb == 'v'
   713		case []byte:
   714			p.fmtBytes(f, verb, goSyntax, depth, field, reflect.Value{})
   715			return verb == 's'
   716		}
   717	
   718		// Need to use reflection
   719		return p.printReflectValue(reflect.ValueOf(field), verb, plus, goSyntax, depth)
   720	}
   721	
   722	// printValue is like printField but starts with a reflect value, not an interface{} value.
   723	func (p *pp) printValue(value reflect.Value, verb int, plus, goSyntax bool, depth int) (wasString bool) {
   724		if !value.IsValid() {
   725			if verb == 'T' || verb == 'v' {
   726				p.buf.Write(nilAngleBytes)
   727			} else {
   728				p.badVerb(verb, nil, value)
   729			}
   730			return false
   731		}
   732	
   733		// Special processing considerations.
   734		// %T (the value's type) and %p (its address) are special; we always do them first.
   735		switch verb {
   736		case 'T':
   737			p.printField(value.Type().String(), 's', false, false, 0)
   738			return false
   739		case 'p':
   740			p.fmtPointer(nil, value, verb, goSyntax)
   741			return false
   742		}
   743	
   744		// Handle values with special methods.
   745		// Call always, even when field == nil, because handleMethods clears p.fmt.plus for us.
   746		var field interface{}
   747		if value.CanInterface() {
   748			field = value.Interface()
   749		}
   750		if wasString, handled := p.handleMethods(field, verb, plus, goSyntax, depth); handled {
   751			return wasString
   752		}
   753	
   754		return p.printReflectValue(value, verb, plus, goSyntax, depth)
   755	}
   756	
   757	// printReflectValue is the fallback for both printField and printValue.
   758	// It uses reflect to print the value.
   759	func (p *pp) printReflectValue(value reflect.Value, verb int, plus, goSyntax bool, depth int) (wasString bool) {
   760	BigSwitch:
   761		switch f := value; f.Kind() {
   762		case reflect.Bool:
   763			p.fmtBool(f.Bool(), verb, nil, value)
   764		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   765			p.fmtInt64(f.Int(), verb, nil, value)
   766		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   767			p.fmtUint64(uint64(f.Uint()), verb, goSyntax, nil, value)
   768		case reflect.Float32, reflect.Float64:
   769			if f.Type().Size() == 4 {
   770				p.fmtFloat32(float32(f.Float()), verb, nil, value)
   771			} else {
   772				p.fmtFloat64(float64(f.Float()), verb, nil, value)
   773			}
   774		case reflect.Complex64, reflect.Complex128:
   775			if f.Type().Size() == 8 {
   776				p.fmtComplex64(complex64(f.Complex()), verb, nil, value)
   777			} else {
   778				p.fmtComplex128(complex128(f.Complex()), verb, nil, value)
   779			}
   780		case reflect.String:
   781			p.fmtString(f.String(), verb, goSyntax, nil, value)
   782		case reflect.Map:
   783			if goSyntax {
   784				p.buf.WriteString(f.Type().String())
   785				p.buf.WriteByte('{')
   786			} else {
   787				p.buf.Write(mapBytes)
   788			}
   789			keys := f.MapKeys()
   790			for i, key := range keys {
   791				if i > 0 {
   792					if goSyntax {
   793						p.buf.Write(commaSpaceBytes)
   794					} else {
   795						p.buf.WriteByte(' ')
   796					}
   797				}
   798				p.printValue(key, verb, plus, goSyntax, depth+1)
   799				p.buf.WriteByte(':')
   800				p.printValue(f.MapIndex(key), verb, plus, goSyntax, depth+1)
   801			}
   802			if goSyntax {
   803				p.buf.WriteByte('}')
   804			} else {
   805				p.buf.WriteByte(']')
   806			}
   807		case reflect.Struct:
   808			if goSyntax {
   809				p.buf.WriteString(value.Type().String())
   810			}
   811			p.add('{')
   812			v := f
   813			t := v.Type()
   814			for i := 0; i < v.NumField(); i++ {
   815				if i > 0 {
   816					if goSyntax {
   817						p.buf.Write(commaSpaceBytes)
   818					} else {
   819						p.buf.WriteByte(' ')
   820					}
   821				}
   822				if plus || goSyntax {
   823					if f := t.Field(i); f.Name != "" {
   824						p.buf.WriteString(f.Name)
   825						p.buf.WriteByte(':')
   826					}
   827				}
   828				p.printValue(getField(v, i), verb, plus, goSyntax, depth+1)
   829			}
   830			p.buf.WriteByte('}')
   831		case reflect.Interface:
   832			value := f.Elem()
   833			if !value.IsValid() {
   834				if goSyntax {
   835					p.buf.WriteString(value.Type().String())
   836					p.buf.Write(nilParenBytes)
   837				} else {
   838					p.buf.Write(nilAngleBytes)
   839				}
   840			} else {
   841				return p.printValue(value, verb, plus, goSyntax, depth+1)
   842			}
   843		case reflect.Array, reflect.Slice:
   844			// Byte slices are special.
   845			if f.Type().Elem().Kind() == reflect.Uint8 {
   846				// We know it's a slice of bytes, but we also know it does not have static type
   847				// []byte, or it would have been caught above.  Therefore we cannot convert
   848				// it directly in the (slightly) obvious way: f.Interface().([]byte); it doesn't have
   849				// that type, and we can't write an expression of the right type and do a
   850				// conversion because we don't have a static way to write the right type.
   851				// So we build a slice by hand.  This is a rare case but it would be nice
   852				// if reflection could help a little more.
   853				bytes := make([]byte, f.Len())
   854				for i := range bytes {
   855					bytes[i] = byte(f.Index(i).Uint())
   856				}
   857				p.fmtBytes(bytes, verb, goSyntax, depth, nil, value)
   858				return verb == 's'
   859			}
   860			if goSyntax {
   861				p.buf.WriteString(value.Type().String())
   862				p.buf.WriteByte('{')
   863			} else {
   864				p.buf.WriteByte('[')
   865			}
   866			for i := 0; i < f.Len(); i++ {
   867				if i > 0 {
   868					if goSyntax {
   869						p.buf.Write(commaSpaceBytes)
   870					} else {
   871						p.buf.WriteByte(' ')
   872					}
   873				}
   874				p.printValue(f.Index(i), verb, plus, goSyntax, depth+1)
   875			}
   876			if goSyntax {
   877				p.buf.WriteByte('}')
   878			} else {
   879				p.buf.WriteByte(']')
   880			}
   881		case reflect.Ptr:
   882			v := f.Pointer()
   883			// pointer to array or slice or struct?  ok at top level
   884			// but not embedded (avoid loops)
   885			if v != 0 && depth == 0 {
   886				switch a := f.Elem(); a.Kind() {
   887				case reflect.Array, reflect.Slice:
   888					p.buf.WriteByte('&')
   889					p.printValue(a, verb, plus, goSyntax, depth+1)
   890					break BigSwitch
   891				case reflect.Struct:
   892					p.buf.WriteByte('&')
   893					p.printValue(a, verb, plus, goSyntax, depth+1)
   894					break BigSwitch
   895				}
   896			}
   897			if goSyntax {
   898				p.buf.WriteByte('(')
   899				p.buf.WriteString(value.Type().String())
   900				p.buf.WriteByte(')')
   901				p.buf.WriteByte('(')
   902				if v == 0 {
   903					p.buf.Write(nilBytes)
   904				} else {
   905					p.fmt0x64(uint64(v), true)
   906				}
   907				p.buf.WriteByte(')')
   908				break
   909			}
   910			if v == 0 {
   911				p.buf.Write(nilAngleBytes)
   912				break
   913			}
   914			p.fmt0x64(uint64(v), true)
   915		case reflect.Chan, reflect.Func, reflect.UnsafePointer:
   916			p.fmtPointer(nil, value, verb, goSyntax)
   917		default:
   918			p.unknownType(f)
   919		}
   920		return false
   921	}
   922	
   923	// intFromArg gets the fieldnumth element of a. On return, isInt reports whether the argument has type int.
   924	func intFromArg(a []interface{}, end, i, fieldnum int) (num int, isInt bool, newi, newfieldnum int) {
   925		newi, newfieldnum = end, fieldnum
   926		if i < end && fieldnum < len(a) {
   927			num, isInt = a[fieldnum].(int)
   928			newi, newfieldnum = i+1, fieldnum+1
   929		}
   930		return
   931	}
   932	
   933	func (p *pp) doPrintf(format string, a []interface{}) {
   934		end := len(format)
   935		fieldnum := 0 // we process one field per non-trivial format
   936		for i := 0; i < end; {
   937			lasti := i
   938			for i < end && format[i] != '%' {
   939				i++
   940			}
   941			if i > lasti {
   942				p.buf.WriteString(format[lasti:i])
   943			}
   944			if i >= end {
   945				// done processing format string
   946				break
   947			}
   948	
   949			// Process one verb
   950			i++
   951			// flags and widths
   952			p.fmt.clearflags()
   953		F:
   954			for ; i < end; i++ {
   955				switch format[i] {
   956				case '#':
   957					p.fmt.sharp = true
   958				case '0':
   959					p.fmt.zero = true
   960				case '+':
   961					p.fmt.plus = true
   962				case '-':
   963					p.fmt.minus = true
   964				case ' ':
   965					p.fmt.space = true
   966				default:
   967					break F
   968				}
   969			}
   970			// do we have width?
   971			if i < end && format[i] == '*' {
   972				p.fmt.wid, p.fmt.widPresent, i, fieldnum = intFromArg(a, end, i, fieldnum)
   973				if !p.fmt.widPresent {
   974					p.buf.Write(widthBytes)
   975				}
   976			} else {
   977				p.fmt.wid, p.fmt.widPresent, i = parsenum(format, i, end)
   978			}
   979			// do we have precision?
   980			if i < end && format[i] == '.' {
   981				if format[i+1] == '*' {
   982					p.fmt.prec, p.fmt.precPresent, i, fieldnum = intFromArg(a, end, i+1, fieldnum)
   983					if !p.fmt.precPresent {
   984						p.buf.Write(precBytes)
   985					}
   986				} else {
   987					p.fmt.prec, p.fmt.precPresent, i = parsenum(format, i+1, end)
   988					if !p.fmt.precPresent {
   989						p.fmt.prec = 0
   990						p.fmt.precPresent = true
   991					}
   992				}
   993			}
   994			if i >= end {
   995				p.buf.Write(noVerbBytes)
   996				continue
   997			}
   998			c, w := utf8.DecodeRuneInString(format[i:])
   999			i += w
  1000			// percent is special - absorbs no operand
  1001			if c == '%' {
  1002				p.buf.WriteByte('%') // We ignore width and prec.
  1003				continue
  1004			}
  1005			if fieldnum >= len(a) { // out of operands
  1006				p.buf.WriteByte('%')
  1007				p.add(c)
  1008				p.buf.Write(missingBytes)
  1009				continue
  1010			}
  1011			field := a[fieldnum]
  1012			fieldnum++
  1013	
  1014			goSyntax := c == 'v' && p.fmt.sharp
  1015			plus := c == 'v' && p.fmt.plus
  1016			p.printField(field, c, plus, goSyntax, 0)
  1017		}
  1018	
  1019		if fieldnum < len(a) {
  1020			p.buf.Write(extraBytes)
  1021			for ; fieldnum < len(a); fieldnum++ {
  1022				field := a[fieldnum]
  1023				if field != nil {
  1024					p.buf.WriteString(reflect.TypeOf(field).String())
  1025					p.buf.WriteByte('=')
  1026				}
  1027				p.printField(field, 'v', false, false, 0)
  1028				if fieldnum+1 < len(a) {
  1029					p.buf.Write(commaSpaceBytes)
  1030				}
  1031			}
  1032			p.buf.WriteByte(')')
  1033		}
  1034	}
  1035	
  1036	func (p *pp) doPrint(a []interface{}, addspace, addnewline bool) {
  1037		prevString := false
  1038		for fieldnum := 0; fieldnum < len(a); fieldnum++ {
  1039			p.fmt.clearflags()
  1040			// always add spaces if we're doing println
  1041			field := a[fieldnum]
  1042			if fieldnum > 0 {
  1043				isString := field != nil && reflect.TypeOf(field).Kind() == reflect.String
  1044				if addspace || !isString && !prevString {
  1045					p.buf.WriteByte(' ')
  1046				}
  1047			}
  1048			prevString = p.printField(field, 'v', false, false, 0)
  1049		}
  1050		if addnewline {
  1051			p.buf.WriteByte('\n')
  1052		}
  1053	}

release.r60.3. Except as noted, this content is licensed under a Creative Commons Attribution 3.0 License.