|
11 | 11 | //
|
12 | 12 | // The check applies to calls of the formatting functions such as
|
13 | 13 | // [fmt.Printf] and [fmt.Sprintf], as well as any detected wrappers of
|
14 |
| -// those functions. |
| 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. |
15 | 17 | //
|
16 |
| -// In this example, the %d format operator requires an integer operand: |
| 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: |
17 | 25 | //
|
18 | 26 | // fmt.Printf("%d", "hello") // fmt.Printf format %d has arg "hello" of wrong type string
|
19 | 27 | //
|
20 |
| -// See the documentation of the fmt package for the complete set of |
21 |
| -// format operators and their operand types. |
| 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 |
22 | 61 | //
|
23 | 62 | // To enable printf checking on a function that is not found by this
|
24 | 63 | // analyzer's heuristics (for example, because control is obscured by
|
25 | 64 | // dynamic method calls), insert a bogus call:
|
26 | 65 | //
|
27 | 66 | // func MyPrintf(format string, args ...any) {
|
28 | 67 | // if false {
|
29 |
| -// _ = fmt.Sprintf(format, args...) // enable printf checker |
| 68 | +// _ = fmt.Sprintf(format, args...) // enable printf checking |
30 | 69 | // }
|
31 | 70 | // ...
|
32 | 71 | // }
|
33 | 72 | //
|
34 |
| -// The -funcs flag specifies a comma-separated list of names of additional |
35 |
| -// known formatting functions or methods. If the name contains a period, |
36 |
| -// it must denote a specific function using one of the following forms: |
| 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: |
37 | 81 | //
|
38 | 82 | // dir/pkg.Function
|
39 | 83 | // dir/pkg.Type.Method
|
|
0 commit comments