// Format implements fmt.Formatter. It accepts format.State for // language-specific rendering. func (v Value) Format(s fmt.State, verb rune) { var lang int if state, ok := s.(format.State); ok { lang, _ = language.CompactIndex(state.Language()) } // Get the options. Use DefaultFormat if not present. opt := v.format if opt == nil { opt = defaultFormat } cur := v.currency if cur.index == 0 { cur = opt.currency } // TODO: use pattern. io.WriteString(s, opt.symbol(lang, cur)) if v.amount != nil { s.Write(space) // TODO: apply currency-specific rounding scale, _ := opt.kind.Rounding(cur) if _, ok := s.Precision(); !ok { fmt.Fprintf(s, "%.*f", scale, v.amount) } else { fmt.Fprint(s, v.amount) } } }
func (af *ansiFormatter) Format(f fmt.State, c rune) { // reconstruct the format string in bf bf := new(bytes.Buffer) bf.WriteByte('%') for _, x := range []byte{'-', '+', '#', ' ', '0'} { if f.Flag(int(x)) { bf.WriteByte(x) } } if w, ok := f.Width(); ok { fmt.Fprint(bf, w) } if p, ok := f.Precision(); ok { fmt.Fprintf(bf, ".%d", p) } bf.WriteRune(c) format := bf.String() if len(af.codes) == 0 { fmt.Fprintf(f, format, af.value) return } fmt.Fprintf(f, "\x1b[%d", af.codes[0]) for _, code := range af.codes[1:] { fmt.Fprintf(f, ";%d", code) } f.Write([]byte{'m'}) fmt.Fprintf(f, format, af.value) fmt.Fprint(f, "\x1b[0m") }
func (a Attributes) Format(fs fmt.State, c rune) { for i, tv := range a { fmt.Fprintf(fs, "%s %s", tv.Tag, tv.Value) if i < len(a)-1 { fs.Write([]byte("; ")) } } }
// write count copies of text to s func writeMultiple(s fmt.State, text string, count int) { if len(text) > 0 { b := []byte(text) for ; count > 0; count-- { s.Write(b) } } }
// We implement fmt.Formatter interface just so we can left-align the cards. func (s Suit) Format(f fmt.State, c int) { x := stringTable[s] f.Write([]byte(x)) if w, ok := f.Width(); ok { for i := 0; i < w-len(x); i++ { f.Write([]byte{' '}) } } }
// Format implements fmt.Formatter with support for the following verbs. // // %s source file // %d line number // %n function name // %v equivalent to %s:%d // // It accepts the '+' and '#' flags for most of the verbs as follows. // // %+s path of source file relative to the compile time GOPATH // %#s full path of source file // %+n import path qualified function name // %+v equivalent to %+s:%d // %#v equivalent to %#s:%d func (c Call) Format(s fmt.State, verb rune) { if c.fn == nil { fmt.Fprintf(s, "%%!%c(NOFUNC)", verb) return } switch verb { case 's', 'v': file, line := c.fn.FileLine(c.pc) switch { case s.Flag('#'): // done case s.Flag('+'): file = file[pkgIndex(file, c.fn.Name()):] default: const sep = "/" if i := strings.LastIndex(file, sep); i != -1 { file = file[i+len(sep):] } } io.WriteString(s, file) if verb == 'v' { buf := [7]byte{':'} s.Write(strconv.AppendInt(buf[:1], int64(line), 10)) } case 'd': _, line := c.fn.FileLine(c.pc) buf := [6]byte{} s.Write(strconv.AppendInt(buf[:0], int64(line), 10)) case 'n': name := c.fn.Name() if !s.Flag('+') { const pathSep = "/" if i := strings.LastIndex(name, pathSep); i != -1 { name = name[i+len(pathSep):] } const pkgSep = "." if i := strings.Index(name, pkgSep); i != -1 { name = name[i+len(pkgSep):] } } io.WriteString(s, name) } }
func (f *formatter) formatStruct(s fmt.State, c rune, val reflect.Value) { f.depth++ if f.verbose { writeType(s, val) writeLeftcurly(s) if f.pretty { writeNewline(s) writeFullIndent(s, f.depth) } } else { writeLeftcurly(s) } typ := val.Type() for i, n := 0, val.NumField(); i < n; i++ { field := typ.Field(i) if i > 0 { f.sep(s) } if f.verbose || f.extra { s.Write([]byte(field.Name)) writeColon(s) } if field.PkgPath == "" { f.format(s, c, val.Field(i)) } else { field := typ.Field(i) var valptr reflect.Value if val.CanAddr() { valptr = val.Addr() } else { valptr = reflect.New(typ) reflect.Indirect(valptr).Set(val) } fieldp := valptr.Pointer() + field.Offset fieldptr := reflect.NewAt(field.Type, unsafe.Pointer(fieldp)) f.format(s, c, reflect.Indirect(fieldptr)) } } f.depth-- if f.verbose && f.pretty { writeComma(s) writeNewline(s) writeFullIndent(s, f.depth) } writeRightcurly(s) }
// Format satisfies the fmt.Formatter interface. See NewFormatter for usage // details. func (f *formatState) Format(fs fmt.State, verb rune) { f.fs = fs // Use standard formatting for verbs that are not v. if verb != 'v' { format := f.constructOrigFormat(verb) fmt.Fprintf(fs, format, f.value) return } if f.value == nil { if fs.Flag('#') { fs.Write(interfaceBytes) } fs.Write(nilAngleBytes) return } f.format(reflect.ValueOf(f.value)) }
// Format allows text to satisfy the fmt.Formatter interface. The format // behaviour is the same as for fmt.Print. func (t text) Format(fs fmt.State, c rune) { if t.Mode&activeBits != 0 { t.Mode.set(fs) } w, wOk := fs.Width() p, pOk := fs.Precision() var ( b bytes.Buffer prevString bool ) b.WriteByte('%') for _, f := range "+-# 0" { if fs.Flag(int(f)) { b.WriteRune(f) } } if wOk { fmt.Fprint(&b, w) } if pOk { b.WriteByte('.') fmt.Fprint(&b, p) } b.WriteRune(c) format := b.String() for _, v := range t.v { isString := v != nil && doesString(v) if isString && prevString { fs.Write([]byte{' '}) } prevString = isString fmt.Fprintf(fs, format, v) } if t.Mode&activeBits != 0 && t.Mode&activeBits != Reset && t.Mode&NoResetAfter == 0 { t.reset(fs) } }
func format(b Bed, fs fmt.State, c rune) { bv := reflect.ValueOf(b) if bv.IsNil() { fmt.Fprint(fs, "<nil>") return } bv = bv.Elem() switch c { case 'v': if fs.Flag('#') { fmt.Fprintf(fs, "&%#v", bv.Interface()) return } fallthrough case 's': width, _ := fs.Width() if !b.canBed(width) { fmt.Fprintf(fs, "%%!(BADWIDTH)%T", b) return } if width == 0 { width = bv.NumField() } for i := 0; i < width; i++ { f := bv.Field(i).Interface() if i >= rgbField { switch i { case rgbField: rv := reflect.ValueOf(f) if reflect.DeepEqual(rv.Interface(), color.RGBA{}) { fs.Write([]byte{'0'}) } else { fmt.Fprintf(fs, "%d,%d,%d", rv.Field(0).Interface(), rv.Field(1).Interface(), rv.Field(2).Interface()) } case blockCountField: fmt.Fprint(fs, f) case blockSizesField, blockStartsField: av := reflect.ValueOf(f) l := av.Len() for j := 0; j < l; j++ { fmt.Fprint(fs, av.Index(j).Interface()) if j < l-1 { fs.Write([]byte{','}) } } } } else { fmt.Fprint(fs, f) } if i < width-1 { fs.Write([]byte{'\t'}) } } default: fmt.Fprintf(fs, "%%!%c(%T=%3s)", c, b, b) } }
func (this *Person) Format(f fmt.State, c rune) { if c == 'L' { f.Write([]byte(this.String())) f.Write([]byte(" Person has three fields.")) } else { // 没有此句,会导致 fmt.Printf("%s", p) 啥也不输出 f.Write([]byte(fmt.Sprintln(this.String()))) } }
func (r Range) Format(f fmt.State, c int) { i := byte(0) for ; i < r.Min; i++ { f.Write([]byte{'X'}) } for ; float64(i)+0.5 < r.Mean; i++ { f.Write([]byte{'x'}) } for ; i < r.Max; i++ { f.Write([]byte{'.'}) } if w, ok := f.Width(); ok { for ; i < byte(w); i++ { f.Write([]byte{' '}) } } }
// Format implements fmt.Formatter by printing the Trace as square brackes ([, // ]) surrounding a space separated list of Calls each formatted with the // supplied verb and options. func (pcs Trace) Format(s fmt.State, c rune) { s.Write([]byte("[")) for i, pc := range pcs { if i > 0 { s.Write([]byte(" ")) } pc.Format(s, c) } s.Write([]byte("]")) }
// Format implements fmt.Formatter by printing the CallStack as square brackes // ([, ]) surrounding a space separated list of Calls each formatted with the // supplied verb and options. func (cs CallStack) Format(s fmt.State, verb rune) { s.Write([]byte("[")) for i, pc := range cs { if i > 0 { s.Write([]byte(" ")) } pc.Format(s, verb) } s.Write([]byte("]")) }
// Format implements fmt.Formatter by printing the CallStack as square brackets // ([, ]) surrounding a space separated list of Calls each formatted with the // supplied verb and options. func (cs CallStack) Format(s fmt.State, verb rune) { s.Write(openBracketBytes) for i, pc := range cs { if i > 0 { s.Write(spaceBytes) } pc.Format(s, verb) } s.Write(closeBracketBytes) }
func writeColon(s fmt.State) { s.Write(colonBytes) }
func writeComma(s fmt.State) { s.Write(commaBytes) }
func writeSpace(s fmt.State) { s.Write(spaceBytes) }
func writePtr(s fmt.State) { s.Write(ptrBytes) }
// Format prints a pretty representation of m to the fs io.Writer. The format character c // specifies the numerical representation of of elements; valid values are those for float64 // specified in the fmt package, with their associated flags. In addition to this, a '#' for // all valid verbs except 'v' indicates that zero values be represented by the dot character. // The '#' associated with the 'v' verb formats the matrix with Go syntax representation. // The printed range of the matrix can be limited by specifying a positive value for margin; // If margin is greater than zero, only the first and last margin rows/columns of the matrix // are output. func Format(m Matrix, margin int, dot byte, fs fmt.State, c rune) { rows, cols := m.Dims() var printed int if margin <= 0 { printed = rows if cols > printed { printed = cols } } else { printed = margin } prec, pOk := fs.Precision() if !pOk { prec = -1 } var ( maxWidth int buf, pad []byte ) switch c { case 'v', 'e', 'E', 'f', 'F', 'g', 'G': // Note that the '#' flag should have been dealt with by the type. // So %v is treated exactly as %g here. if c == 'v' { buf, maxWidth = maxCellWidth(m, 'g', printed, prec) } else { buf, maxWidth = maxCellWidth(m, c, printed, prec) } default: fmt.Fprintf(fs, "%%!%c(%T=Dims(%d, %d))", c, m, rows, cols) return } width, _ := fs.Width() width = max(width, maxWidth) pad = make([]byte, max(width, 2)) for i := range pad { pad[i] = ' ' } if rows > 2*printed || cols > 2*printed { fmt.Fprintf(fs, "Dims(%d, %d)\n", rows, cols) } skipZero := fs.Flag('#') for i := 0; i < rows; i++ { var el string switch { case rows == 1: fmt.Fprint(fs, "[") el = "]" case i == 0: fmt.Fprint(fs, "⎡") el = "⎤\n" case i < rows-1: fmt.Fprint(fs, "⎢") el = "⎥\n" default: fmt.Fprint(fs, "⎣") el = "⎦" } for j := 0; j < cols; j++ { if j >= printed && j < cols-printed { j = cols - printed - 1 if i == 0 || i == rows-1 { fmt.Fprint(fs, "... ... ") } else { fmt.Fprint(fs, " ") } continue } v := m.At(i, j) if v == 0 && skipZero { buf = buf[:1] buf[0] = dot } else { if c == 'v' { buf = strconv.AppendFloat(buf[:0], v, 'g', prec, 64) } else { buf = strconv.AppendFloat(buf[:0], v, byte(c), prec, 64) } } if fs.Flag('-') { fs.Write(buf) fs.Write(pad[:width-len(buf)]) } else { fs.Write(pad[:width-len(buf)]) fs.Write(buf) } if j < cols-1 { fs.Write(pad[:2]) } } fmt.Fprint(fs, el) if i >= printed-1 && i < rows-printed && 2*printed < rows { i = rows - printed - 1 fmt.Fprint(fs, " .\n .\n .\n") continue } } }
func writeMap(s fmt.State) { s.Write(mapBytes) }
// Format implements fmt.Formatter with support for the following verbs. // // %s source file // %d line number // %n function name // %v equivalent to %s:%d // // It accepts the '+' and '#' flags for most of the verbs as follows. // // %+s path of source file relative to the compile time GOPATH // %#s full path of source file // %+n import path qualified function name // %+v equivalent to %+s:%d // %#v equivalent to %#s:%d func (c Call) Format(s fmt.State, verb rune) { if c.fn == nil { fmt.Fprintf(s, "%%!%c(NOFUNC)", verb) return } switch verb { case 's', 'v': file, line := c.fn.FileLine(c.pc) switch { case s.Flag('#'): // done case s.Flag('+'): // Here we want to get the source file path relative to the // compile time GOPATH. As of Go 1.4.x there is no direct way to // know the compiled GOPATH at runtime, but we can infer the // number of path segments in the GOPATH. We note that fn.Name() // returns the function name qualified by the import path, which // does not include the GOPATH. Thus we can trim segments from the // beginning of the file path until the number of path separators // remaining is one more than the number of path separators in the // function name. For example, given: // // GOPATH /home/user // file /home/user/src/pkg/sub/file.go // fn.Name() pkg/sub.Type.Method // // We want to produce: // // pkg/sub/file.go // // From this we can easily see that fn.Name() has one less path // separator than our desired output. We count separators from the // end of the file path until it finds two more than in the // function name and then move one character forward to preserve // the initial path segment without a leading separator. const sep = "/" goal := strings.Count(c.fn.Name(), sep) + 2 pathCnt := 0 i := len(file) for pathCnt < goal { i = strings.LastIndex(file[:i], sep) if i == -1 { i = -len(sep) break } pathCnt++ } // get back to 0 or trim the leading seperator file = file[i+len(sep):] default: const sep = "/" if i := strings.LastIndex(file, sep); i != -1 { file = file[i+len(sep):] } } io.WriteString(s, file) if verb == 'v' { buf := [7]byte{':'} s.Write(strconv.AppendInt(buf[:1], int64(line), 10)) } case 'd': _, line := c.fn.FileLine(c.pc) buf := [6]byte{} s.Write(strconv.AppendInt(buf[:0], int64(line), 10)) case 'n': name := c.fn.Name() if !s.Flag('+') { const pathSep = "/" if i := strings.LastIndex(name, pathSep); i != -1 { name = name[i+len(pathSep):] } const pkgSep = "." if i := strings.Index(name, pkgSep); i != -1 { name = name[i+len(pkgSep):] } } io.WriteString(s, name) } }
func writeNil(s fmt.State) { s.Write(nilBytes) }
// Format implements fmt.Formatter. It accepts the formats // 'b' (binary), 'o' (octal), 'd' (decimal), 'x' (lowercase // hexadecimal), and 'X' (uppercase hexadecimal). // Also supported are the full suite of package fmt's format // flags for integral types, including '+' and ' ' for sign // control, '#' for leading zero in octal and for hexadecimal, // a leading "0x" or "0X" for "%#x" and "%#X" respectively, // specification of minimum digits precision, output field // width, space or zero padding, and '-' for left or right // justification. // func (x *Int) Format(s fmt.State, ch rune) { // determine base var base int switch ch { case 'b': base = 2 case 'o': base = 8 case 'd', 's', 'v': base = 10 case 'x', 'X': base = 16 default: // unknown format fmt.Fprintf(s, "%%!%c(big.Int=%s)", ch, x.String()) return } if x == nil { fmt.Fprint(s, "<nil>") return } // determine sign character sign := "" switch { case x.neg: sign = "-" case s.Flag('+'): // supersedes ' ' when both specified sign = "+" case s.Flag(' '): sign = " " } // determine prefix characters for indicating output base prefix := "" if s.Flag('#') { switch ch { case 'o': // octal prefix = "0" case 'x': // hexadecimal prefix = "0x" case 'X': prefix = "0X" } } digits := x.abs.utoa(base) if ch == 'X' { // faster than bytes.ToUpper for i, d := range digits { if 'a' <= d && d <= 'z' { digits[i] = 'A' + (d - 'a') } } } // number of characters for the three classes of number padding var left int // space characters to left of digits for right justification ("%8d") var zeros int // zero characters (actually cs[0]) as left-most digits ("%.8d") var right int // space characters to right of digits for left justification ("%-8d") // determine number padding from precision: the least number of digits to output precision, precisionSet := s.Precision() if precisionSet { switch { case len(digits) < precision: zeros = precision - len(digits) // count of zero padding case len(digits) == 1 && digits[0] == '0' && precision == 0: return // print nothing if zero value (x == 0) and zero precision ("." or ".0") } } // determine field pad from width: the least number of characters to output length := len(sign) + len(prefix) + zeros + len(digits) if width, widthSet := s.Width(); widthSet && length < width { // pad as specified switch d := width - length; { case s.Flag('-'): // pad on the right with spaces; supersedes '0' when both specified right = d case s.Flag('0') && !precisionSet: // pad with zeros unless precision also specified zeros = d default: // pad on the left with spaces left = d } } // print number as [left pad][sign][prefix][zero pad][digits][right pad] writeMultiple(s, " ", left) writeMultiple(s, sign, 1) writeMultiple(s, prefix, 1) writeMultiple(s, "0", zeros) s.Write(digits) writeMultiple(s, " ", right) }
/* Format implements the fmt.Formatter interface, based on Apache HTTP's CustomLog directive. This allows a Context object to have Sprintf verbs for its values. See: https://httpd.apache.org/docs/2.4/mod/mod_log_config.html#formats Verb Description ---- --------------------------------------------------- %% Percent sign %a Client remote address %b Size of reponse in bytes, excluding headers. Or '-' if zero. %#a Proxy client address, or unknown. %h Remote hostname. Will perform lookup. %l Remote ident, will write '-' (only for Apache log support). %m Request method %q Request query string. %r Request line. %#r Request line without protocol. %s Response status code. %#s Response status code and text. %t Request time, as string. %u Remote user, if any. %v Request host name. %A User agent. %B Size of reponse in bytes, excluding headers. %C Colorized status code. For console, using ANSI escape codes. %D Time lapsed to serve request, in seconds. %H Request protocol. %I Bytes received. %L Request ID. %P Server port used. %R Referer. %U Request path. Example: // Print request line and remote address. // Index [1] needed to reuse ctx argument. fmt.Printf("\"%r\" %[1]a", ctx) // Output: // "GET /v1/" 192.168.1.10 */ func (ctx *Context) Format(f fmt.State, c rune) { var str string p, pok := f.Precision() if !pok { p = -1 } switch c { case 'a': if f.Flag('#') { str = ctx.ProxyClient() break } str = ctx.Request.RemoteAddr case 'b': if ctx.Bytes() == 0 { f.Write([]byte{45}) return } fallthrough case 'B': str = strconv.Itoa(ctx.Bytes()) case 'h': t := strings.Split(ctx.Request.RemoteAddr, ":") str = t[0] case 'l': f.Write([]byte{45}) return case 'm': str = ctx.Request.Method case 'q': str = ctx.Request.URL.RawQuery case 'r': str = ctx.Request.Method + " " + ctx.Request.URL.RequestURI() if f.Flag('#') { break } str += " " + ctx.Request.Proto case 's': str = strconv.Itoa(ctx.Status()) if f.Flag('#') { str += " " + http.StatusText(ctx.Status()) } case 't': t := ctx.Info.GetTime("context.start_time") str = t.Format("[02/Jan/2006:15:04:05 -0700]") case 'u': // XXX: i dont think net/http sets User if ctx.Request.URL.User == nil { f.Write([]byte{45}) return } str = ctx.Request.URL.User.Username() case 'v': str = ctx.Request.Host case 'A': str = ctx.Request.UserAgent() case 'C': str = statusColor(ctx.Status()) case 'D': when := ctx.Info.GetTime("context.start_time") if when.IsZero() { f.Write([]byte("%!(BADTIME)")) return } pok = false str = strconv.FormatFloat(time.Since(when).Seconds(), 'f', p, 32) case 'H': str = ctx.Request.Proto case 'I': str = fmt.Sprintf("%d", ctx.Request.ContentLength) case 'L': str = ctx.Info.Get("context.request_id") case 'P': s := strings.Split(ctx.Request.Host, ":") if len(s) > 1 { str = s[1] break } str = "80" case 'R': str = ctx.Request.Referer() case 'U': str = ctx.Request.URL.Path } if pok { str = str[:p] } f.Write([]byte(str)) }
func writeNilangle(s fmt.State) { s.Write(nilangleBytes) }
func writeRightparen(s fmt.State) { s.Write(rightparenBytes) }
func (p *Error) Format(f fmt.State, c rune) { f.Write([]byte(p.Message)) }
// Format implements fmt.Formatter. It accepts all the regular // formats for floating-point numbers ('e', 'E', 'f', 'F', 'g', // 'G') as well as 'b', 'p', and 'v'. See (*Float).Text for the // interpretation of 'b' and 'p'. The 'v' format is handled like // 'g'. // Format also supports specification of the minimum precision // in digits, the output field width, as well as the format verbs // '+' and ' ' for sign control, '0' for space or zero padding, // and '-' for left or right justification. See the fmt package // for details. func (x *Float) Format(s fmt.State, format rune) { prec, hasPrec := s.Precision() if !hasPrec { prec = 6 // default precision for 'e', 'f' } switch format { case 'e', 'E', 'f', 'b', 'p': // nothing to do case 'F': // (*Float).Text doesn't support 'F'; handle like 'f' format = 'f' case 'v': // handle like 'g' format = 'g' fallthrough case 'g', 'G': if !hasPrec { prec = -1 // default precision for 'g', 'G' } default: fmt.Fprintf(s, "%%!%c(*big.Float=%s)", format, x.String()) return } var buf []byte buf = x.Append(buf, byte(format), prec) if len(buf) == 0 { buf = []byte("?") // should never happen, but don't crash } // len(buf) > 0 var sign string switch { case buf[0] == '-': sign = "-" buf = buf[1:] case buf[0] == '+': // +Inf sign = "+" if s.Flag(' ') { sign = " " } buf = buf[1:] case s.Flag('+'): sign = "+" case s.Flag(' '): sign = " " } var padding int if width, hasWidth := s.Width(); hasWidth && width > len(sign)+len(buf) { padding = width - len(sign) - len(buf) } switch { case s.Flag('0') && !x.IsInf(): // 0-padding on left writeMultiple(s, sign, 1) writeMultiple(s, "0", padding) s.Write(buf) case s.Flag('-'): // padding on right writeMultiple(s, sign, 1) s.Write(buf) writeMultiple(s, " ", padding) default: // padding on left writeMultiple(s, " ", padding) writeMultiple(s, sign, 1) s.Write(buf) } }
func writeType(s fmt.State, v reflect.Value) { s.Write([]byte(v.Type().String())) }