printf

package
v0.28.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 4, 2024 License: BSD-3-Clause Imports: 19 Imported by: 325

Documentation

Overview

Package printf defines an Analyzer that checks consistency of Printf format strings and arguments.

Analyzer printf

printf: check consistency of Printf format strings and arguments

The check applies to calls of the formatting functions such as fmt.Printf and fmt.Sprintf, as well as any detected wrappers of those functions such as log.Printf. It reports a variety of mistakes such as syntax errors in the format string and mismatches (of number and type) between the verbs and their arguments.

See the documentation of the fmt package for the complete set of format operators and their operand types.

Examples

The %d format operator requires an integer operand. Here it is incorrectly applied to a string:

fmt.Printf("%d", "hello") // fmt.Printf format %d has arg "hello" of wrong type string

A call to Printf must have as many operands as there are "verbs" in the format string, not too few:

fmt.Printf("%d") // fmt.Printf format reads arg 1, but call has 0 args

nor too many:

fmt.Printf("%d", 1, 2) // fmt.Printf call needs 1 arg, but has 2 args

Explicit argument indexes must be no greater than the number of arguments:

fmt.Printf("%[3]d", 1, 2) // fmt.Printf call has invalid argument index 3

The checker also uses a heuristic to report calls to Print-like functions that appear to have been intended for their Printf-like counterpart:

log.Print("%d", 123) // log.Print call has possible formatting directive %d

Conversely, it also reports calls to Printf-like functions with a non-constant format string and no other arguments:

fmt.Printf(message) // non-constant format string in call to fmt.Printf

Such calls may have been intended for the function's Print-like counterpart: if the value of message happens to contain "%", misformatting will occur. In this case, the checker additionally suggests a fix to turn the call into:

fmt.Printf("%s", message)

Inferred printf wrappers

Functions that delegate their arguments to fmt.Printf are considered "printf wrappers"; calls to them are subject to the same checking. In this example, logf is a printf wrapper:

func logf(level int, format string, args ...any) {
	if enabled(level) {
		log.Printf(format, args...)
	}
}

logf(3, "invalid request: %v") // logf format reads arg 1, but call has 0 args

To enable printf checking on a function that is not found by this analyzer's heuristics (for example, because control is obscured by dynamic method calls), insert a bogus call:

func MyPrintf(format string, args ...any) {
	if false {
		_ = fmt.Sprintf(format, args...) // enable printf checking
	}
	...
}

Specifying printf wrappers by flag

The -funcs flag specifies a comma-separated list of names of additional known formatting functions or methods. (This legacy flag is rarely used due to the automatic inference described above.)

If the name contains a period, it must denote a specific function using one of the following forms:

dir/pkg.Function
dir/pkg.Type.Method
(*dir/pkg.Type).Method

Otherwise the name is interpreted as a case-insensitive unqualified identifier such as "errorf". Either way, if a listed name ends in f, the function is assumed to be Printf-like, taking a format string before the argument list. Otherwise it is assumed to be Print-like, taking a list of arguments with no format string.

Index

Constants

This section is empty.

Variables

View Source
var Analyzer = &analysis.Analyzer{
	Name:       "printf",
	Doc:        analysisutil.MustExtractDoc(doc, "printf"),
	URL:        "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/printf",
	Requires:   []*analysis.Analyzer{inspect.Analyzer},
	Run:        run,
	ResultType: reflect.TypeOf((*Result)(nil)),
	FactTypes:  []analysis.Fact{new(isWrapper)},
}

Functions

This section is empty.

Types

type Kind

type Kind int

Kind is a kind of fmt function behavior.

const (
	KindNone   Kind = iota // not a fmt wrapper function
	KindPrint              // function behaves like fmt.Print
	KindPrintf             // function behaves like fmt.Printf
	KindErrorf             // function behaves like fmt.Errorf
)

func (Kind) String

func (kind Kind) String() string

type Result

type Result struct {
	// contains filtered or unexported fields
}

Result is the printf analyzer's result type. Clients may query the result to learn whether a function behaves like fmt.Print or fmt.Printf.

func (*Result) Kind

func (r *Result) Kind(fn *types.Func) Kind

Kind reports whether fn behaves like fmt.Print or fmt.Printf.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL