print.go 23.4 KB
Newer Older
Rob Pike's avatar
Rob Pike committed
1 2 3 4
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

Rob Pike's avatar
Rob Pike committed
5 6 7 8 9 10 11 12
/*
	Package fmt implements formatted I/O with functions analogous
	to C's printf.  The format 'verbs' are derived from C's but
	are simpler.

	The verbs:

	General:
Russ Cox's avatar
Russ Cox committed
13
		%v	the value in a default format.
Rob Pike's avatar
Rob Pike committed
14
			when printing structs, the plus flag (%+v) adds field names
Russ Cox's avatar
Russ Cox committed
15 16 17
		%#v	a Go-syntax representation of the value
		%T	a Go-syntax representation of the type of the value

Rob Pike's avatar
Rob Pike committed
18 19 20 21 22 23 24 25 26 27 28
	Boolean:
		%t	the word true or false
	Integer:
		%b	base 2
		%c	the character represented by the corresponding Unicode code point
		%d	base 10
		%o	base 8
		%x	base 16, with lower-case letters for a-f
		%X	base 16, with upper-case letters for A-F
	Floating-point:
		%e	scientific notation, e.g. -1234.456e+78
Russ Cox's avatar
Russ Cox committed
29
		%E	scientific notation, e.g. -1234.456E+78
Rob Pike's avatar
Rob Pike committed
30 31
		%f	decimal point but no exponent, e.g. 123.456
		%g	whichever of %e or %f produces more compact output
Russ Cox's avatar
Russ Cox committed
32
		%G	whichever of %E or %f produces more compact output
Rob Pike's avatar
Rob Pike committed
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
	String and slice of bytes:
		%s	the uninterpreted bytes of the string or slice
		%q	a double-quoted string safely escaped with Go syntax
		%x	base 16 notation with two characters per byte
	Pointer:
		%p	base 16 notation, with leading 0x

	There is no 'u' flag.  Integers are printed unsigned if they have unsigned type.
	Similarly, there is no need to specify the size of the operand (int8, int64).

	For numeric values, the width and precision flags control
	formatting; width sets the width of the field, precision the
	number of places after the decimal, if appropriate.  The
	format %6.2f prints 123.45.

	Other flags:
		+	always print a sign for numeric values
		-	pad with spaces on the right rather than the left (left-justify the field)
		#	alternate format: add leading 0 for octal (%#o), 0x for hex (%#x);
			suppress 0x for %p (%#p);
			print a raw (backquoted) string if possible for %q (%#q)
		' '	(space) leave a space for elided sign in numbers (% d);
			put spaces between bytes printing strings or slices in hex (% x)
		0	pad with leading zeros rather than spaces

	For each Printf-like function, there is also a Print function
	that takes no format and is equivalent to saying %v for every
	operand.  Another variant Println inserts blanks between
	operands and appends a newline.

63 64 65 66 67 68 69
	Regardless of the verb, if an operand is an interface value,
	the internal concrete value is used, not the interface itself.
	Thus:
		var i interface{} = 23;
		fmt.Printf("%v\n", i);
	will print 23.

Rob Pike's avatar
Rob Pike committed
70
	If an operand implements interface Formatter, that interface
Rob Pike's avatar
Rob Pike committed
71 72 73 74 75
	can be used for fine control of formatting.

	If an operand implements method String() string that method
	will be used for %v, %s, or Print etc.
*/
Rob Pike's avatar
Rob Pike committed
76 77
package fmt

Rob Pike's avatar
Rob Pike committed
78

Rob Pike's avatar
Rob Pike committed
79
import (
80 81 82 83 84
	"bytes"
	"io"
	"os"
	"reflect"
	"utf8"
Rob Pike's avatar
Rob Pike committed
85 86
)

87 88 89
// Some constants in the form of bytes, to avoid string overhead.
// Needlessly fastidious, I suppose.
var (
90 91 92 93 94 95 96 97 98
	trueBytes       = []byte{'t', 'r', 'u', 'e'}
	falseBytes      = []byte{'f', 'a', 'l', 's', 'e'}
	commaSpaceBytes = []byte{',', ' '}
	nilAngleBytes   = []byte{'<', 'n', 'i', 'l', '>'}
	nilParenBytes   = []byte{'(', 'n', 'i', 'l', ')'}
	nilBytes        = []byte{'n', 'i', 'l'}
	mapBytes        = []byte{'m', 'a', 'p', '['}
	missingBytes    = []byte{'m', 'i', 's', 's', 'i', 'n', 'g'}
	extraBytes      = []byte{'?', '(', 'e', 'x', 't', 'r', 'a', ' '}
99 100
)

101
// State represents the printer state passed to custom formatters.
102
// It provides access to the io.Writer interface plus information about
Rob Pike's avatar
Rob Pike committed
103
// the flags and options for the operand's format specifier.
104
type State interface {
Rob Pike's avatar
Rob Pike committed
105
	// Write is the function to call to emit formatted output to be printed.
106
	Write(b []byte) (ret int, err os.Error)
Rob Pike's avatar
Rob Pike committed
107
	// Width returns the value of the width option and whether it has been set.
108
	Width() (wid int, ok bool)
Rob Pike's avatar
Rob Pike committed
109
	// Precision returns the value of the precision option and whether it has been set.
110
	Precision() (prec int, ok bool)
111

Rob Pike's avatar
Rob Pike committed
112
	// Flag returns whether the flag c, a character, has been set.
113
	Flag(int) bool
Rob Pike's avatar
Rob Pike committed
114 115
}

Russ Cox's avatar
Russ Cox committed
116
// Formatter is the interface implemented by values with a custom formatter.
Rob Pike's avatar
Rob Pike committed
117 118
// The implementation of Format may call Sprintf or Fprintf(f) etc.
// to generate its output.
119
type Formatter interface {
120
	Format(f State, c int)
121 122
}

Russ Cox's avatar
Russ Cox committed
123 124 125 126
// Stringer is implemented by any value that has a String method(),
// which defines the ``native'' format for that value.
// The String method is used to print values passed as an operand
// to a %s or %v format or to an unformatted printer such as Print.
127
type Stringer interface {
128
	String() string
Rob Pike's avatar
Rob Pike committed
129 130
}

Russ Cox's avatar
Russ Cox committed
131 132 133 134 135
// GoStringer is implemented by any value that has a GoString() method,
// which defines the Go syntax for that value.
// The GoString method is used to print values passed as an operand
// to a %#v format.
type GoStringer interface {
136
	GoString() string
Russ Cox's avatar
Russ Cox committed
137 138
}

Rob Pike's avatar
Rob Pike committed
139 140 141 142 143 144
// getter is implemented by any value that has a Get() method,
// which means the object contains a pointer.  Used by %p.
type getter interface {
	Get() uintptr
}

Rob Pike's avatar
Rob Pike committed
145
const allocSize = 32
Rob Pike's avatar
Rob Pike committed
146

Rob Pike's avatar
Rob Pike committed
147
type pp struct {
148 149 150 151
	n       int
	buf     bytes.Buffer
	runeBuf [utf8.UTFMax]byte
	fmt     fmt
Rob Pike's avatar
Rob Pike committed
152 153
}

154 155 156
// A leaky bucket of reusable pp structures.
var ppFree = make(chan *pp, 100)

157
// Allocate a new pp struct.  Probably can grab the previous one from ppFree.
Rob Pike's avatar
Rob Pike committed
158
func newPrinter() *pp {
159
	p, ok := <-ppFree
160 161 162
	if !ok {
		p = new(pp)
	}
163 164
	p.fmt.init(&p.buf)
	return p
Rob Pike's avatar
Rob Pike committed
165 166
}

167 168 169 170 171 172
// Save used pp structs in ppFree; avoids an allocation per invocation.
func (p *pp) free() {
	// Don't hold on to pp structs with large buffers.
	if cap(p.buf.Bytes()) > 1024 {
		return
	}
173 174
	p.buf.Reset()
	_ = ppFree <- p
175
}
176

177
func (p *pp) Width() (wid int, ok bool) { return p.fmt.wid, p.fmt.widPresent }
Rob Pike's avatar
Rob Pike committed
178

179
func (p *pp) Precision() (prec int, ok bool) { return p.fmt.prec, p.fmt.precPresent }
180

Rob Pike's avatar
Rob Pike committed
181
func (p *pp) Flag(b int) bool {
182 183
	switch b {
	case '-':
184
		return p.fmt.minus
185
	case '+':
186
		return p.fmt.plus
187
	case '#':
188
		return p.fmt.sharp
189
	case ' ':
190
		return p.fmt.space
191
	case '0':
192
		return p.fmt.zero
193
	}
194
	return false
Rob Pike's avatar
Rob Pike committed
195 196
}

Rob Pike's avatar
Rob Pike committed
197
func (p *pp) add(c int) {
198
	if c < utf8.RuneSelf {
199
		p.buf.WriteByte(byte(c))
Rob Pike's avatar
Rob Pike committed
200
	} else {
201 202
		w := utf8.EncodeRune(c, &p.runeBuf)
		p.buf.Write(p.runeBuf[0:w])
Rob Pike's avatar
Rob Pike committed
203 204 205
	}
}

206
// Implement Write so we can call Fprintf on a pp (through State), for
Rob Pike's avatar
Rob Pike committed
207
// recursive use in custom verbs.
208
func (p *pp) Write(b []byte) (ret int, err os.Error) {
209
	return p.buf.Write(b)
Rob Pike's avatar
Rob Pike committed
210 211 212 213
}

// These routines end in 'f' and take a format string.

Rob Pike's avatar
Rob Pike committed
214
// Fprintf formats according to a format specifier and writes to w.
215
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, error os.Error) {
216
	p := newPrinter()
217
	p.doprintf(format, a)
218 219 220
	n64, error := p.buf.WriteTo(w)
	p.free()
	return int(n64), error
Rob Pike's avatar
Rob Pike committed
221 222
}

Rob Pike's avatar
Rob Pike committed
223
// Printf formats according to a format specifier and writes to standard output.
224 225
func Printf(format string, a ...interface{}) (n int, errno os.Error) {
	n, errno = Fprintf(os.Stdout, format, a)
226
	return n, errno
Rob Pike's avatar
Rob Pike committed
227 228
}

Rob Pike's avatar
Rob Pike committed
229
// Sprintf formats according to a format specifier and returns the resulting string.
230
func Sprintf(format string, a ...interface{}) string {
231
	p := newPrinter()
232
	p.doprintf(format, a)
233 234 235
	s := p.buf.String()
	p.free()
	return s
Rob Pike's avatar
Rob Pike committed
236 237
}

