golang.org/x/tools@v0.21.0/go/analysis/passes/printf/doc.go (about)

     1  // Copyright 2023 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 printf defines an Analyzer that checks consistency
     6  // of Printf format strings and arguments.
     7  //
     8  // # Analyzer printf
     9  //
    10  // printf: check consistency of Printf format strings and arguments
    11  //
    12  // The check applies to calls of the formatting functions such as
    13  // [fmt.Printf] and [fmt.Sprintf], as well as any detected wrappers of
    14  // those functions such as [log.Printf]. It reports a variety of
    15  // mistakes such as syntax errors in the format string and mismatches
    16  // (of number and type) between the verbs and their arguments.
    17  //
    18  // See the documentation of the fmt package for the complete set of
    19  // format operators and their operand types.
    20  //
    21  // # Examples
    22  //
    23  // The %d format operator requires an integer operand.
    24  // Here it is incorrectly applied to a string:
    25  //
    26  //	fmt.Printf("%d", "hello") // fmt.Printf format %d has arg "hello" of wrong type string
    27  //
    28  // A call to Printf must have as many operands as there are "verbs" in
    29  // the format string, not too few:
    30  //
    31  //	fmt.Printf("%d") // fmt.Printf format reads arg 1, but call has 0 args
    32  //
    33  // nor too many:
    34  //
    35  //	fmt.Printf("%d", 1, 2) // fmt.Printf call needs 1 arg, but has 2 args
    36  //
    37  // Explicit argument indexes must be no greater than the number of
    38  // arguments:
    39  //
    40  //	fmt.Printf("%[3]d", 1, 2) // fmt.Printf call has invalid argument index 3
    41  //
    42  // The checker also uses a heuristic to report calls to Print-like
    43  // functions that appear to have been intended for their Printf-like
    44  // counterpart:
    45  //
    46  //	log.Print("%d", 123) // log.Print call has possible formatting directive %d
    47  //
    48  // # Inferred printf wrappers
    49  //
    50  // Functions that delegate their arguments to fmt.Printf are
    51  // considered "printf wrappers"; calls to them are subject to the same
    52  // checking. In this example, logf is a printf wrapper:
    53  //
    54  //	func logf(level int, format string, args ...any) {
    55  //		if enabled(level) {
    56  //			log.Printf(format, args...)
    57  //		}
    58  //	}
    59  //
    60  //	logf(3, "invalid request: %v") // logf format reads arg 1, but call has 0 args
    61  //
    62  // To enable printf checking on a function that is not found by this
    63  // analyzer's heuristics (for example, because control is obscured by
    64  // dynamic method calls), insert a bogus call:
    65  //
    66  //	func MyPrintf(format string, args ...any) {
    67  //		if false {
    68  //			_ = fmt.Sprintf(format, args...) // enable printf checking
    69  //		}
    70  //		...
    71  //	}
    72  //
    73  // # Specifying printf wrappers by flag
    74  //
    75  // The -funcs flag specifies a comma-separated list of names of
    76  // additional known formatting functions or methods. (This legacy flag
    77  // is rarely used due to the automatic inference described above.)
    78  //
    79  // If the name contains a period, it must denote a specific function
    80  // using one of the following forms:
    81  //
    82  //	dir/pkg.Function
    83  //	dir/pkg.Type.Method
    84  //	(*dir/pkg.Type).Method
    85  //
    86  // Otherwise the name is interpreted as a case-insensitive unqualified
    87  // identifier such as "errorf". Either way, if a listed name ends in f, the
    88  // function is assumed to be Printf-like, taking a format string before the
    89  // argument list. Otherwise it is assumed to be Print-like, taking a list
    90  // of arguments with no format string.
    91  package printf