"Fossies" - the Fresh Open Source Software Archive

Member "go/src/cmd/vendor/golang.org/x/xerrors/adaptor.go" (9 Sep 2020, 4130 Bytes) of package /windows/misc/go1.14.9.windows-386.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Go source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 // Copyright 2018 The Go Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style
    3 // license that can be found in the LICENSE file.
    4 
    5 package xerrors
    6 
    7 import (
    8     "bytes"
    9     "fmt"
   10     "io"
   11     "reflect"
   12     "strconv"
   13 )
   14 
   15 // FormatError calls the FormatError method of f with an errors.Printer
   16 // configured according to s and verb, and writes the result to s.
   17 func FormatError(f Formatter, s fmt.State, verb rune) {
   18     // Assuming this function is only called from the Format method, and given
   19     // that FormatError takes precedence over Format, it cannot be called from
   20     // any package that supports errors.Formatter. It is therefore safe to
   21     // disregard that State may be a specific printer implementation and use one
   22     // of our choice instead.
   23 
   24     // limitations: does not support printing error as Go struct.
   25 
   26     var (
   27         sep    = " " // separator before next error
   28         p      = &state{State: s}
   29         direct = true
   30     )
   31 
   32     var err error = f
   33 
   34     switch verb {
   35     // Note that this switch must match the preference order
   36     // for ordinary string printing (%#v before %+v, and so on).
   37 
   38     case 'v':
   39         if s.Flag('#') {
   40             if stringer, ok := err.(fmt.GoStringer); ok {
   41                 io.WriteString(&p.buf, stringer.GoString())
   42                 goto exit
   43             }
   44             // proceed as if it were %v
   45         } else if s.Flag('+') {
   46             p.printDetail = true
   47             sep = "\n  - "
   48         }
   49     case 's':
   50     case 'q', 'x', 'X':
   51         // Use an intermediate buffer in the rare cases that precision,
   52         // truncation, or one of the alternative verbs (q, x, and X) are
   53         // specified.
   54         direct = false
   55 
   56     default:
   57         p.buf.WriteString("%!")
   58         p.buf.WriteRune(verb)
   59         p.buf.WriteByte('(')
   60         switch {
   61         case err != nil:
   62             p.buf.WriteString(reflect.TypeOf(f).String())
   63         default:
   64             p.buf.WriteString("<nil>")
   65         }
   66         p.buf.WriteByte(')')
   67         io.Copy(s, &p.buf)
   68         return
   69     }
   70 
   71 loop:
   72     for {
   73         switch v := err.(type) {
   74         case Formatter:
   75             err = v.FormatError((*printer)(p))
   76         case fmt.Formatter:
   77             v.Format(p, 'v')
   78             break loop
   79         default:
   80             io.WriteString(&p.buf, v.Error())
   81             break loop
   82         }
   83         if err == nil {
   84             break
   85         }
   86         if p.needColon || !p.printDetail {
   87             p.buf.WriteByte(':')
   88             p.needColon = false
   89         }
   90         p.buf.WriteString(sep)
   91         p.inDetail = false
   92         p.needNewline = false
   93     }
   94 
   95 exit:
   96     width, okW := s.Width()
   97     prec, okP := s.Precision()
   98 
   99     if !direct || (okW && width > 0) || okP {
  100         // Construct format string from State s.
  101         format := []byte{'%'}
  102         if s.Flag('-') {
  103             format = append(format, '-')
  104         }
  105         if s.Flag('+') {
  106             format = append(format, '+')
  107         }
  108         if s.Flag(' ') {
  109             format = append(format, ' ')
  110         }
  111         if okW {
  112             format = strconv.AppendInt(format, int64(width), 10)
  113         }
  114         if okP {
  115             format = append(format, '.')
  116             format = strconv.AppendInt(format, int64(prec), 10)
  117         }
  118         format = append(format, string(verb)...)
  119         fmt.Fprintf(s, string(format), p.buf.String())
  120     } else {
  121         io.Copy(s, &p.buf)
  122     }
  123 }
  124 
  125 var detailSep = []byte("\n    ")
  126 
  127 // state tracks error printing state. It implements fmt.State.
  128 type state struct {
  129     fmt.State
  130     buf bytes.Buffer
  131 
  132     printDetail bool
  133     inDetail    bool
  134     needColon   bool
  135     needNewline bool
  136 }
  137 
  138 func (s *state) Write(b []byte) (n int, err error) {
  139     if s.printDetail {
  140         if len(b) == 0 {
  141             return 0, nil
  142         }
  143         if s.inDetail && s.needColon {
  144             s.needNewline = true
  145             if b[0] == '\n' {
  146                 b = b[1:]
  147             }
  148         }
  149         k := 0
  150         for i, c := range b {
  151             if s.needNewline {
  152                 if s.inDetail && s.needColon {
  153                     s.buf.WriteByte(':')
  154                     s.needColon = false
  155                 }
  156                 s.buf.Write(detailSep)
  157                 s.needNewline = false
  158             }
  159             if c == '\n' {
  160                 s.buf.Write(b[k:i])
  161                 k = i + 1
  162                 s.needNewline = true
  163             }
  164         }
  165         s.buf.Write(b[k:])
  166         if !s.inDetail {
  167             s.needColon = true
  168         }
  169     } else if !s.inDetail {
  170         s.buf.Write(b)
  171     }
  172     return len(b), nil
  173 }
  174 
  175 // printer wraps a state to implement an xerrors.Printer.
  176 type printer state
  177 
  178 func (s *printer) Print(args ...interface{}) {
  179     if !s.inDetail || s.printDetail {
  180         fmt.Fprint((*state)(s), args...)
  181     }
  182 }
  183 
  184 func (s *printer) Printf(format string, args ...interface{}) {
  185     if !s.inDetail || s.printDetail {
  186         fmt.Fprintf((*state)(s), format, args...)
  187     }
  188 }
  189 
  190 func (s *printer) Detail() bool {
  191     s.inDetail = true
  192     return s.printDetail
  193 }