Rob Pike's avatar
Rob Pike committed
238
// These routines do not take a format string
Rob Pike's avatar
Rob Pike committed
239

Rob Pike's avatar
Rob Pike committed
240 241
// Fprint formats using the default formats for its operands and writes to w.
// Spaces are added between operands when neither is a string.
242
func Fprint(w io.Writer, a ...interface{}) (n int, error os.Error) {
243
	p := newPrinter()
244
	p.doprint(a, false, false)
245 246 247
	n64, error := p.buf.WriteTo(w)
	p.free()
	return int(n64), error
Rob Pike's avatar
Rob Pike committed
248 249
}

Rob Pike's avatar
Rob Pike committed
250 251
// Print formats using the default formats for its operands and writes to standard output.
// Spaces are added between operands when neither is a string.
252 253
func Print(a ...interface{}) (n int, errno os.Error) {
	n, errno = Fprint(os.Stdout, a)
254
	return n, errno
Rob Pike's avatar
Rob Pike committed
255 256
}

Rob Pike's avatar
Rob Pike committed
257 258
// Sprint formats using the default formats for its operands and returns the resulting string.
// Spaces are added between operands when neither is a string.
259
func Sprint(a ...interface{}) string {
260
	p := newPrinter()
261
	p.doprint(a, false, false)
262 263 264
	s := p.buf.String()
	p.free()
	return s
Rob Pike's avatar
Rob Pike committed
265 266 267 268 269 270
}

// These routines end in 'ln', do not take a format string,
// always add spaces between operands, and add a newline
// after the last operand.

Rob Pike's avatar
Rob Pike committed
271 272
// Fprintln formats using the default formats for its operands and writes to w.
// Spaces are always added between operands and a newline is appended.
273
func Fprintln(w io.Writer, a ...interface{}) (n int, error os.Error) {
274
	p := newPrinter()
275
	p.doprint(a, true, true)
276 277 278
	n64, error := p.buf.WriteTo(w)
	p.free()
	return int(n64), error
Rob Pike's avatar
Rob Pike committed
279 280
}

Rob Pike's avatar
Rob Pike committed
281 282
// Println formats using the default formats for its operands and writes to standard output.
// Spaces are always added between operands and a newline is appended.
283 284
func Println(a ...interface{}) (n int, errno os.Error) {
	n, errno = Fprintln(os.Stdout, a)
285
	return n, errno
Rob Pike's avatar
Rob Pike committed
286 287
}

Rob Pike's avatar
Rob Pike committed
288 289
// Sprintln formats using the default formats for its operands and returns the resulting string.
// Spaces are always added between operands and a newline is appended.
290
func Sprintln(a ...interface{}) string {
291
	p := newPrinter()
292
	p.doprint(a, true, true)
293 294 295
	s := p.buf.String()
	p.free()
	return s
Rob Pike's avatar
Rob Pike committed
296 297
}

298 299 300 301

// Get the i'th arg of the struct value.
// If the arg itself is an interface, return a value for
// the thing inside the interface, not the interface itself.
302
func getField(v *reflect.StructValue, i int) reflect.Value {
303
	val := v.Field(i)
304 305
	if i, ok := val.(*reflect.InterfaceValue); ok {
		if inter := i.Interface(); inter != nil {
306
			return reflect.NewValue(inter)
307
		}
308
	}
309
	return val
310 311
}

Rob Pike's avatar
Rob Pike committed
312 313
// Getters for the fields of the argument structure.

314 315 316 317 318 319 320
func getBool(a interface{}) (val bool, ok bool) {
	// Is it a regular bool type?
	if b, ok := a.(bool); ok {
		return b, true
	}
	// Must be a renamed bool type.
	if b, ok := reflect.NewValue(a).(*reflect.BoolValue); ok {
321
		return b.Get(), true
Rob Pike's avatar
Rob Pike committed
322
	}
323
	return
Rob Pike's avatar
Rob Pike committed
324 325
}

326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
func getInt(a interface{}) (val int64, signed, ok bool) {
	// Is it a predeclared integer type?
	switch i := a.(type) {
	case int:
		return int64(i), true, true
	case int8:
		return int64(i), true, true
	case int16:
		return int64(i), true, true
	case int32:
		return int64(i), true, true
	case int64:
		return i, true, true
	case uint:
		return int64(i), false, true
	case uint8:
		return int64(i), false, true
	case uint16:
		return int64(i), false, true
	case uint32:
		return int64(i), false, true
	case uint64:
		return int64(i), false, true
	case uintptr:
		return int64(i), false, true
	}
	// Must be a renamed integer type.
	switch i := reflect.NewValue(a).(type) {
354
	case *reflect.IntValue:
355
		return int64(i.Get()), true, true
356
	case *reflect.Int8Value:
357
		return int64(i.Get()), true, true
358
	case *reflect.Int16Value:
359
		return int64(i.Get()), true, true
360
	case *reflect.Int32Value:
361
		return int64(i.Get()), true, true
362
	case *reflect.Int64Value:
363
		return i.Get(), true, true
364
	case *reflect.UintValue:
365
		return int64(i.Get()), false, true
366
	case *reflect.Uint8Value:
367
		return int64(i.Get()), false, true
368
	case *reflect.Uint16Value:
369
		return int64(i.Get()), false, true
370
	case *reflect.Uint32Value:
371
		return int64(i.Get()), false, true
372
	case *reflect.Uint64Value:
373
		return int64(i.Get()), false, true
374
	case *reflect.UintptrValue:
375
		return int64(i.Get()), false, true
Rob Pike's avatar
Rob Pike committed
376
	}
377
	return
Rob Pike's avatar
Rob Pike committed
378 379
}

