OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [fmt/] [print.go] - Blame information for rev 747

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.