2008-10-24 17:33:29 -06:00
|
|
|
// 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.
|
|
|
|
|
|
|
|
package fmt
|
|
|
|
|
|
|
|
import (
|
2011-11-01 20:04:37 -06:00
|
|
|
"errors"
|
2009-12-15 16:27:16 -07:00
|
|
|
"io"
|
|
|
|
"os"
|
|
|
|
"reflect"
|
2011-09-29 12:23:06 -06:00
|
|
|
"sync"
|
2011-11-08 16:40:58 -07:00
|
|
|
"unicode/utf8"
|
2008-10-24 17:33:29 -06:00
|
|
|
)
|
|
|
|
|
2016-02-21 08:05:44 -07:00
|
|
|
// Strings for use with buffer.WriteString.
|
|
|
|
// This is less overhead than using buffer.Write with byte arrays.
|
|
|
|
const (
|
|
|
|
commaSpaceString = ", "
|
|
|
|
nilAngleString = "<nil>"
|
|
|
|
nilParenString = "(nil)"
|
|
|
|
nilString = "nil"
|
|
|
|
mapString = "map["
|
|
|
|
percentBangString = "%!"
|
|
|
|
missingString = "(MISSING)"
|
|
|
|
badIndexString = "(BADINDEX)"
|
|
|
|
panicString = "(PANIC="
|
|
|
|
extraString = "%!(EXTRA "
|
|
|
|
bytesString = "[]byte{"
|
|
|
|
badWidthString = "%!(BADWIDTH)"
|
|
|
|
badPrecString = "%!(BADPREC)"
|
|
|
|
noVerbString = "%!(NOVERB)"
|
|
|
|
invReflectString = "<invalid reflect.Value>"
|
2009-12-06 13:03:52 -07:00
|
|
|
)
|
|
|
|
|
2009-06-23 16:20:30 -06:00
|
|
|
// State represents the printer state passed to custom formatters.
|
2009-05-08 12:22:57 -06:00
|
|
|
// It provides access to the io.Writer interface plus information about
|
2009-03-06 04:35:38 -07:00
|
|
|
// the flags and options for the operand's format specifier.
|
2009-06-23 16:20:30 -06:00
|
|
|
type State interface {
|
2009-03-06 04:35:38 -07:00
|
|
|
// Write is the function to call to emit formatted output to be printed.
|
2011-11-01 20:04:37 -06:00
|
|
|
Write(b []byte) (ret int, err error)
|
2009-03-06 04:35:38 -07:00
|
|
|
// Width returns the value of the width option and whether it has been set.
|
2009-12-15 16:27:16 -07:00
|
|
|
Width() (wid int, ok bool)
|
2009-03-06 04:35:38 -07:00
|
|
|
// Precision returns the value of the precision option and whether it has been set.
|
2009-12-15 16:27:16 -07:00
|
|
|
Precision() (prec int, ok bool)
|
2008-12-11 17:53:33 -07:00
|
|
|
|
2013-07-22 19:59:49 -06:00
|
|
|
// Flag reports whether the flag c, a character, has been set.
|
2011-05-18 12:34:19 -06:00
|
|
|
Flag(c int) bool
|
2008-11-06 11:40:57 -07:00
|
|
|
}
|
|
|
|
|
2009-08-31 17:38:30 -06:00
|
|
|
// Formatter is the interface implemented by values with a custom formatter.
|
2013-04-10 15:05:34 -06:00
|
|
|
// The implementation of Format may call Sprint(f) or Fprint(f) etc.
|
2009-03-06 04:35:38 -07:00
|
|
|
// to generate its output.
|
2009-06-23 16:20:30 -06:00
|
|
|
type Formatter interface {
|
2011-10-25 23:21:33 -06:00
|
|
|
Format(f State, c rune)
|
2008-11-06 12:38:44 -07:00
|
|
|
}
|
|
|
|
|
2011-07-17 19:44:27 -06:00
|
|
|
// Stringer is implemented by any value that has a String method,
|
2009-08-31 17:38:30 -06:00
|
|
|
// which defines the ``native'' format for that value.
|
|
|
|
// The String method is used to print values passed as an operand
|
2013-04-10 15:05:34 -06:00
|
|
|
// to any format that accepts a string or to an unformatted printer
|
|
|
|
// such as Print.
|
2009-05-08 12:22:57 -06:00
|
|
|
type Stringer interface {
|
2009-12-15 16:27:16 -07:00
|
|
|
String() string
|
2008-11-06 11:40:57 -07:00
|
|
|
}
|
|
|
|
|
2011-07-17 19:44:27 -06:00
|
|
|
// GoStringer is implemented by any value that has a GoString method,
|
2009-08-31 17:38:30 -06:00
|
|
|
// 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 {
|
2009-12-15 16:27:16 -07:00
|
|
|
GoString() string
|
2009-08-31 17:38:30 -06:00
|
|
|
}
|
|
|
|
|
2012-03-06 21:27:11 -07:00
|
|
|
// Use simple []byte instead of bytes.Buffer to avoid large dependency.
|
|
|
|
type buffer []byte
|
|
|
|
|
2016-02-21 08:05:44 -07:00
|
|
|
func (b *buffer) Write(p []byte) {
|
2012-03-06 21:27:11 -07:00
|
|
|
*b = append(*b, p...)
|
|
|
|
}
|
|
|
|
|
2016-02-21 08:05:44 -07:00
|
|
|
func (b *buffer) WriteString(s string) {
|
2012-03-06 21:27:11 -07:00
|
|
|
*b = append(*b, s...)
|
|
|
|
}
|
|
|
|
|
2016-02-21 08:05:44 -07:00
|
|
|
func (b *buffer) WriteByte(c byte) {
|
2012-03-06 21:27:11 -07:00
|
|
|
*b = append(*b, c)
|
|
|
|
}
|
|
|
|
|
2016-02-21 08:05:44 -07:00
|
|
|
func (bp *buffer) WriteRune(r rune) {
|
2012-03-06 21:27:11 -07:00
|
|
|
if r < utf8.RuneSelf {
|
|
|
|
*bp = append(*bp, byte(r))
|
2016-02-21 08:05:44 -07:00
|
|
|
return
|
2012-03-06 21:27:11 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
b := *bp
|
|
|
|
n := len(b)
|
|
|
|
for n+utf8.UTFMax > cap(b) {
|
|
|
|
b = append(b, 0)
|
|
|
|
}
|
|
|
|
w := utf8.EncodeRune(b[n:n+utf8.UTFMax], r)
|
|
|
|
*bp = b[:n+w]
|
|
|
|
}
|
|
|
|
|
2009-01-15 16:40:27 -07:00
|
|
|
type pp struct {
|
fmt: catch panics from calls to String etc.
This change causes Print et al. to catch panics generated by
calls to String, GoString, and Format. The panic is formatted
into the output stream as an error, but the program continues.
As a special case, if the argument was a nil pointer, the
result is just "<nil>", because that's almost certainly enough
information and handles the very common case of String
methods that don't guard against nil.
Scan does not want this change. Input must work; output can
be for debugging and it's nice to get output even when you
make a mistake.
R=dsymonds, r, adg, gri, rsc, gri
CC=golang-dev
https://golang.org/cl/4640043
2011-06-20 16:31:02 -06:00
|
|
|
n int
|
|
|
|
panicking bool
|
2011-12-14 17:37:54 -07:00
|
|
|
erroring bool // printing an error condition
|
2012-03-06 21:27:11 -07:00
|
|
|
buf buffer
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
// arg holds the current item, as an interface{}.
|
|
|
|
arg interface{}
|
2011-10-18 17:23:07 -06:00
|
|
|
// value holds the current item, as a reflect.Value, and will be
|
|
|
|
// the zero Value if the item has not been reflected.
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
value reflect.Value
|
|
|
|
// reordered records whether the format string used argument reordering.
|
|
|
|
reordered bool
|
2013-09-23 00:03:57 -06:00
|
|
|
// goodArgNum records whether the most recent reordering directive was valid.
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
goodArgNum bool
|
|
|
|
runeBuf [utf8.UTFMax]byte
|
|
|
|
fmt fmt
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
|
|
|
|
2013-12-18 12:09:07 -07:00
|
|
|
var ppFree = sync.Pool{
|
|
|
|
New: func() interface{} { return new(pp) },
|
2011-01-31 16:36:28 -07:00
|
|
|
}
|
2009-12-06 13:03:52 -07:00
|
|
|
|
2014-10-03 14:23:35 -06:00
|
|
|
// newPrinter allocates a new pp struct or grabs a cached one.
|
2011-01-31 16:36:28 -07:00
|
|
|
func newPrinter() *pp {
|
2013-12-18 12:09:07 -07:00
|
|
|
p := ppFree.Get().(*pp)
|
fmt: catch panics from calls to String etc.
This change causes Print et al. to catch panics generated by
calls to String, GoString, and Format. The panic is formatted
into the output stream as an error, but the program continues.
As a special case, if the argument was a nil pointer, the
result is just "<nil>", because that's almost certainly enough
information and handles the very common case of String
methods that don't guard against nil.
Scan does not want this change. Input must work; output can
be for debugging and it's nice to get output even when you
make a mistake.
R=dsymonds, r, adg, gri, rsc, gri
CC=golang-dev
https://golang.org/cl/4640043
2011-06-20 16:31:02 -06:00
|
|
|
p.panicking = false
|
2011-12-14 17:37:54 -07:00
|
|
|
p.erroring = false
|
2009-12-15 16:27:16 -07:00
|
|
|
p.fmt.init(&p.buf)
|
|
|
|
return p
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
|
|
|
|
2013-01-22 15:12:45 -07:00
|
|
|
// free saves used pp structs in ppFree; avoids an allocation per invocation.
|
2009-12-06 16:01:07 -07:00
|
|
|
func (p *pp) free() {
|
|
|
|
// Don't hold on to pp structs with large buffers.
|
2012-03-06 21:27:11 -07:00
|
|
|
if cap(p.buf) > 1024 {
|
2009-12-06 16:01:07 -07:00
|
|
|
return
|
|
|
|
}
|
2012-03-06 21:27:11 -07:00
|
|
|
p.buf = p.buf[:0]
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
p.arg = nil
|
2011-10-18 17:23:07 -06:00
|
|
|
p.value = reflect.Value{}
|
2013-12-18 12:09:07 -07:00
|
|
|
ppFree.Put(p)
|
2009-12-06 16:01:07 -07:00
|
|
|
}
|
2009-12-06 13:03:52 -07:00
|
|
|
|
2009-12-15 16:27:16 -07:00
|
|
|
func (p *pp) Width() (wid int, ok bool) { return p.fmt.wid, p.fmt.widPresent }
|
2008-11-06 11:40:57 -07:00
|
|
|
|
2009-12-15 16:27:16 -07:00
|
|
|
func (p *pp) Precision() (prec int, ok bool) { return p.fmt.prec, p.fmt.precPresent }
|
2008-12-11 17:53:33 -07:00
|
|
|
|
2009-01-15 16:40:27 -07:00
|
|
|
func (p *pp) Flag(b int) bool {
|
2008-12-11 17:53:33 -07:00
|
|
|
switch b {
|
|
|
|
case '-':
|
2009-11-09 13:07:39 -07:00
|
|
|
return p.fmt.minus
|
2008-12-11 17:53:33 -07:00
|
|
|
case '+':
|
2009-11-09 13:07:39 -07:00
|
|
|
return p.fmt.plus
|
2008-12-11 17:53:33 -07:00
|
|
|
case '#':
|
2009-11-09 13:07:39 -07:00
|
|
|
return p.fmt.sharp
|
2008-12-11 17:53:33 -07:00
|
|
|
case ' ':
|
2009-11-09 13:07:39 -07:00
|
|
|
return p.fmt.space
|
2008-12-11 17:53:33 -07:00
|
|
|
case '0':
|
2009-11-09 13:07:39 -07:00
|
|
|
return p.fmt.zero
|
2008-12-11 17:53:33 -07:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
return false
|
2008-11-06 11:40:57 -07:00
|
|
|
}
|
|
|
|
|
2009-12-06 13:03:52 -07:00
|
|
|
// Implement Write so we can call Fprintf on a pp (through State), for
|
2008-11-04 14:57:21 -07:00
|
|
|
// recursive use in custom verbs.
|
2011-11-01 20:04:37 -06:00
|
|
|
func (p *pp) Write(b []byte) (ret int, err error) {
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.Write(b)
|
|
|
|
return len(b), nil
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// These routines end in 'f' and take a format string.
|
|
|
|
|
2009-03-06 04:35:38 -07:00
|
|
|
// Fprintf formats according to a format specifier and writes to w.
|
2010-08-18 20:07:24 -06:00
|
|
|
// It returns the number of bytes written and any write error encountered.
|
2011-11-01 20:04:37 -06:00
|
|
|
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
|
2009-12-15 16:27:16 -07:00
|
|
|
p := newPrinter()
|
2010-06-14 18:16:35 -06:00
|
|
|
p.doPrintf(format, a)
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
n, err = w.Write(p.buf)
|
2009-12-15 16:27:16 -07:00
|
|
|
p.free()
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
return
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
|
|
|
|
2009-03-06 04:35:38 -07:00
|
|
|
// Printf formats according to a format specifier and writes to standard output.
|
2010-08-18 20:07:24 -06:00
|
|
|
// It returns the number of bytes written and any write error encountered.
|
2011-11-01 20:04:37 -06:00
|
|
|
func Printf(format string, a ...interface{}) (n int, err error) {
|
2011-06-28 12:00:31 -06:00
|
|
|
return Fprintf(os.Stdout, format, a...)
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
|
|
|
|
2009-03-06 04:35:38 -07:00
|
|
|
// Sprintf formats according to a format specifier and returns the resulting string.
|
2010-02-01 16:53:37 -07:00
|
|
|
func Sprintf(format string, a ...interface{}) string {
|
2009-12-15 16:27:16 -07:00
|
|
|
p := newPrinter()
|
2010-06-14 18:16:35 -06:00
|
|
|
p.doPrintf(format, a)
|
2012-03-06 21:27:11 -07:00
|
|
|
s := string(p.buf)
|
2009-12-15 16:27:16 -07:00
|
|
|
p.free()
|
|
|
|
return s
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
|
|
|
|
2012-10-30 14:38:01 -06:00
|
|
|
// Errorf formats according to a format specifier and returns the string
|
2011-11-01 20:58:09 -06:00
|
|
|
// as a value that satisfies error.
|
2011-11-01 20:04:37 -06:00
|
|
|
func Errorf(format string, a ...interface{}) error {
|
|
|
|
return errors.New(Sprintf(format, a...))
|
2010-09-30 22:04:55 -06:00
|
|
|
}
|
|
|
|
|
2009-03-06 04:35:38 -07:00
|
|
|
// These routines do not take a format string
|
2008-10-24 17:33:29 -06:00
|
|
|
|
2009-03-06 04:35:38 -07:00
|
|
|
// Fprint formats using the default formats for its operands and writes to w.
|
|
|
|
// Spaces are added between operands when neither is a string.
|
2010-08-18 20:07:24 -06:00
|
|
|
// It returns the number of bytes written and any write error encountered.
|
2011-11-01 20:04:37 -06:00
|
|
|
func Fprint(w io.Writer, a ...interface{}) (n int, err error) {
|
2009-12-15 16:27:16 -07:00
|
|
|
p := newPrinter()
|
2010-06-14 18:16:35 -06:00
|
|
|
p.doPrint(a, false, false)
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
n, err = w.Write(p.buf)
|
2009-12-15 16:27:16 -07:00
|
|
|
p.free()
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
return
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
|
|
|
|
2009-03-06 04:35:38 -07:00
|
|
|
// Print formats using the default formats for its operands and writes to standard output.
|
|
|
|
// Spaces are added between operands when neither is a string.
|
2010-08-18 20:07:24 -06:00
|
|
|
// It returns the number of bytes written and any write error encountered.
|
2011-11-01 20:04:37 -06:00
|
|
|
func Print(a ...interface{}) (n int, err error) {
|
2011-06-28 12:00:31 -06:00
|
|
|
return Fprint(os.Stdout, a...)
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
|
|
|
|
2009-03-06 04:35:38 -07:00
|
|
|
// Sprint formats using the default formats for its operands and returns the resulting string.
|
|
|
|
// Spaces are added between operands when neither is a string.
|
2010-02-01 16:53:37 -07:00
|
|
|
func Sprint(a ...interface{}) string {
|
2009-12-15 16:27:16 -07:00
|
|
|
p := newPrinter()
|
2010-06-14 18:16:35 -06:00
|
|
|
p.doPrint(a, false, false)
|
2012-03-06 21:27:11 -07:00
|
|
|
s := string(p.buf)
|
2009-12-15 16:27:16 -07:00
|
|
|
p.free()
|
|
|
|
return s
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// These routines end in 'ln', do not take a format string,
|
|
|
|
// always add spaces between operands, and add a newline
|
|
|
|
// after the last operand.
|
|
|
|
|
2009-03-06 04:35:38 -07:00
|
|
|
// Fprintln formats using the default formats for its operands and writes to w.
|
|
|
|
// Spaces are always added between operands and a newline is appended.
|
2010-08-18 20:07:24 -06:00
|
|
|
// It returns the number of bytes written and any write error encountered.
|
2011-11-01 20:04:37 -06:00
|
|
|
func Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
|
2009-12-15 16:27:16 -07:00
|
|
|
p := newPrinter()
|
2010-06-14 18:16:35 -06:00
|
|
|
p.doPrint(a, true, true)
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
n, err = w.Write(p.buf)
|
2009-12-15 16:27:16 -07:00
|
|
|
p.free()
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
return
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
|
|
|
|
2009-03-06 04:35:38 -07:00
|
|
|
// 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.
|
2010-08-18 20:07:24 -06:00
|
|
|
// It returns the number of bytes written and any write error encountered.
|
2011-11-01 20:04:37 -06:00
|
|
|
func Println(a ...interface{}) (n int, err error) {
|
2011-06-28 12:00:31 -06:00
|
|
|
return Fprintln(os.Stdout, a...)
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
|
|
|
|
2009-03-06 04:35:38 -07:00
|
|
|
// 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.
|
2010-02-01 16:53:37 -07:00
|
|
|
func Sprintln(a ...interface{}) string {
|
2009-12-15 16:27:16 -07:00
|
|
|
p := newPrinter()
|
2010-06-14 18:16:35 -06:00
|
|
|
p.doPrint(a, true, true)
|
2012-03-06 21:27:11 -07:00
|
|
|
s := string(p.buf)
|
2009-12-15 16:27:16 -07:00
|
|
|
p.free()
|
|
|
|
return s
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
|
|
|
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
// getField gets the i'th field of the struct value.
|
|
|
|
// If the field is itself is an interface, return a value for
|
2008-11-24 15:51:33 -07:00
|
|
|
// the thing inside the interface, not the interface itself.
|
2011-04-08 10:27:58 -06:00
|
|
|
func getField(v reflect.Value, i int) reflect.Value {
|
2009-12-15 16:27:16 -07:00
|
|
|
val := v.Field(i)
|
2011-10-17 16:48:45 -06:00
|
|
|
if val.Kind() == reflect.Interface && !val.IsNil() {
|
|
|
|
val = val.Elem()
|
2008-11-24 15:51:33 -07:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
return val
|
2008-11-24 15:51:33 -07:00
|
|
|
}
|
|
|
|
|
2015-06-24 06:48:35 -06:00
|
|
|
// tooLarge reports whether the magnitude of the integer is
|
|
|
|
// too large to be used as a formatting width or precision.
|
|
|
|
func tooLarge(x int) bool {
|
|
|
|
const max int = 1e6
|
|
|
|
return x > max || x < -max
|
|
|
|
}
|
|
|
|
|
2012-12-25 15:54:24 -07:00
|
|
|
// parsenum converts ASCII to integer. num is 0 (and isnum is false) if no number present.
|
2010-06-14 18:16:35 -06:00
|
|
|
func parsenum(s string, start, end int) (num int, isnum bool, newi int) {
|
|
|
|
if start >= end {
|
|
|
|
return 0, false, end
|
2010-02-01 16:53:37 -07:00
|
|
|
}
|
2010-06-14 18:16:35 -06:00
|
|
|
for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++ {
|
2015-06-24 06:48:35 -06:00
|
|
|
if tooLarge(num) {
|
2015-05-04 12:28:51 -06:00
|
|
|
return 0, false, end // Overflow; crazy long number most likely.
|
|
|
|
}
|
2015-05-05 09:59:18 -06:00
|
|
|
num = num*10 + int(s[newi]-'0')
|
2010-06-14 18:16:35 -06:00
|
|
|
isnum = true
|
2008-11-06 11:40:57 -07:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
return
|
2008-11-06 11:40:57 -07:00
|
|
|
}
|
|
|
|
|
2014-10-01 15:35:12 -06:00
|
|
|
func (p *pp) unknownType(v reflect.Value) {
|
|
|
|
if !v.IsValid() {
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(nilAngleString)
|
2010-06-14 18:16:35 -06:00
|
|
|
return
|
2010-02-01 16:53:37 -07:00
|
|
|
}
|
2010-06-14 18:16:35 -06:00
|
|
|
p.buf.WriteByte('?')
|
2014-10-01 15:35:12 -06:00
|
|
|
p.buf.WriteString(v.Type().String())
|
2010-06-14 18:16:35 -06:00
|
|
|
p.buf.WriteByte('?')
|
|
|
|
}
|
|
|
|
|
2011-10-25 23:21:33 -06:00
|
|
|
func (p *pp) badVerb(verb rune) {
|
2011-12-14 17:37:54 -07:00
|
|
|
p.erroring = true
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(percentBangString)
|
|
|
|
p.buf.WriteRune(verb)
|
|
|
|
p.buf.WriteByte('(')
|
2011-10-17 16:48:45 -06:00
|
|
|
switch {
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
case p.arg != nil:
|
|
|
|
p.buf.WriteString(reflect.TypeOf(p.arg).String())
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteByte('=')
|
2014-10-03 14:23:35 -06:00
|
|
|
p.printArg(p.arg, 'v', 0)
|
2011-10-18 17:23:07 -06:00
|
|
|
case p.value.IsValid():
|
|
|
|
p.buf.WriteString(p.value.Type().String())
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteByte('=')
|
2014-10-03 14:23:35 -06:00
|
|
|
p.printValue(p.value, 'v', 0)
|
2011-10-17 16:48:45 -06:00
|
|
|
default:
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(nilAngleString)
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteByte(')')
|
2011-12-14 17:37:54 -07:00
|
|
|
p.erroring = false
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
|
|
|
|
2011-10-25 23:21:33 -06:00
|
|
|
func (p *pp) fmtBool(v bool, verb rune) {
|
2010-06-14 18:16:35 -06:00
|
|
|
switch verb {
|
|
|
|
case 't', 'v':
|
|
|
|
p.fmt.fmt_boolean(v)
|
|
|
|
default:
|
2011-10-21 14:59:27 -06:00
|
|
|
p.badVerb(verb)
|
2010-02-04 17:23:25 -07:00
|
|
|
}
|
2010-06-14 18:16:35 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// fmtC formats a rune for the 'c' format.
|
|
|
|
func (p *pp) fmtC(c int64) {
|
2011-10-25 23:21:33 -06:00
|
|
|
r := rune(c) // Check for overflow.
|
|
|
|
if int64(r) != c {
|
|
|
|
r = utf8.RuneError
|
2010-02-01 16:53:37 -07:00
|
|
|
}
|
2011-10-25 23:21:33 -06:00
|
|
|
w := utf8.EncodeRune(p.runeBuf[0:utf8.UTFMax], r)
|
2010-06-14 18:16:35 -06:00
|
|
|
p.fmt.pad(p.runeBuf[0:w])
|
|
|
|
}
|
|
|
|
|
2011-10-25 23:21:33 -06:00
|
|
|
func (p *pp) fmtInt64(v int64, verb rune) {
|
2010-06-14 18:16:35 -06:00
|
|
|
switch verb {
|
|
|
|
case 'b':
|
|
|
|
p.fmt.integer(v, 2, signed, ldigits)
|
|
|
|
case 'c':
|
|
|
|
p.fmtC(v)
|
|
|
|
case 'd', 'v':
|
|
|
|
p.fmt.integer(v, 10, signed, ldigits)
|
|
|
|
case 'o':
|
|
|
|
p.fmt.integer(v, 8, signed, ldigits)
|
2011-05-25 05:25:15 -06:00
|
|
|
case 'q':
|
2012-03-06 21:27:11 -07:00
|
|
|
if 0 <= v && v <= utf8.MaxRune {
|
2011-05-25 05:25:15 -06:00
|
|
|
p.fmt.fmt_qc(v)
|
|
|
|
} else {
|
2011-10-21 14:59:27 -06:00
|
|
|
p.badVerb(verb)
|
2011-05-25 05:25:15 -06:00
|
|
|
}
|
2010-06-14 18:16:35 -06:00
|
|
|
case 'x':
|
|
|
|
p.fmt.integer(v, 16, signed, ldigits)
|
2010-12-06 12:23:37 -07:00
|
|
|
case 'U':
|
|
|
|
p.fmtUnicode(v)
|
2010-06-14 18:16:35 -06:00
|
|
|
case 'X':
|
|
|
|
p.fmt.integer(v, 16, signed, udigits)
|
|
|
|
default:
|
2011-10-21 14:59:27 -06:00
|
|
|
p.badVerb(verb)
|
2009-07-07 12:03:31 -06:00
|
|
|
}
|
2010-06-14 18:16:35 -06:00
|
|
|
}
|
|
|
|
|
2011-03-01 14:25:52 -07:00
|
|
|
// fmt0x64 formats a uint64 in hexadecimal and prefixes it with 0x or
|
|
|
|
// not, as requested, by temporarily setting the sharp flag.
|
|
|
|
func (p *pp) fmt0x64(v uint64, leading0x bool) {
|
2010-06-14 18:16:35 -06:00
|
|
|
sharp := p.fmt.sharp
|
2011-03-01 14:25:52 -07:00
|
|
|
p.fmt.sharp = leading0x
|
2010-06-14 18:16:35 -06:00
|
|
|
p.fmt.integer(int64(v), 16, unsigned, ldigits)
|
|
|
|
p.fmt.sharp = sharp
|
|
|
|
}
|
|
|
|
|
2010-12-06 12:23:37 -07:00
|
|
|
// fmtUnicode formats a uint64 in U+1234 form by
|
|
|
|
// temporarily turning on the unicode flag and tweaking the precision.
|
|
|
|
func (p *pp) fmtUnicode(v int64) {
|
|
|
|
precPresent := p.fmt.precPresent
|
2011-06-10 18:03:02 -06:00
|
|
|
sharp := p.fmt.sharp
|
|
|
|
p.fmt.sharp = false
|
2010-12-06 12:23:37 -07:00
|
|
|
prec := p.fmt.prec
|
|
|
|
if !precPresent {
|
|
|
|
// If prec is already set, leave it alone; otherwise 4 is minimum.
|
|
|
|
p.fmt.prec = 4
|
|
|
|
p.fmt.precPresent = true
|
|
|
|
}
|
|
|
|
p.fmt.unicode = true // turn on U+
|
2011-06-10 18:03:02 -06:00
|
|
|
p.fmt.uniQuote = sharp
|
2010-12-06 12:23:37 -07:00
|
|
|
p.fmt.integer(int64(v), 16, unsigned, udigits)
|
|
|
|
p.fmt.unicode = false
|
2011-06-10 18:03:02 -06:00
|
|
|
p.fmt.uniQuote = false
|
2010-12-06 12:23:37 -07:00
|
|
|
p.fmt.prec = prec
|
|
|
|
p.fmt.precPresent = precPresent
|
2011-06-10 18:03:02 -06:00
|
|
|
p.fmt.sharp = sharp
|
2010-12-06 12:23:37 -07:00
|
|
|
}
|
|
|
|
|
2014-10-02 15:16:58 -06:00
|
|
|
func (p *pp) fmtUint64(v uint64, verb rune) {
|
2010-06-14 18:16:35 -06:00
|
|
|
switch verb {
|
|
|
|
case 'b':
|
|
|
|
p.fmt.integer(int64(v), 2, unsigned, ldigits)
|
|
|
|
case 'c':
|
|
|
|
p.fmtC(int64(v))
|
|
|
|
case 'd':
|
|
|
|
p.fmt.integer(int64(v), 10, unsigned, ldigits)
|
|
|
|
case 'v':
|
2014-10-02 15:16:58 -06:00
|
|
|
if p.fmt.sharpV {
|
2011-03-01 14:25:52 -07:00
|
|
|
p.fmt0x64(v, true)
|
2010-06-14 18:16:35 -06:00
|
|
|
} else {
|
|
|
|
p.fmt.integer(int64(v), 10, unsigned, ldigits)
|
|
|
|
}
|
|
|
|
case 'o':
|
|
|
|
p.fmt.integer(int64(v), 8, unsigned, ldigits)
|
2011-05-25 05:25:15 -06:00
|
|
|
case 'q':
|
2012-03-06 21:27:11 -07:00
|
|
|
if 0 <= v && v <= utf8.MaxRune {
|
2011-05-25 05:25:15 -06:00
|
|
|
p.fmt.fmt_qc(int64(v))
|
|
|
|
} else {
|
2011-10-21 14:59:27 -06:00
|
|
|
p.badVerb(verb)
|
2011-05-25 05:25:15 -06:00
|
|
|
}
|
2010-06-14 18:16:35 -06:00
|
|
|
case 'x':
|
|
|
|
p.fmt.integer(int64(v), 16, unsigned, ldigits)
|
|
|
|
case 'X':
|
|
|
|
p.fmt.integer(int64(v), 16, unsigned, udigits)
|
2011-04-12 12:03:05 -06:00
|
|
|
case 'U':
|
|
|
|
p.fmtUnicode(int64(v))
|
2010-06-14 18:16:35 -06:00
|
|
|
default:
|
2011-10-21 14:59:27 -06:00
|
|
|
p.badVerb(verb)
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-25 23:21:33 -06:00
|
|
|
func (p *pp) fmtFloat32(v float32, verb rune) {
|
2010-06-14 18:16:35 -06:00
|
|
|
switch verb {
|
|
|
|
case 'b':
|
|
|
|
p.fmt.fmt_fb32(v)
|
|
|
|
case 'e':
|
|
|
|
p.fmt.fmt_e32(v)
|
|
|
|
case 'E':
|
|
|
|
p.fmt.fmt_E32(v)
|
2014-03-19 15:51:06 -06:00
|
|
|
case 'f', 'F':
|
2010-06-14 18:16:35 -06:00
|
|
|
p.fmt.fmt_f32(v)
|
|
|
|
case 'g', 'v':
|
|
|
|
p.fmt.fmt_g32(v)
|
|
|
|
case 'G':
|
|
|
|
p.fmt.fmt_G32(v)
|
|
|
|
default:
|
2011-10-21 14:59:27 -06:00
|
|
|
p.badVerb(verb)
|
2008-11-17 13:34:03 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-25 23:21:33 -06:00
|
|
|
func (p *pp) fmtFloat64(v float64, verb rune) {
|
2010-06-14 18:16:35 -06:00
|
|
|
switch verb {
|
|
|
|
case 'b':
|
|
|
|
p.fmt.fmt_fb64(v)
|
|
|
|
case 'e':
|
|
|
|
p.fmt.fmt_e64(v)
|
|
|
|
case 'E':
|
|
|
|
p.fmt.fmt_E64(v)
|
2014-03-19 15:51:06 -06:00
|
|
|
case 'f', 'F':
|
2010-06-14 18:16:35 -06:00
|
|
|
p.fmt.fmt_f64(v)
|
|
|
|
case 'g', 'v':
|
|
|
|
p.fmt.fmt_g64(v)
|
|
|
|
case 'G':
|
|
|
|
p.fmt.fmt_G64(v)
|
|
|
|
default:
|
2011-10-21 14:59:27 -06:00
|
|
|
p.badVerb(verb)
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-25 23:21:33 -06:00
|
|
|
func (p *pp) fmtComplex64(v complex64, verb rune) {
|
2010-06-14 18:16:35 -06:00
|
|
|
switch verb {
|
2013-09-14 18:45:36 -06:00
|
|
|
case 'b', 'e', 'E', 'f', 'F', 'g', 'G':
|
2010-06-14 18:16:35 -06:00
|
|
|
p.fmt.fmt_c64(v, verb)
|
|
|
|
case 'v':
|
|
|
|
p.fmt.fmt_c64(v, 'g')
|
|
|
|
default:
|
2011-10-21 14:59:27 -06:00
|
|
|
p.badVerb(verb)
|
2010-03-05 21:16:04 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-25 23:21:33 -06:00
|
|
|
func (p *pp) fmtComplex128(v complex128, verb rune) {
|
2010-06-14 18:16:35 -06:00
|
|
|
switch verb {
|
2013-09-14 18:45:36 -06:00
|
|
|
case 'b', 'e', 'E', 'f', 'F', 'g', 'G':
|
2010-06-14 18:16:35 -06:00
|
|
|
p.fmt.fmt_c128(v, verb)
|
|
|
|
case 'v':
|
|
|
|
p.fmt.fmt_c128(v, 'g')
|
|
|
|
default:
|
2011-10-21 14:59:27 -06:00
|
|
|
p.badVerb(verb)
|
2010-03-05 21:16:04 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-02 15:16:58 -06:00
|
|
|
func (p *pp) fmtString(v string, verb rune) {
|
2010-06-14 18:16:35 -06:00
|
|
|
switch verb {
|
|
|
|
case 'v':
|
2014-10-02 15:16:58 -06:00
|
|
|
if p.fmt.sharpV {
|
2010-06-14 18:16:35 -06:00
|
|
|
p.fmt.fmt_q(v)
|
|
|
|
} else {
|
|
|
|
p.fmt.fmt_s(v)
|
|
|
|
}
|
|
|
|
case 's':
|
|
|
|
p.fmt.fmt_s(v)
|
|
|
|
case 'x':
|
2011-12-15 13:52:29 -07:00
|
|
|
p.fmt.fmt_sx(v, ldigits)
|
2010-06-14 18:16:35 -06:00
|
|
|
case 'X':
|
2011-12-15 13:52:29 -07:00
|
|
|
p.fmt.fmt_sx(v, udigits)
|
2010-06-14 18:16:35 -06:00
|
|
|
case 'q':
|
|
|
|
p.fmt.fmt_q(v)
|
|
|
|
default:
|
2011-10-21 14:59:27 -06:00
|
|
|
p.badVerb(verb)
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-02 15:16:58 -06:00
|
|
|
func (p *pp) fmtBytes(v []byte, verb rune, typ reflect.Type, depth int) {
|
2010-10-04 03:57:48 -06:00
|
|
|
if verb == 'v' || verb == 'd' {
|
2014-10-02 15:16:58 -06:00
|
|
|
if p.fmt.sharpV {
|
2014-04-03 14:11:03 -06:00
|
|
|
if v == nil {
|
|
|
|
if typ == nil {
|
|
|
|
p.buf.WriteString("[]byte(nil)")
|
|
|
|
} else {
|
|
|
|
p.buf.WriteString(typ.String())
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(nilParenString)
|
2014-04-03 14:11:03 -06:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
2013-01-30 18:53:53 -07:00
|
|
|
if typ == nil {
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(bytesString)
|
2013-01-30 18:53:53 -07:00
|
|
|
} else {
|
|
|
|
p.buf.WriteString(typ.String())
|
|
|
|
p.buf.WriteByte('{')
|
|
|
|
}
|
2010-06-14 18:16:35 -06:00
|
|
|
} else {
|
|
|
|
p.buf.WriteByte('[')
|
|
|
|
}
|
|
|
|
for i, c := range v {
|
|
|
|
if i > 0 {
|
2014-10-02 15:16:58 -06:00
|
|
|
if p.fmt.sharpV {
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(commaSpaceString)
|
2010-06-14 18:16:35 -06:00
|
|
|
} else {
|
|
|
|
p.buf.WriteByte(' ')
|
|
|
|
}
|
|
|
|
}
|
2014-10-03 14:23:35 -06:00
|
|
|
p.printArg(c, 'v', depth+1)
|
2010-06-14 18:16:35 -06:00
|
|
|
}
|
2014-10-02 15:16:58 -06:00
|
|
|
if p.fmt.sharpV {
|
2010-06-14 18:16:35 -06:00
|
|
|
p.buf.WriteByte('}')
|
|
|
|
} else {
|
|
|
|
p.buf.WriteByte(']')
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
switch verb {
|
|
|
|
case 's':
|
2012-09-26 14:21:38 -06:00
|
|
|
p.fmt.fmt_s(string(v))
|
2010-06-14 18:16:35 -06:00
|
|
|
case 'x':
|
2012-09-26 14:21:38 -06:00
|
|
|
p.fmt.fmt_bx(v, ldigits)
|
2010-06-14 18:16:35 -06:00
|
|
|
case 'X':
|
2012-09-26 14:21:38 -06:00
|
|
|
p.fmt.fmt_bx(v, udigits)
|
2010-06-14 18:16:35 -06:00
|
|
|
case 'q':
|
2012-09-26 14:21:38 -06:00
|
|
|
p.fmt.fmt_q(string(v))
|
2010-06-14 18:16:35 -06:00
|
|
|
default:
|
2011-10-21 14:59:27 -06:00
|
|
|
p.badVerb(verb)
|
2010-06-14 18:16:35 -06:00
|
|
|
}
|
2009-08-31 17:38:30 -06:00
|
|
|
}
|
|
|
|
|
2014-10-02 15:16:58 -06:00
|
|
|
func (p *pp) fmtPointer(value reflect.Value, verb rune) {
|
2012-08-17 17:12:25 -06:00
|
|
|
use0x64 := true
|
2012-02-07 21:37:05 -07:00
|
|
|
switch verb {
|
2012-08-17 17:12:25 -06:00
|
|
|
case 'p', 'v':
|
|
|
|
// ok
|
|
|
|
case 'b', 'd', 'o', 'x', 'X':
|
|
|
|
use0x64 = false
|
2012-02-07 21:37:05 -07:00
|
|
|
// ok
|
|
|
|
default:
|
|
|
|
p.badVerb(verb)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2011-03-30 20:12:30 -06:00
|
|
|
var u uintptr
|
2011-04-08 10:27:58 -06:00
|
|
|
switch value.Kind() {
|
|
|
|
case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
|
|
|
|
u = value.Pointer()
|
2011-03-30 20:12:30 -06:00
|
|
|
default:
|
2011-10-21 14:59:27 -06:00
|
|
|
p.badVerb(verb)
|
2010-08-13 15:37:03 -06:00
|
|
|
return
|
2010-02-01 16:53:37 -07:00
|
|
|
}
|
2012-02-07 21:37:05 -07:00
|
|
|
|
2014-10-02 15:16:58 -06:00
|
|
|
if p.fmt.sharpV {
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteByte('(')
|
2011-10-17 16:48:45 -06:00
|
|
|
p.buf.WriteString(value.Type().String())
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(")(")
|
2010-06-14 18:16:35 -06:00
|
|
|
if u == 0 {
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(nilString)
|
2010-06-14 18:16:35 -06:00
|
|
|
} else {
|
2011-03-30 20:12:30 -06:00
|
|
|
p.fmt0x64(uint64(u), true)
|
2010-06-14 18:16:35 -06:00
|
|
|
}
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteByte(')')
|
2012-02-07 21:37:05 -07:00
|
|
|
} else if verb == 'v' && u == 0 {
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(nilAngleString)
|
2010-06-14 18:16:35 -06:00
|
|
|
} else {
|
2012-08-17 17:12:25 -06:00
|
|
|
if use0x64 {
|
|
|
|
p.fmt0x64(uint64(u), !p.fmt.sharp)
|
|
|
|
} else {
|
2014-10-02 15:16:58 -06:00
|
|
|
p.fmtUint64(uint64(u), verb)
|
2012-08-17 17:12:25 -06:00
|
|
|
}
|
2010-06-14 18:16:35 -06:00
|
|
|
}
|
2010-02-01 16:53:37 -07:00
|
|
|
}
|
|
|
|
|
2010-06-20 13:16:25 -06:00
|
|
|
var (
|
2011-04-25 11:39:36 -06:00
|
|
|
intBits = reflect.TypeOf(0).Bits()
|
|
|
|
uintptrBits = reflect.TypeOf(uintptr(0)).Bits()
|
2010-06-20 13:16:25 -06:00
|
|
|
)
|
|
|
|
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
func (p *pp) catchPanic(arg interface{}, verb rune) {
|
fmt: catch panics from calls to String etc.
This change causes Print et al. to catch panics generated by
calls to String, GoString, and Format. The panic is formatted
into the output stream as an error, but the program continues.
As a special case, if the argument was a nil pointer, the
result is just "<nil>", because that's almost certainly enough
information and handles the very common case of String
methods that don't guard against nil.
Scan does not want this change. Input must work; output can
be for debugging and it's nice to get output even when you
make a mistake.
R=dsymonds, r, adg, gri, rsc, gri
CC=golang-dev
https://golang.org/cl/4640043
2011-06-20 16:31:02 -06:00
|
|
|
if err := recover(); err != nil {
|
|
|
|
// If it's a nil pointer, just say "<nil>". The likeliest causes are a
|
|
|
|
// Stringer that fails to guard against nil or a nil pointer for a
|
|
|
|
// value receiver, and in either case, "<nil>" is a nice result.
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
if v := reflect.ValueOf(arg); v.Kind() == reflect.Ptr && v.IsNil() {
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(nilAngleString)
|
fmt: catch panics from calls to String etc.
This change causes Print et al. to catch panics generated by
calls to String, GoString, and Format. The panic is formatted
into the output stream as an error, but the program continues.
As a special case, if the argument was a nil pointer, the
result is just "<nil>", because that's almost certainly enough
information and handles the very common case of String
methods that don't guard against nil.
Scan does not want this change. Input must work; output can
be for debugging and it's nice to get output even when you
make a mistake.
R=dsymonds, r, adg, gri, rsc, gri
CC=golang-dev
https://golang.org/cl/4640043
2011-06-20 16:31:02 -06:00
|
|
|
return
|
|
|
|
}
|
|
|
|
// Otherwise print a concise panic message. Most of the time the panic
|
|
|
|
// value will print itself nicely.
|
|
|
|
if p.panicking {
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
// Nested panics; the recursion in printArg cannot succeed.
|
fmt: catch panics from calls to String etc.
This change causes Print et al. to catch panics generated by
calls to String, GoString, and Format. The panic is formatted
into the output stream as an error, but the program continues.
As a special case, if the argument was a nil pointer, the
result is just "<nil>", because that's almost certainly enough
information and handles the very common case of String
methods that don't guard against nil.
Scan does not want this change. Input must work; output can
be for debugging and it's nice to get output even when you
make a mistake.
R=dsymonds, r, adg, gri, rsc, gri
CC=golang-dev
https://golang.org/cl/4640043
2011-06-20 16:31:02 -06:00
|
|
|
panic(err)
|
|
|
|
}
|
2014-10-02 15:16:58 -06:00
|
|
|
p.fmt.clearflags() // We are done, and for this output we want default behavior.
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(percentBangString)
|
|
|
|
p.buf.WriteRune(verb)
|
|
|
|
p.buf.WriteString(panicString)
|
fmt: catch panics from calls to String etc.
This change causes Print et al. to catch panics generated by
calls to String, GoString, and Format. The panic is formatted
into the output stream as an error, but the program continues.
As a special case, if the argument was a nil pointer, the
result is just "<nil>", because that's almost certainly enough
information and handles the very common case of String
methods that don't guard against nil.
Scan does not want this change. Input must work; output can
be for debugging and it's nice to get output even when you
make a mistake.
R=dsymonds, r, adg, gri, rsc, gri
CC=golang-dev
https://golang.org/cl/4640043
2011-06-20 16:31:02 -06:00
|
|
|
p.panicking = true
|
2014-10-03 14:23:35 -06:00
|
|
|
p.printArg(err, 'v', 0)
|
fmt: catch panics from calls to String etc.
This change causes Print et al. to catch panics generated by
calls to String, GoString, and Format. The panic is formatted
into the output stream as an error, but the program continues.
As a special case, if the argument was a nil pointer, the
result is just "<nil>", because that's almost certainly enough
information and handles the very common case of String
methods that don't guard against nil.
Scan does not want this change. Input must work; output can
be for debugging and it's nice to get output even when you
make a mistake.
R=dsymonds, r, adg, gri, rsc, gri
CC=golang-dev
https://golang.org/cl/4640043
2011-06-20 16:31:02 -06:00
|
|
|
p.panicking = false
|
|
|
|
p.buf.WriteByte(')')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-02 15:16:58 -06:00
|
|
|
// clearSpecialFlags pushes %#v back into the regular flags and returns their old state.
|
2014-10-03 14:23:35 -06:00
|
|
|
func (p *pp) clearSpecialFlags() (plusV, sharpV bool) {
|
|
|
|
plusV = p.fmt.plusV
|
|
|
|
if plusV {
|
|
|
|
p.fmt.plus = true
|
|
|
|
p.fmt.plusV = false
|
|
|
|
}
|
|
|
|
sharpV = p.fmt.sharpV
|
|
|
|
if sharpV {
|
2014-10-02 15:16:58 -06:00
|
|
|
p.fmt.sharp = true
|
|
|
|
p.fmt.sharpV = false
|
|
|
|
}
|
2014-10-03 14:23:35 -06:00
|
|
|
return
|
2014-10-02 15:16:58 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// restoreSpecialFlags, whose argument should be a call to clearSpecialFlags,
|
2014-10-03 14:23:35 -06:00
|
|
|
// restores the setting of the plusV and sharpV flags.
|
|
|
|
func (p *pp) restoreSpecialFlags(plusV, sharpV bool) {
|
|
|
|
if plusV {
|
|
|
|
p.fmt.plus = false
|
|
|
|
p.fmt.plusV = true
|
|
|
|
}
|
2014-10-02 15:16:58 -06:00
|
|
|
if sharpV {
|
|
|
|
p.fmt.sharp = false
|
|
|
|
p.fmt.sharpV = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-03 14:23:35 -06:00
|
|
|
func (p *pp) handleMethods(verb rune, depth int) (handled bool) {
|
2011-12-14 17:37:54 -07:00
|
|
|
if p.erroring {
|
|
|
|
return
|
|
|
|
}
|
2010-08-13 01:26:32 -06:00
|
|
|
// Is it a Formatter?
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
if formatter, ok := p.arg.(Formatter); ok {
|
2011-10-17 16:48:45 -06:00
|
|
|
handled = true
|
2014-10-02 15:16:58 -06:00
|
|
|
defer p.restoreSpecialFlags(p.clearSpecialFlags())
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
defer p.catchPanic(p.arg, verb)
|
2010-08-13 01:26:32 -06:00
|
|
|
formatter.Format(p, verb)
|
2011-10-17 16:48:45 -06:00
|
|
|
return
|
2010-08-13 01:26:32 -06:00
|
|
|
}
|
2011-10-17 16:48:45 -06:00
|
|
|
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
// If we're doing Go syntax and the argument knows how to supply it, take care of it now.
|
2014-10-02 15:16:58 -06:00
|
|
|
if p.fmt.sharpV {
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
if stringer, ok := p.arg.(GoStringer); ok {
|
2011-10-17 16:48:45 -06:00
|
|
|
handled = true
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
defer p.catchPanic(p.arg, verb)
|
2010-08-13 01:26:32 -06:00
|
|
|
// Print the result of GoString unadorned.
|
2014-10-03 14:23:35 -06:00
|
|
|
p.fmt.fmt_s(stringer.GoString())
|
2011-10-17 16:48:45 -06:00
|
|
|
return
|
2010-08-13 01:26:32 -06:00
|
|
|
}
|
|
|
|
} else {
|
2011-12-05 17:45:51 -07:00
|
|
|
// If a string is acceptable according to the format, see if
|
|
|
|
// the value satisfies one of the string-valued interfaces.
|
|
|
|
// Println etc. set verb to %v, which is "stringable".
|
|
|
|
switch verb {
|
|
|
|
case 'v', 's', 'x', 'X', 'q':
|
|
|
|
// Is it an error or Stringer?
|
|
|
|
// The duplication in the bodies is necessary:
|
2014-10-02 15:16:58 -06:00
|
|
|
// setting handled and deferring catchPanic
|
2011-12-05 17:45:51 -07:00
|
|
|
// must happen before calling the method.
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
switch v := p.arg.(type) {
|
2011-12-05 17:45:51 -07:00
|
|
|
case error:
|
|
|
|
handled = true
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
defer p.catchPanic(p.arg, verb)
|
2014-10-03 14:23:35 -06:00
|
|
|
p.printArg(v.Error(), verb, depth)
|
2011-12-05 17:45:51 -07:00
|
|
|
return
|
|
|
|
|
|
|
|
case Stringer:
|
|
|
|
handled = true
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
defer p.catchPanic(p.arg, verb)
|
2014-10-03 14:23:35 -06:00
|
|
|
p.printArg(v.String(), verb, depth)
|
2011-12-05 17:45:51 -07:00
|
|
|
return
|
|
|
|
}
|
2011-10-17 16:48:45 -06:00
|
|
|
}
|
|
|
|
}
|
2014-10-02 15:16:58 -06:00
|
|
|
return false
|
2011-10-17 16:48:45 -06:00
|
|
|
}
|
|
|
|
|
2014-10-03 14:23:35 -06:00
|
|
|
func (p *pp) printArg(arg interface{}, verb rune, depth int) (wasString bool) {
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
p.arg = arg
|
2012-06-25 17:48:20 -06:00
|
|
|
p.value = reflect.Value{}
|
|
|
|
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
if arg == nil {
|
2011-10-17 16:48:45 -06:00
|
|
|
if verb == 'T' || verb == 'v' {
|
2016-02-21 08:05:44 -07:00
|
|
|
p.fmt.padString(nilAngleString)
|
2011-10-17 16:48:45 -06:00
|
|
|
} else {
|
2011-10-21 14:59:27 -06:00
|
|
|
p.badVerb(verb)
|
2008-12-11 13:59:49 -07:00
|
|
|
}
|
2011-10-17 16:48:45 -06:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// Special processing considerations.
|
|
|
|
// %T (the value's type) and %p (its address) are special; we always do them first.
|
|
|
|
switch verb {
|
|
|
|
case 'T':
|
2014-10-03 14:23:35 -06:00
|
|
|
p.printArg(reflect.TypeOf(arg).String(), 's', 0)
|
2011-10-17 16:48:45 -06:00
|
|
|
return false
|
|
|
|
case 'p':
|
2014-10-02 15:16:58 -06:00
|
|
|
p.fmtPointer(reflect.ValueOf(arg), verb)
|
2011-10-17 16:48:45 -06:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2010-02-01 16:53:37 -07:00
|
|
|
// Some types can be done without reflection.
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
switch f := arg.(type) {
|
2010-02-01 16:53:37 -07:00
|
|
|
case bool:
|
2011-10-21 14:59:27 -06:00
|
|
|
p.fmtBool(f, verb)
|
2010-06-14 18:16:35 -06:00
|
|
|
case float32:
|
2011-10-21 14:59:27 -06:00
|
|
|
p.fmtFloat32(f, verb)
|
2010-06-14 18:16:35 -06:00
|
|
|
case float64:
|
2011-10-21 14:59:27 -06:00
|
|
|
p.fmtFloat64(f, verb)
|
2010-06-14 18:16:35 -06:00
|
|
|
case complex64:
|
2013-08-28 12:55:39 -06:00
|
|
|
p.fmtComplex64(f, verb)
|
2010-06-14 18:16:35 -06:00
|
|
|
case complex128:
|
2011-10-21 14:59:27 -06:00
|
|
|
p.fmtComplex128(f, verb)
|
2010-06-14 18:16:35 -06:00
|
|
|
case int:
|
2011-10-21 14:59:27 -06:00
|
|
|
p.fmtInt64(int64(f), verb)
|
2010-06-14 18:16:35 -06:00
|
|
|
case int8:
|
2011-10-21 14:59:27 -06:00
|
|
|
p.fmtInt64(int64(f), verb)
|
2010-06-14 18:16:35 -06:00
|
|
|
case int16:
|
2011-10-21 14:59:27 -06:00
|
|
|
p.fmtInt64(int64(f), verb)
|
2010-06-14 18:16:35 -06:00
|
|
|
case int32:
|
2011-10-21 14:59:27 -06:00
|
|
|
p.fmtInt64(int64(f), verb)
|
2010-06-14 18:16:35 -06:00
|
|
|
case int64:
|
2011-10-21 14:59:27 -06:00
|
|
|
p.fmtInt64(f, verb)
|
2010-06-14 18:16:35 -06:00
|
|
|
case uint:
|
2014-10-02 15:16:58 -06:00
|
|
|
p.fmtUint64(uint64(f), verb)
|
2010-06-14 18:16:35 -06:00
|
|
|
case uint8:
|
2014-10-02 15:16:58 -06:00
|
|
|
p.fmtUint64(uint64(f), verb)
|
2010-06-14 18:16:35 -06:00
|
|
|
case uint16:
|
2014-10-02 15:16:58 -06:00
|
|
|
p.fmtUint64(uint64(f), verb)
|
2010-06-14 18:16:35 -06:00
|
|
|
case uint32:
|
2014-10-02 15:16:58 -06:00
|
|
|
p.fmtUint64(uint64(f), verb)
|
2010-06-14 18:16:35 -06:00
|
|
|
case uint64:
|
2014-10-02 15:16:58 -06:00
|
|
|
p.fmtUint64(f, verb)
|
2010-06-14 18:16:35 -06:00
|
|
|
case uintptr:
|
2014-10-02 15:16:58 -06:00
|
|
|
p.fmtUint64(uint64(f), verb)
|
2010-02-01 16:53:37 -07:00
|
|
|
case string:
|
2014-10-02 15:16:58 -06:00
|
|
|
p.fmtString(f, verb)
|
2011-10-21 14:59:27 -06:00
|
|
|
wasString = verb == 's' || verb == 'v'
|
2010-06-14 18:16:35 -06:00
|
|
|
case []byte:
|
2014-10-02 15:16:58 -06:00
|
|
|
p.fmtBytes(f, verb, nil, depth)
|
2011-10-21 14:59:27 -06:00
|
|
|
wasString = verb == 's'
|
2015-04-09 17:30:48 -06:00
|
|
|
case reflect.Value:
|
|
|
|
return p.printReflectValue(f, verb, depth)
|
2011-10-21 14:59:27 -06:00
|
|
|
default:
|
2012-05-29 16:08:08 -06:00
|
|
|
// If the type is not simple, it might have methods.
|
2014-10-03 14:23:35 -06:00
|
|
|
if handled := p.handleMethods(verb, depth); handled {
|
2014-10-02 15:16:58 -06:00
|
|
|
return false
|
2012-05-29 16:08:08 -06:00
|
|
|
}
|
2011-10-21 14:59:27 -06:00
|
|
|
// Need to use reflection
|
2014-10-03 14:23:35 -06:00
|
|
|
return p.printReflectValue(reflect.ValueOf(arg), verb, depth)
|
2010-06-14 18:16:35 -06:00
|
|
|
}
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
p.arg = nil
|
2011-10-21 14:59:27 -06:00
|
|
|
return
|
2011-10-17 16:48:45 -06:00
|
|
|
}
|
|
|
|
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
// printValue is like printArg but starts with a reflect value, not an interface{} value.
|
2014-10-03 14:23:35 -06:00
|
|
|
func (p *pp) printValue(value reflect.Value, verb rune, depth int) (wasString bool) {
|
2011-10-17 16:48:45 -06:00
|
|
|
if !value.IsValid() {
|
|
|
|
if verb == 'T' || verb == 'v' {
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(nilAngleString)
|
2011-10-17 16:48:45 -06:00
|
|
|
} else {
|
2011-10-21 14:59:27 -06:00
|
|
|
p.badVerb(verb)
|
2011-10-17 16:48:45 -06:00
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// Special processing considerations.
|
|
|
|
// %T (the value's type) and %p (its address) are special; we always do them first.
|
|
|
|
switch verb {
|
|
|
|
case 'T':
|
2014-10-03 14:23:35 -06:00
|
|
|
p.printArg(value.Type().String(), 's', 0)
|
2011-10-17 16:48:45 -06:00
|
|
|
return false
|
|
|
|
case 'p':
|
2014-10-02 15:16:58 -06:00
|
|
|
p.fmtPointer(value, verb)
|
2011-10-17 16:48:45 -06:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle values with special methods.
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
// Call always, even when arg == nil, because handleMethods clears p.fmt.plus for us.
|
|
|
|
p.arg = nil // Make sure it's cleared, for safety.
|
2011-10-17 16:48:45 -06:00
|
|
|
if value.CanInterface() {
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
p.arg = value.Interface()
|
2011-10-17 16:48:45 -06:00
|
|
|
}
|
2014-10-03 14:23:35 -06:00
|
|
|
if handled := p.handleMethods(verb, depth); handled {
|
2014-10-02 15:16:58 -06:00
|
|
|
return false
|
2011-10-17 16:48:45 -06:00
|
|
|
}
|
|
|
|
|
2014-10-03 14:23:35 -06:00
|
|
|
return p.printReflectValue(value, verb, depth)
|
2011-10-17 16:48:45 -06:00
|
|
|
}
|
2010-06-14 18:16:35 -06:00
|
|
|
|
fmt: print byte stringers correctly
type T byte
func (T) String() string { return "X" }
fmt.Sprintf("%s", []T{97, 98, 99, 100}) == "abcd"
fmt.Sprintf("%x", []T{97, 98, 99, 100}) == "61626364"
fmt.Sprintf("%v", []T{97, 98, 99, 100}) == "[X X X X]"
This change makes the last case print correctly.
Before, it would have been "[97 98 99 100]".
Fixes #8360.
LGTM=r
R=r, dan.kortschak
CC=golang-codereviews
https://golang.org/cl/129330043
2014-08-18 16:52:52 -06:00
|
|
|
var byteType = reflect.TypeOf(byte(0))
|
|
|
|
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
// printReflectValue is the fallback for both printArg and printValue.
|
2011-10-17 16:48:45 -06:00
|
|
|
// It uses reflect to print the value.
|
2014-10-03 14:23:35 -06:00
|
|
|
func (p *pp) printReflectValue(value reflect.Value, verb rune, depth int) (wasString bool) {
|
2011-10-18 17:23:07 -06:00
|
|
|
oldValue := p.value
|
|
|
|
p.value = value
|
2010-02-01 16:53:37 -07:00
|
|
|
BigSwitch:
|
2011-04-08 10:27:58 -06:00
|
|
|
switch f := value; f.Kind() {
|
2015-04-16 13:18:27 -06:00
|
|
|
case reflect.Invalid:
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(invReflectString)
|
2011-04-08 10:27:58 -06:00
|
|
|
case reflect.Bool:
|
2011-10-21 14:59:27 -06:00
|
|
|
p.fmtBool(f.Bool(), verb)
|
2011-04-08 10:27:58 -06:00
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
2011-10-21 14:59:27 -06:00
|
|
|
p.fmtInt64(f.Int(), verb)
|
2011-04-08 10:27:58 -06:00
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
2014-10-02 15:16:58 -06:00
|
|
|
p.fmtUint64(f.Uint(), verb)
|
2011-04-08 10:27:58 -06:00
|
|
|
case reflect.Float32, reflect.Float64:
|
2010-06-20 13:16:25 -06:00
|
|
|
if f.Type().Size() == 4 {
|
2011-10-21 14:59:27 -06:00
|
|
|
p.fmtFloat32(float32(f.Float()), verb)
|
2008-11-17 13:34:03 -07:00
|
|
|
} else {
|
2013-08-28 12:55:39 -06:00
|
|
|
p.fmtFloat64(f.Float(), verb)
|
2008-11-17 13:34:03 -07:00
|
|
|
}
|
2011-04-08 10:27:58 -06:00
|
|
|
case reflect.Complex64, reflect.Complex128:
|
2010-06-20 13:16:25 -06:00
|
|
|
if f.Type().Size() == 8 {
|
2011-10-21 14:59:27 -06:00
|
|
|
p.fmtComplex64(complex64(f.Complex()), verb)
|
2009-08-31 17:38:30 -06:00
|
|
|
} else {
|
2013-08-28 12:55:39 -06:00
|
|
|
p.fmtComplex128(f.Complex(), verb)
|
2008-12-22 12:04:17 -07:00
|
|
|
}
|
2011-04-08 10:27:58 -06:00
|
|
|
case reflect.String:
|
2014-10-02 15:16:58 -06:00
|
|
|
p.fmtString(f.String(), verb)
|
2011-04-08 10:27:58 -06:00
|
|
|
case reflect.Map:
|
2014-10-02 15:16:58 -06:00
|
|
|
if p.fmt.sharpV {
|
2010-02-01 16:53:37 -07:00
|
|
|
p.buf.WriteString(f.Type().String())
|
2011-11-14 14:10:58 -07:00
|
|
|
if f.IsNil() {
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(nilParenString)
|
2011-11-14 14:10:58 -07:00
|
|
|
break
|
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
p.buf.WriteByte('{')
|
2009-08-31 17:38:30 -06:00
|
|
|
} else {
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(mapString)
|
2009-08-31 17:38:30 -06:00
|
|
|
}
|
2011-04-08 10:27:58 -06:00
|
|
|
keys := f.MapKeys()
|
2009-07-09 18:30:07 -06:00
|
|
|
for i, key := range keys {
|
|
|
|
if i > 0 {
|
2014-10-02 15:16:58 -06:00
|
|
|
if p.fmt.sharpV {
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(commaSpaceString)
|
2009-08-31 17:38:30 -06:00
|
|
|
} else {
|
2009-12-06 13:03:52 -07:00
|
|
|
p.buf.WriteByte(' ')
|
2009-08-31 17:38:30 -06:00
|
|
|
}
|
2009-07-09 18:30:07 -06:00
|
|
|
}
|
2014-10-03 14:23:35 -06:00
|
|
|
p.printValue(key, verb, depth+1)
|
2009-12-15 16:27:16 -07:00
|
|
|
p.buf.WriteByte(':')
|
2014-10-03 14:23:35 -06:00
|
|
|
p.printValue(f.MapIndex(key), verb, depth+1)
|
2009-08-31 17:38:30 -06:00
|
|
|
}
|
2014-10-02 15:16:58 -06:00
|
|
|
if p.fmt.sharpV {
|
2009-12-06 13:03:52 -07:00
|
|
|
p.buf.WriteByte('}')
|
2009-08-31 17:38:30 -06:00
|
|
|
} else {
|
2009-12-06 13:03:52 -07:00
|
|
|
p.buf.WriteByte(']')
|
2009-07-09 18:30:07 -06:00
|
|
|
}
|
2011-04-08 10:27:58 -06:00
|
|
|
case reflect.Struct:
|
2014-10-02 15:16:58 -06:00
|
|
|
if p.fmt.sharpV {
|
2011-10-17 16:48:45 -06:00
|
|
|
p.buf.WriteString(value.Type().String())
|
2009-08-31 17:38:30 -06:00
|
|
|
}
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteByte('{')
|
2009-12-15 16:27:16 -07:00
|
|
|
v := f
|
2011-04-08 10:27:58 -06:00
|
|
|
t := v.Type()
|
2009-10-06 16:38:57 -06:00
|
|
|
for i := 0; i < v.NumField(); i++ {
|
2008-12-11 17:53:33 -07:00
|
|
|
if i > 0 {
|
2014-10-02 15:16:58 -06:00
|
|
|
if p.fmt.sharpV {
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(commaSpaceString)
|
2009-08-31 17:38:30 -06:00
|
|
|
} else {
|
2009-12-06 13:03:52 -07:00
|
|
|
p.buf.WriteByte(' ')
|
2009-08-31 17:38:30 -06:00
|
|
|
}
|
2008-12-11 17:53:33 -07:00
|
|
|
}
|
2014-10-03 14:23:35 -06:00
|
|
|
if p.fmt.plusV || p.fmt.sharpV {
|
2009-07-07 12:03:31 -06:00
|
|
|
if f := t.Field(i); f.Name != "" {
|
2009-12-15 16:27:16 -07:00
|
|
|
p.buf.WriteString(f.Name)
|
|
|
|
p.buf.WriteByte(':')
|
2008-12-11 17:53:33 -07:00
|
|
|
}
|
|
|
|
}
|
2014-10-03 14:23:35 -06:00
|
|
|
p.printValue(getField(v, i), verb, depth+1)
|
2008-12-11 17:53:33 -07:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
p.buf.WriteByte('}')
|
2011-04-08 10:27:58 -06:00
|
|
|
case reflect.Interface:
|
2009-12-15 16:27:16 -07:00
|
|
|
value := f.Elem()
|
2011-04-08 10:27:58 -06:00
|
|
|
if !value.IsValid() {
|
2014-10-02 15:16:58 -06:00
|
|
|
if p.fmt.sharpV {
|
2011-10-19 14:26:08 -06:00
|
|
|
p.buf.WriteString(f.Type().String())
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(nilParenString)
|
2009-08-31 17:38:30 -06:00
|
|
|
} else {
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(nilAngleString)
|
2009-08-31 17:38:30 -06:00
|
|
|
}
|
2008-12-11 13:59:49 -07:00
|
|
|
} else {
|
2014-10-03 14:23:35 -06:00
|
|
|
wasString = p.printValue(value, verb, depth+1)
|
2009-08-31 17:38:30 -06:00
|
|
|
}
|
2011-04-08 10:27:58 -06:00
|
|
|
case reflect.Array, reflect.Slice:
|
fmt: print byte stringers correctly
type T byte
func (T) String() string { return "X" }
fmt.Sprintf("%s", []T{97, 98, 99, 100}) == "abcd"
fmt.Sprintf("%x", []T{97, 98, 99, 100}) == "61626364"
fmt.Sprintf("%v", []T{97, 98, 99, 100}) == "[X X X X]"
This change makes the last case print correctly.
Before, it would have been "[97 98 99 100]".
Fixes #8360.
LGTM=r
R=r, dan.kortschak
CC=golang-codereviews
https://golang.org/cl/129330043
2014-08-18 16:52:52 -06:00
|
|
|
// Byte slices are special:
|
|
|
|
// - Handle []byte (== []uint8) with fmtBytes.
|
|
|
|
// - Handle []T, where T is a named byte type, with fmtBytes only
|
|
|
|
// for the s, q, an x verbs. For other verbs, T might be a
|
|
|
|
// Stringer, so we use printValue to print each element.
|
|
|
|
if typ := f.Type(); typ.Elem().Kind() == reflect.Uint8 && (typ.Elem() == byteType || verb == 's' || verb == 'q' || verb == 'x') {
|
2013-01-30 18:53:53 -07:00
|
|
|
var bytes []byte
|
|
|
|
if f.Kind() == reflect.Slice {
|
|
|
|
bytes = f.Bytes()
|
|
|
|
} else if f.CanAddr() {
|
|
|
|
bytes = f.Slice(0, f.Len()).Bytes()
|
|
|
|
} else {
|
|
|
|
// We have an array, but we cannot Slice() a non-addressable array,
|
|
|
|
// so we build a slice by hand. This is a rare case but it would be nice
|
|
|
|
// if reflection could help a little more.
|
|
|
|
bytes = make([]byte, f.Len())
|
|
|
|
for i := range bytes {
|
|
|
|
bytes[i] = byte(f.Index(i).Uint())
|
|
|
|
}
|
2010-08-16 16:34:40 -06:00
|
|
|
}
|
2014-10-02 15:16:58 -06:00
|
|
|
p.fmtBytes(bytes, verb, typ, depth)
|
2011-10-18 17:23:07 -06:00
|
|
|
wasString = verb == 's'
|
|
|
|
break
|
2010-08-16 16:34:40 -06:00
|
|
|
}
|
2014-10-02 15:16:58 -06:00
|
|
|
if p.fmt.sharpV {
|
2011-10-17 16:48:45 -06:00
|
|
|
p.buf.WriteString(value.Type().String())
|
2011-11-23 10:04:02 -07:00
|
|
|
if f.Kind() == reflect.Slice && f.IsNil() {
|
2011-11-14 14:10:58 -07:00
|
|
|
p.buf.WriteString("(nil)")
|
|
|
|
break
|
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
p.buf.WriteByte('{')
|
2009-08-31 17:38:30 -06:00
|
|
|
} else {
|
2009-12-06 13:03:52 -07:00
|
|
|
p.buf.WriteByte('[')
|
2009-08-31 17:38:30 -06:00
|
|
|
}
|
|
|
|
for i := 0; i < f.Len(); i++ {
|
|
|
|
if i > 0 {
|
2014-10-02 15:16:58 -06:00
|
|
|
if p.fmt.sharpV {
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(commaSpaceString)
|
2009-08-31 17:38:30 -06:00
|
|
|
} else {
|
2009-12-06 13:03:52 -07:00
|
|
|
p.buf.WriteByte(' ')
|
2009-08-31 17:38:30 -06:00
|
|
|
}
|
|
|
|
}
|
2014-10-03 14:23:35 -06:00
|
|
|
p.printValue(f.Index(i), verb, depth+1)
|
2009-08-31 17:38:30 -06:00
|
|
|
}
|
2014-10-02 15:16:58 -06:00
|
|
|
if p.fmt.sharpV {
|
2009-12-06 13:03:52 -07:00
|
|
|
p.buf.WriteByte('}')
|
2009-08-31 17:38:30 -06:00
|
|
|
} else {
|
2009-12-06 13:03:52 -07:00
|
|
|
p.buf.WriteByte(']')
|
2009-08-31 17:38:30 -06:00
|
|
|
}
|
2011-04-08 10:27:58 -06:00
|
|
|
case reflect.Ptr:
|
|
|
|
v := f.Pointer()
|
2009-08-31 17:38:30 -06:00
|
|
|
// pointer to array or slice or struct? ok at top level
|
|
|
|
// but not embedded (avoid loops)
|
|
|
|
if v != 0 && depth == 0 {
|
2011-04-08 10:27:58 -06:00
|
|
|
switch a := f.Elem(); a.Kind() {
|
|
|
|
case reflect.Array, reflect.Slice:
|
2009-12-15 16:27:16 -07:00
|
|
|
p.buf.WriteByte('&')
|
2014-10-03 14:23:35 -06:00
|
|
|
p.printValue(a, verb, depth+1)
|
2009-12-15 16:27:16 -07:00
|
|
|
break BigSwitch
|
2011-04-08 10:27:58 -06:00
|
|
|
case reflect.Struct:
|
2009-12-15 16:27:16 -07:00
|
|
|
p.buf.WriteByte('&')
|
2014-10-03 14:23:35 -06:00
|
|
|
p.printValue(a, verb, depth+1)
|
2009-12-15 16:27:16 -07:00
|
|
|
break BigSwitch
|
2014-10-03 21:27:08 -06:00
|
|
|
case reflect.Map:
|
|
|
|
p.buf.WriteByte('&')
|
|
|
|
p.printValue(a, verb, depth+1)
|
|
|
|
break BigSwitch
|
2009-08-31 17:38:30 -06:00
|
|
|
}
|
|
|
|
}
|
2012-02-07 21:37:05 -07:00
|
|
|
fallthrough
|
2011-04-08 10:27:58 -06:00
|
|
|
case reflect.Chan, reflect.Func, reflect.UnsafePointer:
|
2014-10-02 15:16:58 -06:00
|
|
|
p.fmtPointer(value, verb)
|
2010-06-14 18:16:35 -06:00
|
|
|
default:
|
|
|
|
p.unknownType(f)
|
2008-11-13 16:20:52 -07:00
|
|
|
}
|
2011-10-18 17:23:07 -06:00
|
|
|
p.value = oldValue
|
|
|
|
return wasString
|
2008-11-13 16:20:52 -07:00
|
|
|
}
|
|
|
|
|
2015-09-10 14:41:03 -06:00
|
|
|
// intFromArg gets the argNumth element of a. On return, isInt reports whether the argument has integer type.
|
2013-05-29 09:29:29 -06:00
|
|
|
func intFromArg(a []interface{}, argNum int) (num int, isInt bool, newArgNum int) {
|
|
|
|
newArgNum = argNum
|
|
|
|
if argNum < len(a) {
|
2015-09-10 14:41:03 -06:00
|
|
|
num, isInt = a[argNum].(int) // Almost always OK.
|
|
|
|
if !isInt {
|
|
|
|
// Work harder.
|
|
|
|
switch v := reflect.ValueOf(a[argNum]); v.Kind() {
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
|
|
n := v.Int()
|
|
|
|
if int64(int(n)) == n {
|
|
|
|
num = int(n)
|
|
|
|
isInt = true
|
|
|
|
}
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
|
|
n := v.Uint()
|
|
|
|
if int64(n) >= 0 && uint64(int(n)) == n {
|
|
|
|
num = int(n)
|
|
|
|
isInt = true
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
// Already 0, false.
|
|
|
|
}
|
|
|
|
}
|
2013-05-29 09:29:29 -06:00
|
|
|
newArgNum = argNum + 1
|
2015-06-24 06:48:35 -06:00
|
|
|
if tooLarge(num) {
|
|
|
|
num = 0
|
|
|
|
isInt = false
|
|
|
|
}
|
2010-09-22 00:10:38 -06:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
// parseArgNumber returns the value of the bracketed number, minus 1
|
|
|
|
// (explicit argument numbers are one-indexed but we want zero-indexed).
|
|
|
|
// The opening bracket is known to be present at format[0].
|
|
|
|
// The returned values are the index, the number of bytes to consume
|
|
|
|
// up to the closing paren, if present, and whether the number parsed
|
|
|
|
// ok. The bytes to consume will be 1 if no closing paren is present.
|
|
|
|
func parseArgNumber(format string) (index int, wid int, ok bool) {
|
2015-05-03 15:22:33 -06:00
|
|
|
// There must be at least 3 bytes: [n].
|
|
|
|
if len(format) < 3 {
|
|
|
|
return 0, 1, false
|
|
|
|
}
|
|
|
|
|
2013-09-23 00:03:57 -06:00
|
|
|
// Find closing bracket.
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
for i := 1; i < len(format); i++ {
|
|
|
|
if format[i] == ']' {
|
|
|
|
width, ok, newi := parsenum(format, 1, i)
|
|
|
|
if !ok || newi != i {
|
|
|
|
return 0, i + 1, false
|
|
|
|
}
|
|
|
|
return width - 1, i + 1, true // arg numbers are one-indexed and skip paren.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0, 1, false
|
|
|
|
}
|
|
|
|
|
|
|
|
// argNumber returns the next argument to evaluate, which is either the value of the passed-in
|
|
|
|
// argNum or the value of the bracketed integer that begins format[i:]. It also returns
|
|
|
|
// the new value of i, that is, the index of the next byte of the format to process.
|
2013-05-29 09:29:29 -06:00
|
|
|
func (p *pp) argNumber(argNum int, format string, i int, numArgs int) (newArgNum, newi int, found bool) {
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
if len(format) <= i || format[i] != '[' {
|
2013-05-29 09:29:29 -06:00
|
|
|
return argNum, i, false
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
}
|
|
|
|
p.reordered = true
|
|
|
|
index, wid, ok := parseArgNumber(format[i:])
|
|
|
|
if ok && 0 <= index && index < numArgs {
|
2013-05-29 09:29:29 -06:00
|
|
|
return index, i + wid, true
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
}
|
|
|
|
p.goodArgNum = false
|
2015-05-03 15:22:33 -06:00
|
|
|
return argNum, i + wid, ok
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
}
|
|
|
|
|
2010-06-14 18:16:35 -06:00
|
|
|
func (p *pp) doPrintf(format string, a []interface{}) {
|
2011-01-05 11:11:34 -07:00
|
|
|
end := len(format)
|
2013-05-29 09:29:29 -06:00
|
|
|
argNum := 0 // we process one argument per non-trivial format
|
|
|
|
afterIndex := false // previous item in format was an index like [3].
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
p.reordered = false
|
2011-01-05 11:11:34 -07:00
|
|
|
for i := 0; i < end; {
|
2013-09-23 00:03:57 -06:00
|
|
|
p.goodArgNum = true
|
2011-01-05 12:42:35 -07:00
|
|
|
lasti := i
|
|
|
|
for i < end && format[i] != '%' {
|
|
|
|
i++
|
|
|
|
}
|
|
|
|
if i > lasti {
|
|
|
|
p.buf.WriteString(format[lasti:i])
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
2011-01-05 12:42:35 -07:00
|
|
|
if i >= end {
|
|
|
|
// done processing format string
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
2011-01-05 11:11:34 -07:00
|
|
|
// Process one verb
|
2009-12-15 16:27:16 -07:00
|
|
|
i++
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
|
|
|
|
// Do we have flags?
|
2009-12-15 16:27:16 -07:00
|
|
|
p.fmt.clearflags()
|
2010-05-21 21:25:08 -06:00
|
|
|
F:
|
|
|
|
for ; i < end; i++ {
|
2008-11-24 15:51:33 -07:00
|
|
|
switch format[i] {
|
|
|
|
case '#':
|
2009-11-09 13:07:39 -07:00
|
|
|
p.fmt.sharp = true
|
2008-11-24 15:51:33 -07:00
|
|
|
case '0':
|
2009-11-09 13:07:39 -07:00
|
|
|
p.fmt.zero = true
|
2008-11-24 15:51:33 -07:00
|
|
|
case '+':
|
2009-11-09 13:07:39 -07:00
|
|
|
p.fmt.plus = true
|
2008-11-24 15:51:33 -07:00
|
|
|
case '-':
|
2009-11-09 13:07:39 -07:00
|
|
|
p.fmt.minus = true
|
2008-11-24 15:51:33 -07:00
|
|
|
case ' ':
|
2009-11-09 13:07:39 -07:00
|
|
|
p.fmt.space = true
|
2008-11-24 15:51:33 -07:00
|
|
|
default:
|
2009-11-09 13:07:39 -07:00
|
|
|
break F
|
2008-11-24 15:51:33 -07:00
|
|
|
}
|
|
|
|
}
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
|
|
|
|
// Do we have an explicit argument index?
|
2013-05-29 09:29:29 -06:00
|
|
|
argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
|
|
|
|
// Do we have width?
|
2011-01-05 11:11:34 -07:00
|
|
|
if i < end && format[i] == '*' {
|
2013-05-29 09:29:29 -06:00
|
|
|
i++
|
|
|
|
p.fmt.wid, p.fmt.widPresent, argNum = intFromArg(a, argNum)
|
2015-06-24 06:48:35 -06:00
|
|
|
|
2010-09-22 00:10:38 -06:00
|
|
|
if !p.fmt.widPresent {
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(badWidthString)
|
2010-09-22 00:10:38 -06:00
|
|
|
}
|
2015-06-24 06:48:35 -06:00
|
|
|
|
|
|
|
// We have a negative width, so take its value and ensure
|
|
|
|
// that the minus flag is set
|
|
|
|
if p.fmt.wid < 0 {
|
|
|
|
p.fmt.wid = -p.fmt.wid
|
|
|
|
p.fmt.minus = true
|
|
|
|
}
|
2013-05-29 09:29:29 -06:00
|
|
|
afterIndex = false
|
2010-09-22 00:10:38 -06:00
|
|
|
} else {
|
|
|
|
p.fmt.wid, p.fmt.widPresent, i = parsenum(format, i, end)
|
2013-05-29 09:29:29 -06:00
|
|
|
if afterIndex && p.fmt.widPresent { // "%[3]2d"
|
|
|
|
p.goodArgNum = false
|
|
|
|
}
|
2010-09-22 00:10:38 -06:00
|
|
|
}
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
|
|
|
|
// Do we have precision?
|
2013-04-29 14:52:07 -06:00
|
|
|
if i+1 < end && format[i] == '.' {
|
2013-05-29 09:29:29 -06:00
|
|
|
i++
|
|
|
|
if afterIndex { // "%[3].2d"
|
|
|
|
p.goodArgNum = false
|
|
|
|
}
|
|
|
|
argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
|
2015-05-03 15:22:33 -06:00
|
|
|
if i < end && format[i] == '*' {
|
2013-05-29 09:29:29 -06:00
|
|
|
i++
|
|
|
|
p.fmt.prec, p.fmt.precPresent, argNum = intFromArg(a, argNum)
|
2015-06-24 06:48:35 -06:00
|
|
|
// Negative precision arguments don't make sense
|
|
|
|
if p.fmt.prec < 0 {
|
|
|
|
p.fmt.prec = 0
|
|
|
|
p.fmt.precPresent = false
|
|
|
|
}
|
2010-09-22 00:10:38 -06:00
|
|
|
if !p.fmt.precPresent {
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(badPrecString)
|
2010-09-22 00:10:38 -06:00
|
|
|
}
|
2013-05-29 09:29:29 -06:00
|
|
|
afterIndex = false
|
2010-09-22 00:10:38 -06:00
|
|
|
} else {
|
2013-05-29 09:29:29 -06:00
|
|
|
p.fmt.prec, p.fmt.precPresent, i = parsenum(format, i, end)
|
2011-07-21 00:46:51 -06:00
|
|
|
if !p.fmt.precPresent {
|
|
|
|
p.fmt.prec = 0
|
|
|
|
p.fmt.precPresent = true
|
|
|
|
}
|
2010-09-22 00:10:38 -06:00
|
|
|
}
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
2013-05-29 09:29:29 -06:00
|
|
|
|
|
|
|
if !afterIndex {
|
|
|
|
argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
|
|
|
|
}
|
|
|
|
|
2011-01-05 11:11:34 -07:00
|
|
|
if i >= end {
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(noVerbString)
|
2011-01-05 11:11:34 -07:00
|
|
|
continue
|
|
|
|
}
|
2011-01-05 12:42:35 -07:00
|
|
|
c, w := utf8.DecodeRuneInString(format[i:])
|
2009-12-15 16:27:16 -07:00
|
|
|
i += w
|
2008-10-24 17:33:29 -06:00
|
|
|
// percent is special - absorbs no operand
|
|
|
|
if c == '%' {
|
2010-08-16 16:34:40 -06:00
|
|
|
p.buf.WriteByte('%') // We ignore width and prec.
|
2009-12-15 16:27:16 -07:00
|
|
|
continue
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
if !p.goodArgNum {
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(percentBangString)
|
|
|
|
p.buf.WriteRune(c)
|
|
|
|
p.buf.WriteString(badIndexString)
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
continue
|
|
|
|
} else if argNum >= len(a) { // out of operands
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(percentBangString)
|
|
|
|
p.buf.WriteRune(c)
|
|
|
|
p.buf.WriteString(missingString)
|
2009-12-15 16:27:16 -07:00
|
|
|
continue
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
arg := a[argNum]
|
|
|
|
argNum++
|
2009-08-31 17:38:30 -06:00
|
|
|
|
2014-10-03 14:23:35 -06:00
|
|
|
if c == 'v' {
|
|
|
|
if p.fmt.sharp {
|
|
|
|
// Go syntax. Set the flag in the fmt and clear the sharp flag.
|
|
|
|
p.fmt.sharp = false
|
|
|
|
p.fmt.sharpV = true
|
|
|
|
}
|
|
|
|
if p.fmt.plus {
|
|
|
|
// Struct-field syntax. Set the flag in the fmt and clear the plus flag.
|
|
|
|
p.fmt.plus = false
|
|
|
|
p.fmt.plusV = true
|
|
|
|
}
|
2014-10-02 15:16:58 -06:00
|
|
|
}
|
2016-02-19 17:51:32 -07:00
|
|
|
|
|
|
|
// Use space padding instead of zero padding to the right.
|
|
|
|
if p.fmt.minus {
|
|
|
|
p.fmt.zero = false
|
|
|
|
}
|
|
|
|
|
2014-10-03 14:23:35 -06:00
|
|
|
p.printArg(arg, c, 0)
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
2010-06-14 18:16:35 -06:00
|
|
|
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
// Check for extra arguments unless the call accessed the arguments
|
|
|
|
// out of order, in which case it's too expensive to detect if they've all
|
|
|
|
// been used and arguably OK if they're not.
|
|
|
|
if !p.reordered && argNum < len(a) {
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(extraString)
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
for ; argNum < len(a); argNum++ {
|
|
|
|
arg := a[argNum]
|
|
|
|
if arg != nil {
|
|
|
|
p.buf.WriteString(reflect.TypeOf(arg).String())
|
2010-05-13 13:49:48 -06:00
|
|
|
p.buf.WriteByte('=')
|
|
|
|
}
|
2014-10-03 14:23:35 -06:00
|
|
|
p.printArg(arg, 'v', 0)
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
if argNum+1 < len(a) {
|
2016-02-21 08:05:44 -07:00
|
|
|
p.buf.WriteString(commaSpaceString)
|
2008-11-06 11:40:57 -07:00
|
|
|
}
|
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
p.buf.WriteByte(')')
|
2008-11-06 11:40:57 -07:00
|
|
|
}
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
|
|
|
|
2010-06-14 18:16:35 -06:00
|
|
|
func (p *pp) doPrint(a []interface{}, addspace, addnewline bool) {
|
2010-07-29 11:50:09 -06:00
|
|
|
prevString := false
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
for argNum := 0; argNum < len(a); argNum++ {
|
2010-06-28 15:11:38 -06:00
|
|
|
p.fmt.clearflags()
|
2012-12-25 15:54:24 -07:00
|
|
|
// always add spaces if we're doing Println
|
fmt.Printf: introduce notation for random access to arguments.
This text is added to doc.go:
Explicit argument indexes:
In Printf, Sprintf, and Fprintf, the default behavior is for each
formatting verb to format successive arguments passed in the call.
However, the notation [n] immediately before the verb indicates that the
nth one-indexed argument is to be formatted instead. The same notation
before a '*' for a width or precision selects the argument index holding
the value. After processing a bracketed expression [n], arguments n+1,
n+2, etc. will be processed unless otherwise directed.
For example,
fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
will yield "22, 11", while
fmt.Sprintf("%[3]*[2].*[1]f", 12.0, 2, 6),
equivalent to
fmt.Sprintf("%6.2f", 12.0),
will yield " 12.00". Because an explicit index affects subsequent verbs,
this notation can be used to print the same values multiple times
by resetting the index for the first argument to be repeated:
fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
will yield "16 17 0x10 0x11".
The notation chosen differs from that in C, but I believe it's easier to read
and to remember (we're indexing the arguments), and compatibility with
C's printf was never a strong goal anyway.
While we're here, change the word "field" to "arg" or "argument" in the
code; it was being misused and was confusing.
R=rsc, bradfitz, rogpeppe, minux.ma, peter.armitage
CC=golang-dev
https://golang.org/cl/9680043
2013-05-24 16:49:26 -06:00
|
|
|
arg := a[argNum]
|
|
|
|
if argNum > 0 {
|
|
|
|
isString := arg != nil && reflect.TypeOf(arg).Kind() == reflect.String
|
2010-07-29 11:50:09 -06:00
|
|
|
if addspace || !isString && !prevString {
|
2009-12-06 13:03:52 -07:00
|
|
|
p.buf.WriteByte(' ')
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
|
|
|
}
|
2014-10-03 14:23:35 -06:00
|
|
|
prevString = p.printArg(arg, 'v', 0)
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
printf as we know and love it.
Plus print[ln] with the ability to print struct values.
Note for language mavens: if a "..." function passes its argument
to another "..." function, the argument is not wrapped again. This
allows printf to call fprintf without extra manipulation. It's good
but needs to go in the spec.
This code works:
///
package main
import fmt "fmt"
import os "os"
type T struct { s string; a, b int }
func main() {
P := fmt.Printer();
P.printf("%s = %d with float value %.4f\n", "hi there", 7, 123.456);
P.println("hi there", 7, 123.456);
P.fprintf(os.Stdout, "%s = %d with float value %.4f\n", "hi there", 7, 123.456);
P.println(T{"x", 7, 234}, "end of struct", 8, 9);
}
R=rsc
DELTA=28 (7 added, 3 deleted, 18 changed)
OCL=18321
CL=18324
2008-11-02 13:33:02 -07:00
|
|
|
if addnewline {
|
2009-12-06 13:03:52 -07:00
|
|
|
p.buf.WriteByte('\n')
|
2008-10-24 17:33:29 -06:00
|
|
|
}
|
|
|
|
}
|