380 381 382 383 384 385 386 387 388 389 390 391
func getString(a interface{}) (val string, ok bool) {
	// Is it a regular string or []byte type?
	switch s := a.(type) {
	case string:
		return s, true
	case []byte:
		return string(s), true
	}
	// Must be a renamed string or []byte type.
	v := reflect.NewValue(a)
	if s, ok := v.(*reflect.StringValue); ok {
		return s.Get(), true
392 393
	}
	if bytes, ok := v.Interface().([]byte); ok {
394
		return string(bytes), true
Rob Pike's avatar
Rob Pike committed
395
	}
396
	return
Rob Pike's avatar
Rob Pike committed
397 398
}

399 400 401 402 403 404 405 406 407 408 409 410 411 412
var floatBits = reflect.Typeof(float(0)).Size() * 8

func getFloat32(a interface{}) (val float32, ok bool) {
	// Is it a regular floating-point type?
	switch f := a.(type) {
	case float32:
		return f, true
	case float:
		if floatBits == 32 {
			return float32(f), true
		}
	}
	// Must be a renamed floating-point type.
	switch f := a.(type) {
413
	case *reflect.Float32Value:
414
		return float32(f.Get()), true
415
	case *reflect.FloatValue:
416 417
		if floatBits == 32 {
			return float32(f.Get()), true
418 419
		}
	}
420
	return
421 422
}

423 424 425 426 427 428 429 430
func getFloat64(a interface{}) (val float64, ok bool) {
	// Is it a regular floating-point type?
	switch f := a.(type) {
	case float64:
		return f, true
	case float:
		if floatBits == 64 {
			return float64(f), true
431
		}
432 433 434
	}
	// Must be a renamed floating-point type.
	switch f := a.(type) {
435
	case *reflect.Float64Value:
436 437 438 439 440
		return float64(f.Get()), true
	case *reflect.FloatValue:
		if floatBits == 64 {
			return float64(f.Get()), true
		}
Rob Pike's avatar
Rob Pike committed
441
	}
442
	return
Rob Pike's avatar
Rob Pike committed
443 444
}

Rob Pike's avatar
Rob Pike committed
445
// Convert ASCII to integer.  n is 0 (and got is false) if no number present.
Rob Pike's avatar
Rob Pike committed
446 447 448

func parsenum(s string, start, end int) (n int, got bool, newi int) {
	if start >= end {
449
		return 0, false, end
Rob Pike's avatar
Rob Pike committed
450
	}
451 452
	isnum := false
	num := 0
Rob Pike's avatar
Rob Pike committed
453
	for '0' <= s[start] && s[start] <= '9' {
454 455 456
		num = num*10 + int(s[start]-'0')
		start++
		isnum = true
Rob Pike's avatar
Rob Pike committed
457
	}
458
	return num, isnum, start
Rob Pike's avatar
Rob Pike committed
459 460
}

Russ Cox's avatar
Russ Cox committed
461
type uintptrGetter interface {
462
	Get() uintptr
Russ Cox's avatar
Russ Cox committed
463 464
}

465 466 467 468 469 470 471 472 473 474 475 476
func (p *pp) unknownType(v interface{}) {
	if v == nil {
		p.buf.Write(nilAngleBytes)
		return
	}
	p.buf.WriteByte('?')
	p.buf.WriteString(reflect.Typeof(v).String())
	p.buf.WriteByte('?')
}

func (p *pp) printField(field interface{}, plus, sharp bool, depth int) (was_string bool) {
	if field != nil {
Russ Cox's avatar
Russ Cox committed
477 478
		switch {
		default:
479
			if stringer, ok := field.(Stringer); ok {
480 481
				p.buf.WriteString(stringer.String())
				return false // this value is not a string
Russ Cox's avatar
Russ Cox committed
482 483
			}
		case sharp:
484
			if stringer, ok := field.(GoStringer); ok {
485 486
				p.buf.WriteString(stringer.GoString())
				return false // this value is not a string
Russ Cox's avatar
Russ Cox committed
487
			}
488
		}
489
	}
490 491

	// Some types can be done without reflection.
492
	switch f := field.(type) {
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538
	case bool:
		p.fmt.fmt_boolean(f)
		return false
	case float32:
		p.fmt.fmt_g32(f)
		return false
	case float64:
		p.fmt.fmt_g64(f)
		return false
	case float:
		if floatBits == 32 {
			p.fmt.fmt_g32(float32(f))
		} else {
			p.fmt.fmt_g64(float64(f))
		}
		return false
	case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr:
		v, signed, ok := getInt(field)
		if !ok {
			// cannot happen, but print something to be sure
			p.unknownType(f)
		} else {
			if signed {
				p.fmt.fmt_d64(v)
			} else {
				if sharp {
					p.fmt.sharp = true // turn on 0x
					p.fmt.fmt_ux64(uint64(v))
				} else {
					p.fmt.fmt_ud64(uint64(v))
				}
			}
		}
		return false
	case string:
		if sharp {
			p.fmt.fmt_q(f)
		} else {
			p.fmt.fmt_s(f)
		}
		return true
	}

	// Need to use reflection
BigSwitch:
	switch f := reflect.NewValue(field).(type) {
539
	case *reflect.BoolValue:
540
		p.fmt.fmt_boolean(f.Get())
541
	case *reflect.Float32Value:
542
		p.fmt.fmt_g32(f.Get())
543
	case *reflect.Float64Value:
544
		p.fmt.fmt_g64(f.Get())
545
	case *reflect.FloatValue:
546
		if floatBits == 32 {
547
			p.fmt.fmt_g32(float32(f.Get()))
548
		} else {
549
			p.fmt.fmt_g64(float64(f.Get()))
550
		}
551
	case *reflect.StringValue:
Russ Cox's avatar
Russ Cox committed
552
		if sharp {
553
			p.fmt.fmt_q(f.Get())
Russ Cox's avatar
Russ Cox committed
554
		} else {
555 556
			p.fmt.fmt_s(f.Get())
			was_string = true
557
		}
Rob Pike's avatar
Rob Pike committed
558
	case *reflect.MapValue:
Russ Cox's avatar
Russ Cox committed
559
		if sharp {
560
			p.buf.WriteString(f.Type().String())
561
			p.buf.WriteByte('{')
Russ Cox's avatar
Russ Cox committed
562
		} else {
563
			p.buf.Write(mapBytes)
Russ Cox's avatar
Russ Cox committed
564
		}
565
		keys := f.Keys()
Rob Pike's avatar
Rob Pike committed
566 567
		for i, key := range keys {
			if i > 0 {
Russ Cox's avatar
Russ Cox committed
568
				if sharp {
569
					p.buf.Write(commaSpaceBytes)
Russ Cox's avatar
Russ Cox committed
570
				} else {
571
					p.buf.WriteByte(' ')
Russ Cox's avatar
Russ Cox committed
572
				}
Rob Pike's avatar
Rob Pike committed
573
			}
574
			p.printField(key.Interface(), plus, sharp, depth+1)
575
			p.buf.WriteByte(':')
576
			p.printField(f.Elem(key).Interface(), plus, sharp, depth+1)
Russ Cox's avatar
Russ Cox committed
577 578
		}
		if sharp {
579
			p.buf.WriteByte('}')
Russ Cox's avatar
Russ Cox committed
580
		} else {
581
			p.buf.WriteByte(']')
Rob Pike's avatar
Rob Pike committed
582
		}
583
	case *reflect.StructValue:
Russ Cox's avatar
Russ Cox committed
584
		if sharp {
585
			p.buf.WriteString(reflect.Typeof(field).String())
Russ Cox's avatar
Russ Cox committed
586
		}
587 588 589 590
		p.add('{')
		v := f
		t := v.Type().(*reflect.StructType)
		p.fmt.clearflags() // clear flags for p.printField
591
		for i := 0; i < v.NumField(); i++ {
592
			if i > 0 {
Russ Cox's avatar
Russ Cox committed
593
				if sharp {
594
					p.buf.Write(commaSpaceBytes)
Russ Cox's avatar
Russ Cox committed
595
				} else {
596
					p.buf.WriteByte(' ')
Russ Cox's avatar
Russ Cox committed
597
				}
598
			}
Russ Cox's avatar
Russ Cox committed
599
			if plus || sharp {
600
				if f := t.Field(i); f.Name != "" {
601 602
					p.buf.WriteString(f.Name)
					p.buf.WriteByte(':')
603 604
				}
			}
605
			p.printField(getField(v, i).Interface(), plus, sharp, depth+1)
606
		}
607
		p.buf.WriteByte('}')
608
	case *reflect.InterfaceValue:
609
		value := f.Elem()
610
		if value == nil {
Russ Cox's avatar
Russ Cox committed
611
			if sharp {
612
				p.buf.WriteString(reflect.Typeof(field).String())
613
				p.buf.Write(nilParenBytes)
Russ Cox's avatar
Russ Cox committed
614
			} else {
615
				p.buf.Write(nilAngleBytes)
Russ Cox's avatar
Russ Cox committed
616
			}
617
		} else {
618
			return p.printField(value.Interface(), plus, sharp, depth+1)
Russ Cox's avatar
Russ Cox committed
619 620 621
		}
	case reflect.ArrayOrSliceValue:
		if sharp {
622
			p.buf.WriteString(reflect.Typeof(field).String())
623
			p.buf.WriteByte('{')
Russ Cox's avatar
Russ Cox committed
624
		} else {
625
			p.buf.WriteByte('[')
Russ Cox's avatar
Russ Cox committed
626 627 628 629
		}
		for i := 0; i < f.Len(); i++ {
			if i > 0 {
				if sharp {
630
					p.buf.Write(commaSpaceBytes)
Russ Cox's avatar
Russ Cox committed
631
				} else {
632
					p.buf.WriteByte(' ')
Russ Cox's avatar
Russ Cox committed
633 634
				}
			}
635
			p.printField(f.Elem(i).Interface(), plus, sharp, depth+1)
Russ Cox's avatar
Russ Cox committed
636 637
		}
		if sharp {
638
			p.buf.WriteByte('}')
Russ Cox's avatar
Russ Cox committed
639
		} else {
640
			p.buf.WriteByte(']')
Russ Cox's avatar
Russ Cox committed
641 642
		}
	case *reflect.PtrValue:
643
		v := f.Get()
Russ Cox's avatar
Russ Cox committed
644 645 646 647 648
		// pointer to array or slice or struct?  ok at top level
		// but not embedded (avoid loops)
		if v != 0 && depth == 0 {
			switch a := f.Elem().(type) {
			case reflect.ArrayOrSliceValue:
649
				p.buf.WriteByte('&')
650
				p.printField(a.Interface(), plus, sharp, depth+1)
651
				break BigSwitch
Russ Cox's avatar
Russ Cox committed
652
			case *reflect.StructValue:
653
				p.buf.WriteByte('&')
654
				p.printField(a.Interface(), plus, sharp, depth+1)
655
				break BigSwitch
Russ Cox's avatar
Russ Cox committed
656 657 658
			}
		}
		if sharp {
659
			p.buf.WriteByte('(')
660
			p.buf.WriteString(reflect.Typeof(field).String())
661 662
			p.buf.WriteByte(')')
			p.buf.WriteByte('(')
Russ Cox's avatar
Russ Cox committed
663
			if v == 0 {
664
				p.buf.Write(nilBytes)
Russ Cox's avatar
Russ Cox committed
665
			} else {
666 667
				p.fmt.sharp = true
				p.fmt.fmt_ux64(uint64(v))
Russ Cox's avatar
Russ Cox committed
668
			}
669 670
			p.buf.WriteByte(')')
			break
Russ Cox's avatar
Russ Cox committed
671 672
		}
		if v == 0 {
673 674
			p.buf.Write(nilAngleBytes)
			break
Russ Cox's avatar
Russ Cox committed
675
		}
676 677
		p.fmt.sharp = true // turn 0x on
		p.fmt.fmt_ux64(uint64(v))
Russ Cox's avatar
Russ Cox committed
678
	case uintptrGetter:
679
		v := f.Get()
Russ Cox's avatar
Russ Cox committed
680
		if sharp {
681
			p.buf.WriteByte('(')
682
			p.buf.WriteString(reflect.Typeof(field).String())
683 684
			p.buf.WriteByte(')')
			p.buf.WriteByte('(')
Russ Cox's avatar
Russ Cox committed
685
			if v == 0 {
686
				p.buf.Write(nilBytes)
Russ Cox's avatar
Russ Cox committed
687
			} else {
688 689
				p.fmt.sharp = true
				p.fmt.fmt_ux64(uint64(v))
Russ Cox's avatar
Russ Cox committed
690
			}
691
			p.buf.WriteByte(')')
Russ Cox's avatar
Russ Cox committed
692
		} else {
693 694
			p.fmt.sharp = true // turn 0x on
			p.fmt.fmt_ux64(uint64(f.Get()))
695
		}
696
	default:
697
		v, signed, ok := getInt(field)
698 699
		if ok {
			if signed {
700
				p.fmt.fmt_d64(v)
701
			} else {
Russ Cox's avatar
Russ Cox committed
702
				if sharp {
703 704
					p.fmt.sharp = true // turn on 0x
					p.fmt.fmt_ux64(uint64(v))
Russ Cox's avatar
Russ Cox committed
705
				} else {
706
					p.fmt.fmt_ud64(uint64(v))
Russ Cox's avatar
Russ Cox committed
707
				}
708
			}
709
			break
710
		}
711
		p.unknownType(f)
712
	}
713
	return false
714 715
}

716
func (p *pp) doprintf(format string, a []interface{}) {
717 718
	end := len(format) - 1
	fieldnum := 0 // we process one field per non-trivial format
719
	for i := 0; i <= end; {
720
		c, w := utf8.DecodeRuneInString(format[i:])
Rob Pike's avatar
Rob Pike committed
721
		if c != '%' || i == end {
722 723 724 725 726
			if w == 1 {
				p.buf.WriteByte(byte(c))
			} else {
				p.buf.WriteString(format[i : i+w])
			}
727 728
			i += w
			continue
Rob Pike's avatar
Rob Pike committed
729
		}
730
		i++
731
		// flags and widths
732 733
		p.fmt.clearflags()
	F: for ; i < end; i++ {
734 735
			switch format[i] {
			case '#':
736
				p.fmt.sharp = true
737
			case '0':
738
				p.fmt.zero = true
739
			case '+':
740
				p.fmt.plus = true
741
			case '-':
742
				p.fmt.minus = true
743
			case ' ':
744
				p.fmt.space = true
745
			default:
746
				break F
747 748 749
			}
		}
		// do we have 20 (width)?
750
		p.fmt.wid, p.fmt.widPresent, i = parsenum(format, i, end)
751
		// do we have .20 (precision)?
Rob Pike's avatar
Rob Pike committed
752
		if i < end && format[i] == '.' {
753
			p.fmt.prec, p.fmt.precPresent, i = parsenum(format, i+1, end)
Rob Pike's avatar
Rob Pike committed
754
		}
755 756
		c, w = utf8.DecodeRuneInString(format[i:])
		i += w
Rob Pike's avatar
Rob Pike committed
757 758
		// percent is special - absorbs no operand
		if c == '%' {
759 760
			p.buf.WriteByte('%') // TODO: should we bother with width & prec?
			continue
Rob Pike's avatar
Rob Pike committed
761
		}
762
		if fieldnum >= len(a) { // out of operands
763 764 765 766
			p.buf.WriteByte('%')
			p.add(c)
			p.buf.Write(missingBytes)
			continue
Rob Pike's avatar
Rob Pike committed
767
		}
768
		field := a[fieldnum]
769
		fieldnum++
Russ Cox's avatar
Russ Cox committed
770 771 772

		// Try formatter except for %T,
		// which is special and handled internally.
773 774
		if field != nil && c != 'T' {
			if formatter, ok := field.(Formatter); ok {
775 776
				formatter.Format(p, c)
				continue
777
			}
Rob Pike's avatar
Rob Pike committed
778
		}
Russ Cox's avatar
Russ Cox committed
779

Rob Pike's avatar
Rob Pike committed
780
		switch c {
Russ Cox's avatar
Russ Cox committed
781 782 783 784
		// bool
		case 't':
			if v, ok := getBool(field); ok {
				if v {
785
					p.buf.Write(trueBytes)
Rob Pike's avatar
Rob Pike committed
786
				} else {
787
					p.buf.Write(falseBytes)
Rob Pike's avatar
Rob Pike committed
788
				}
Russ Cox's avatar
Russ Cox committed
789
			} else {
790
				goto badtype
Russ Cox's avatar
Russ Cox committed
791
			}
Rob Pike's avatar
Rob Pike committed
792

Russ Cox's avatar
Russ Cox committed
793 794
		// int
		case 'b':
Russ Cox's avatar
Russ Cox committed
795
			if v, _, ok := getInt(field); ok {
796
				p.fmt.fmt_b64(uint64(v)) // always unsigned
Russ Cox's avatar
Russ Cox committed
797
			} else if v, ok := getFloat32(field); ok {
798
				p.fmt.fmt_fb32(v)
Russ Cox's avatar
Russ Cox committed
799
			} else if v, ok := getFloat64(field); ok {
800
				p.fmt.fmt_fb64(v)
Russ Cox's avatar
Russ Cox committed
801
			} else {
802
				goto badtype
Russ Cox's avatar
Russ Cox committed
803 804
			}
		case 'c':
Russ Cox's avatar
Russ Cox committed
805
			if v, _, ok := getInt(field); ok {
806
				p.fmt.fmt_c(int(v))
Russ Cox's avatar
Russ Cox committed
807
			} else {
808
				goto badtype
Russ Cox's avatar
Russ Cox committed
809 810 811 812
			}
		case 'd':
			if v, signed, ok := getInt(field); ok {
				if signed {
813
					p.fmt.fmt_d64(v)
Rob Pike's avatar
Rob Pike committed
814
				} else {
815
					p.fmt.fmt_ud64(uint64(v))
Rob Pike's avatar
Rob Pike committed
816
				}
Russ Cox's avatar
Russ Cox committed
817
			} else {
818
				goto badtype
Russ Cox's avatar
Russ Cox committed
819 820 821 822
			}
		case 'o':
			if v, signed, ok := getInt(field); ok {
				if signed {
823
					p.fmt.fmt_o64(v)
Rob Pike's avatar
Rob Pike committed
824
				} else {
825
					p.fmt.fmt_uo64(uint64(v))
Rob Pike's avatar
Rob Pike committed
826
				}
Russ Cox's avatar
Russ Cox committed
827
			} else {
828
				goto badtype
Russ Cox's avatar
Russ Cox committed
829 830 831 832
			}
		case 'x':
			if v, signed, ok := getInt(field); ok {
				if signed {
833
					p.fmt.fmt_x64(v)
834
				} else {
835
					p.fmt.fmt_ux64(uint64(v))
836
				}
Russ Cox's avatar
Russ Cox committed
837
			} else if v, ok := getString(field); ok {
838
				p.fmt.fmt_sx(v)
Russ Cox's avatar
Russ Cox committed
839
			} else {
840
				goto badtype
Russ Cox's avatar
Russ Cox committed
841 842 843 844
			}
		case 'X':
			if v, signed, ok := getInt(field); ok {
				if signed {
845
					p.fmt.fmt_X64(v)
Rob Pike's avatar
Rob Pike committed
846
				} else {
847
					p.fmt.fmt_uX64(uint64(v))
Rob Pike's avatar
Rob Pike committed
848
				}
Russ Cox's avatar
Russ Cox committed
849
			} else if v, ok := getString(field); ok {
850
				p.fmt.fmt_sX(v)
Russ Cox's avatar
Russ Cox committed
851
			} else {
852
				goto badtype
Russ Cox's avatar
Russ Cox committed
853
			}
Rob Pike's avatar
Rob Pike committed
854

Russ Cox's avatar
Russ Cox committed
855 856 857
		// float
		case 'e':
			if v, ok := getFloat32(field); ok {
858
				p.fmt.fmt_e32(v)
Russ Cox's avatar
Russ Cox committed
859
			} else if v, ok := getFloat64(field); ok {
860
				p.fmt.fmt_e64(v)
Russ Cox's avatar
Russ Cox committed
861
			} else {
862
				goto badtype
Russ Cox's avatar
Russ Cox committed
863 864 865
			}
		case 'E':
			if v, ok := getFloat32(field); ok {
866
				p.fmt.fmt_E32(v)
Russ Cox's avatar
Russ Cox committed
867
			} else if v, ok := getFloat64(field); ok {
868
				p.fmt.fmt_E64(v)
Russ Cox's avatar
Russ Cox committed
869
			} else {
870
				goto badtype
Russ Cox's avatar
Russ Cox committed
871 872 873
			}
		case 'f':
			if v, ok := getFloat32(field); ok {
874
				p.fmt.fmt_f32(v)
Russ Cox's avatar
Russ Cox committed
875
			} else if v, ok := getFloat64(field); ok {
876
				p.fmt.fmt_f64(v)
Russ Cox's avatar
Russ Cox committed
877
			} else {
878
				goto badtype
Russ Cox's avatar
Russ Cox committed
879 880 881
			}
		case 'g':
			if v, ok := getFloat32(field); ok {
882
				p.fmt.fmt_g32(v)
Russ Cox's avatar
Russ Cox committed
883
			} else if v, ok := getFloat64(field); ok {
884
				p.fmt.fmt_g64(v)
Russ Cox's avatar
Russ Cox committed
885
			} else {
886
				goto badtype
Russ Cox's avatar
Russ Cox committed
887 888 889
			}
		case 'G':
			if v, ok := getFloat32(field); ok {
890
				p.fmt.fmt_G32(v)
Russ Cox's avatar
Russ Cox committed
891
			} else if v, ok := getFloat64(field); ok {
892
				p.fmt.fmt_G64(v)
Russ Cox's avatar
Russ Cox committed
893
			} else {
894
				goto badtype
Russ Cox's avatar
Russ Cox committed
895
			}
Rob Pike's avatar
Rob Pike committed
896

Russ Cox's avatar
Russ Cox committed
897 898
		// string
		case 's':
899
			if field != nil {
Russ Cox's avatar
Russ Cox committed
900
				// if object implements String, use the result.
901
				if stringer, ok := field.(Stringer); ok {
902 903
					p.fmt.fmt_s(stringer.String())
					break
904
				}
Russ Cox's avatar
Russ Cox committed
905 906
			}
			if v, ok := getString(field); ok {
907
				p.fmt.fmt_s(v)
Russ Cox's avatar
Russ Cox committed
908
			} else {
909
				goto badtype
Russ Cox's avatar
Russ Cox committed
910 911 912
			}
		case 'q':
			if v, ok := getString(field); ok {
913
				p.fmt.fmt_q(v)
Russ Cox's avatar
Russ Cox committed
914
			} else {
915
				goto badtype
Russ Cox's avatar
Russ Cox committed
916
			}
Rob Pike's avatar
Rob Pike committed
917

918
		// pointer, including addresses of reference types.
Russ Cox's avatar
Russ Cox committed
919
		case 'p':
920
			switch v := reflect.NewValue(field).(type) {
Rob Pike's avatar
Rob Pike committed
921
			case getter:
922 923 924
				p.fmt.fmt_s("0x")
				p.fmt.fmt_uX64(uint64(v.Get()))
			default:
925
				goto badtype
Russ Cox's avatar
Russ Cox committed
926
			}
Rob Pike's avatar
Rob Pike committed
927

Russ Cox's avatar
Russ Cox committed
928 929
		// arbitrary value; do your best
		case 'v':
930 931 932 933
			plus, sharp := p.fmt.plus, p.fmt.sharp
			p.fmt.plus = false
			p.fmt.sharp = false
			p.printField(field, plus, sharp, 0)
934

Russ Cox's avatar
Russ Cox committed
935 936
		// the value's type
		case 'T':
937
			p.buf.WriteString(reflect.Typeof(field).String())
938

Russ Cox's avatar
Russ Cox committed
939 940
		default:
		badtype:
941 942 943
			p.buf.WriteByte('%')
			p.add(c)
			p.buf.WriteByte('(')
944
			p.buf.WriteString(reflect.Typeof(field).String())
945 946 947
			p.buf.WriteByte('=')
			p.printField(field, false, false, 0)
			p.buf.WriteByte(')')
Rob Pike's avatar
Rob Pike committed
948 949
		}
	}
950
	if fieldnum < len(a) {
951
		p.buf.Write(extraBytes)
952 953 954
		for ; fieldnum < len(a); fieldnum++ {
			field := a[fieldnum]
			p.buf.WriteString(reflect.Typeof(field).String())
955 956
			p.buf.WriteByte('=')
			p.printField(field, false, false, 0)
957
			if fieldnum+1 < len(a) {
958
				p.buf.Write(commaSpaceBytes)
Rob Pike's avatar
Rob Pike committed
959 960
			}
		}
961
		p.buf.WriteByte(')')
Rob Pike's avatar
Rob Pike committed
962
	}
Rob Pike's avatar
Rob Pike committed
963 964
}

965
func (p *pp) doprint(a []interface{}, addspace, addnewline bool) {
966
	prev_string := false
967
	for fieldnum := 0; fieldnum < len(a); fieldnum++ {
Rob Pike's avatar
Rob Pike committed
968
		// always add spaces if we're doing println
969
		field := a[fieldnum]
Rob Pike's avatar
Rob Pike committed
970
		if fieldnum > 0 {
971
			_, is_string := field.(*reflect.StringValue)
972
			if addspace || !is_string && !prev_string {
973
				p.buf.WriteByte(' ')
Rob Pike's avatar
Rob Pike committed
974 975
			}
		}
976
		prev_string = p.printField(field, false, false, 0)
Rob Pike's avatar
Rob Pike committed
977
	}
Rob Pike's avatar
Rob Pike committed
978
	if addnewline {
979
		p.buf.WriteByte('\n')
Rob Pike's avatar
Rob Pike committed
980 981
	}
}