A go tool to help with adding and removing printf
debug statements
I created this to learn golang and because while working on another project I was very confused by a wall of output produced by a panic
from within a goroutine from within a library dependency.
I don't know how to use go debug tools.
CLI Usage
Organized debugging using printf statements
Usage:
printfdebug [command]
Available Commands:
add Add printf debug statements to all functions.
completion Generate the autocompletion script for the specified shell
help Help about any command
remove Remove printf debug statements in all locations that this tool previously added them to.
Flags:
-f, --file string The file path.
-h, --help help for printfdebug
-n, --no-runtime Disable the injection of the printfdebug function definition into your file. The alternative is a simple fmt.Printf statement.
-o, --out-file write An optional output file. Cannot be used with write
-d, --path-depth no-runtime Is only taken into account if no-runtime is not set. The depth of the directory tree to print from the printf function. Defaults to only the current file name. (default 1)
-w, --write If specified, the file on disk is overwritten. The default is to output to stdout.
Use "printfdebug [command] --help" for more information about a command.
- Modifies your code by adding
printf
statements upon entering and exiting functions - Captures all function exits branches, panics, system exits, and fatal logs
- Optionally injects a function to help print the current file name and line number (if anyone knows a way of doing this on a single line, I could remove this feature completely!)
- Support all functions (that I know of)
- functions stored as variables (uses variable name as function name)
- struct methods
- anonymous functions
- declared functions
- nested functions
- immediately invoked functions
- Idempotent operations.
- Running
printfdebug add
multiple times on the same input produces sane results - Running
printfdebug add
on code that's been modified since the last run updates the code to add newprintf
statements - Running
printfdebug remove
cleans up all traces of the debugger
- Running
- Complex control flow analysis to avoid extraneous placement of printf statements
- Working with custom code bases that have modified the standard library
- Go fmt automatically (or does dst alreadu handle that?)
- Optional message formatting (before and after function with linenum and name as template vars)
- Optional list of excluded or included function names
- Clean up TODO's in code
To add a new test
- Make your changes
- Create a new file in internal/testassets
- Run
go run internal/tests/gen_tests/gen_tests.go
to generate the output according to the current state of the package. This will:- Do a rebuild of the cli and overwrite the file
printfdebug
in the root of the repo - Generate output for each file in internal/tests/testassets for the standard case and
no-runtime
case - Generate a test for each case and write to internal/ast_test.go
- Do a rebuild of the cli and overwrite the file
- Make sure the outputs in internal/tests/testassets/results/noruntime and internal/tests/testassets/results/runtime are correct (otherwise go back to step 1 and iterate)
- Run
go test -v internal/ast_test.go
from the root directory (right now things are very path dependent)
The readme is generated automatically to inject examples and CLI usage.
After adding tests or modifying the CLI, run go run internal/readme/gen_readme.go
Do not make changed directly to the README.md
file. Only ever make changes to the file README_template.md
and regenerate.
The below examples are generated automatically from test results
Anonymous Function (No Runtime)
Running printfdebug --file internal/tests/testassets/AnonymousFunc.go add --no-runtime
On a file containing
package testassest
func AnonymousFunc() {
func() {
}()
}
Will produce the following result
package testassest
import "fmt"
func AnonymousFunc() {
fmt.Println("Entering \"AnonymousFunc\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
func() {
fmt.Println("Entering \"anonymous-function Fun\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
fmt.Println("Leaving \"anonymous-function Fun\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}()
fmt.Println("Leaving \"AnonymousFunc\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
Anonymous Function (With Runtime)
Running printfdebug --file internal/tests/testassets/AnonymousFunc.go add
On a file containing
package testassest
func AnonymousFunc() {
func() {
}()
}
Will produce the following result
package testassest
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
)
func AnonymousFunc() {
printfdebug_Printf_AnonymousFunc("Entering \"AnonymousFunc\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
func() {
printfdebug_Printf_AnonymousFunc("Entering \"anonymous-function Fun\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
printfdebug_Printf_AnonymousFunc("Leaving \"anonymous-function Fun\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}()
printfdebug_Printf_AnonymousFunc("Leaving \"AnonymousFunc\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
var _ = strings.Split // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = os.PathSeparator // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = runtime.Caller // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = filepath.Clean // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = fmt.Println // automatically added by printf-debugger. Do not change this comment. It is an identifier.
func printfdebug_Printf_AnonymousFunc(message string, pathDepthFromEnd int) {
minInt := func(first int, second int) (min int) {
if first < second {
return first
} else {
return second
}
}
_, file, line, ok := runtime.Caller(1)
if ok {
fileParts := strings.Split(file, string(os.PathSeparator))
pathFromEndSafe := minInt(len(fileParts), pathDepthFromEnd)
limited := filepath.Join(fileParts[len(fileParts)-pathFromEndSafe:]...)
limitedCleaned := "??"
if limited != "" {
limitedCleaned = limited
}
fmt.Printf("%v:%v %v\n", limitedCleaned, line, message)
} else {
fmt.Printf("unkown_file:? %v\n", message)
}
}
Function (No Runtime)
Running printfdebug --file internal/tests/testassets/Func.go add --no-runtime
On a file containing
package testassest
func Func() {
}
Will produce the following result
package testassest
import "fmt"
func Func() {
fmt.Println("Entering \"Func\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
fmt.Println("Leaving \"Func\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
Function (With Runtime)
Running printfdebug --file internal/tests/testassets/Func.go add
On a file containing
package testassest
func Func() {
}
Will produce the following result
package testassest
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
)
func Func() {
printfdebug_Printf_Func("Entering \"Func\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
printfdebug_Printf_Func("Leaving \"Func\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
var _ = runtime.Caller // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = filepath.Clean // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = fmt.Println // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = strings.Split // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = os.PathSeparator // automatically added by printf-debugger. Do not change this comment. It is an identifier.
func printfdebug_Printf_Func(message string, pathDepthFromEnd int) {
minInt := func(first int, second int) (min int) {
if first < second {
return first
} else {
return second
}
}
_, file, line, ok := runtime.Caller(1)
if ok {
fileParts := strings.Split(file, string(os.PathSeparator))
pathFromEndSafe := minInt(len(fileParts), pathDepthFromEnd)
limited := filepath.Join(fileParts[len(fileParts)-pathFromEndSafe:]...)
limitedCleaned := "??"
if limited != "" {
limitedCleaned = limited
}
fmt.Printf("%v:%v %v\n", limitedCleaned, line, message)
} else {
fmt.Printf("unkown_file:? %v\n", message)
}
}
Function Immediately Invoked (No Runtime)
Running printfdebug --file internal/tests/testassets/FuncImmediatelyInvoked.go add --no-runtime
On a file containing
package testassest
var FuncImmediatelyInvoked = func() error {
return nil
}()
Will produce the following result
package testassest
import "fmt"
var FuncImmediatelyInvoked = func() error {
fmt.Println("Entering \"FuncImmediatelyInvoked\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
fmt.Println("Leaving \"FuncImmediatelyInvoked\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return nil
}()
Function Immediately Invoked (With Runtime)
Running printfdebug --file internal/tests/testassets/FuncImmediatelyInvoked.go add
On a file containing
package testassest
var FuncImmediatelyInvoked = func() error {
return nil
}()
Will produce the following result
package testassest
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
)
var FuncImmediatelyInvoked = func() error {
printfdebug_Printf_FuncImmediatelyInvoked("Entering \"FuncImmediatelyInvoked\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
printfdebug_Printf_FuncImmediatelyInvoked("Leaving \"FuncImmediatelyInvoked\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return nil
}()
var _ = filepath.Clean // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = fmt.Println // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = strings.Split // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = os.PathSeparator // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = runtime.Caller // automatically added by printf-debugger. Do not change this comment. It is an identifier.
func printfdebug_Printf_FuncImmediatelyInvoked(message string, pathDepthFromEnd int) {
minInt := func(first int, second int) (min int) {
if first < second {
return first
} else {
return second
}
}
_, file, line, ok := runtime.Caller(1)
if ok {
fileParts := strings.Split(file, string(os.PathSeparator))
pathFromEndSafe := minInt(len(fileParts), pathDepthFromEnd)
limited := filepath.Join(fileParts[len(fileParts)-pathFromEndSafe:]...)
limitedCleaned := "??"
if limited != "" {
limitedCleaned = limited
}
fmt.Printf("%v:%v %v\n", limitedCleaned, line, message)
} else {
fmt.Printf("unkown_file:? %v\n", message)
}
}
Function Log Fatal (No Runtime)
Running printfdebug --file internal/tests/testassets/FuncLogFatal.go add --no-runtime
On a file containing
package testassest
import (
"log"
)
func FuncLogFatal() {
log.Fatal(1)
}
func FuncLogFatalln() {
log.Fatalln(1)
}
func FuncLogFatalf() {
log.Fatalf("")
}
Will produce the following result
package testassest
import (
"fmt"
"log"
)
func FuncLogFatal() {
fmt.Println("Entering \"FuncLogFatal\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
fmt.Println("Leaving \"FuncLogFatal\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
log.Fatal(1)
fmt.Println("Leaving \"FuncLogFatal\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
func FuncLogFatalln() {
fmt.Println("Entering \"FuncLogFatalln\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
fmt.Println("Leaving \"FuncLogFatalln\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
log.Fatalln(1)
fmt.Println("Leaving \"FuncLogFatalln\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
func FuncLogFatalf() {
fmt.Println("Entering \"FuncLogFatalf\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
fmt.Println("Leaving \"FuncLogFatalf\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
log.Fatalf("")
fmt.Println("Leaving \"FuncLogFatalf\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
Function Log Fatal (With Runtime)
Running printfdebug --file internal/tests/testassets/FuncLogFatal.go add
On a file containing
package testassest
import (
"log"
)
func FuncLogFatal() {
log.Fatal(1)
}
func FuncLogFatalln() {
log.Fatalln(1)
}
func FuncLogFatalf() {
log.Fatalf("")
}
Will produce the following result
package testassest
import (
"fmt"
"log"
"os"
"path/filepath"
"runtime"
"strings"
)
func FuncLogFatal() {
printfdebug_Printf_FuncLogFatal("Entering \"FuncLogFatal\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
printfdebug_Printf_FuncLogFatal("Leaving \"FuncLogFatal\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
log.Fatal(1)
printfdebug_Printf_FuncLogFatal("Leaving \"FuncLogFatal\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
func FuncLogFatalln() {
printfdebug_Printf_FuncLogFatal("Entering \"FuncLogFatalln\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
printfdebug_Printf_FuncLogFatal("Leaving \"FuncLogFatalln\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
log.Fatalln(1)
printfdebug_Printf_FuncLogFatal("Leaving \"FuncLogFatalln\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
func FuncLogFatalf() {
printfdebug_Printf_FuncLogFatal("Entering \"FuncLogFatalf\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
printfdebug_Printf_FuncLogFatal("Leaving \"FuncLogFatalf\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
log.Fatalf("")
printfdebug_Printf_FuncLogFatal("Leaving \"FuncLogFatalf\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
var _ = runtime.Caller // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = filepath.Clean // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = fmt.Println // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = strings.Split // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = os.PathSeparator // automatically added by printf-debugger. Do not change this comment. It is an identifier.
func printfdebug_Printf_FuncLogFatal(message string, pathDepthFromEnd int) {
minInt := func(first int, second int) (min int) {
if first < second {
return first
} else {
return second
}
}
_, file, line, ok := runtime.Caller(1)
if ok {
fileParts := strings.Split(file, string(os.PathSeparator))
pathFromEndSafe := minInt(len(fileParts), pathDepthFromEnd)
limited := filepath.Join(fileParts[len(fileParts)-pathFromEndSafe:]...)
limitedCleaned := "??"
if limited != "" {
limitedCleaned = limited
}
fmt.Printf("%v:%v %v\n", limitedCleaned, line, message)
} else {
fmt.Printf("unkown_file:? %v\n", message)
}
}
Function Os Exit (No Runtime)
Running printfdebug --file internal/tests/testassets/FuncOsExit.go add --no-runtime
On a file containing
package testassest
import "os"
func FuncOsExit() {
os.Exit(1)
}
Will produce the following result
package testassest
import (
"fmt"
"os"
)
func FuncOsExit() {
fmt.Println("Entering \"FuncOsExit\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
fmt.Println("Leaving \"FuncOsExit\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
os.Exit(1)
fmt.Println("Leaving \"FuncOsExit\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
Function Os Exit (With Runtime)
Running printfdebug --file internal/tests/testassets/FuncOsExit.go add
On a file containing
package testassest
import "os"
func FuncOsExit() {
os.Exit(1)
}
Will produce the following result
package testassest
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
)
func FuncOsExit() {
printfdebug_Printf_FuncOsExit("Entering \"FuncOsExit\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
printfdebug_Printf_FuncOsExit("Leaving \"FuncOsExit\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
os.Exit(1)
printfdebug_Printf_FuncOsExit("Leaving \"FuncOsExit\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
var _ = fmt.Println // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = strings.Split // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = os.PathSeparator // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = runtime.Caller // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = filepath.Clean // automatically added by printf-debugger. Do not change this comment. It is an identifier.
func printfdebug_Printf_FuncOsExit(message string, pathDepthFromEnd int) {
minInt := func(first int, second int) (min int) {
if first < second {
return first
} else {
return second
}
}
_, file, line, ok := runtime.Caller(1)
if ok {
fileParts := strings.Split(file, string(os.PathSeparator))
pathFromEndSafe := minInt(len(fileParts), pathDepthFromEnd)
limited := filepath.Join(fileParts[len(fileParts)-pathFromEndSafe:]...)
limitedCleaned := "??"
if limited != "" {
limitedCleaned = limited
}
fmt.Printf("%v:%v %v\n", limitedCleaned, line, message)
} else {
fmt.Printf("unkown_file:? %v\n", message)
}
}
Function Panic (No Runtime)
Running printfdebug --file internal/tests/testassets/FuncPanic.go add --no-runtime
On a file containing
package testassest
func FuncPanic() {
panic("Oh no, how will we know how we got here?")
return
}
Will produce the following result
package testassest
import "fmt"
func FuncPanic() {
fmt.Println("Entering \"FuncPanic\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
fmt.Println("Leaving \"FuncPanic\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
panic("Oh no, how will we know how we got here?")
fmt.Println("Leaving \"FuncPanic\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return
}
Function Panic (With Runtime)
Running printfdebug --file internal/tests/testassets/FuncPanic.go add
On a file containing
package testassest
func FuncPanic() {
panic("Oh no, how will we know how we got here?")
return
}
Will produce the following result
package testassest
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
)
func FuncPanic() {
printfdebug_Printf_FuncPanic("Entering \"FuncPanic\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
printfdebug_Printf_FuncPanic("Leaving \"FuncPanic\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
panic("Oh no, how will we know how we got here?")
printfdebug_Printf_FuncPanic("Leaving \"FuncPanic\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return
}
var _ = strings.Split // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = os.PathSeparator // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = runtime.Caller // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = filepath.Clean // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = fmt.Println // automatically added by printf-debugger. Do not change this comment. It is an identifier.
func printfdebug_Printf_FuncPanic(message string, pathDepthFromEnd int) {
minInt := func(first int, second int) (min int) {
if first < second {
return first
} else {
return second
}
}
_, file, line, ok := runtime.Caller(1)
if ok {
fileParts := strings.Split(file, string(os.PathSeparator))
pathFromEndSafe := minInt(len(fileParts), pathDepthFromEnd)
limited := filepath.Join(fileParts[len(fileParts)-pathFromEndSafe:]...)
limitedCleaned := "??"
if limited != "" {
limitedCleaned = limited
}
fmt.Printf("%v:%v %v\n", limitedCleaned, line, message)
} else {
fmt.Printf("unkown_file:? %v\n", message)
}
}
Function Stored As Variable (No Runtime)
Running printfdebug --file internal/tests/testassets/FuncStoredAsVar.go add --no-runtime
On a file containing
package testassest
var FuncStoredAsVar = func() error {
return nil
}
Will produce the following result
package testassest
import "fmt"
var FuncStoredAsVar = func() error {
fmt.Println("Entering \"FuncStoredAsVar\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
fmt.Println("Leaving \"FuncStoredAsVar\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return nil
}
Function Stored As Variable (With Runtime)
Running printfdebug --file internal/tests/testassets/FuncStoredAsVar.go add
On a file containing
package testassest
var FuncStoredAsVar = func() error {
return nil
}
Will produce the following result
package testassest
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
)
var FuncStoredAsVar = func() error {
printfdebug_Printf_FuncStoredAsVar("Entering \"FuncStoredAsVar\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
printfdebug_Printf_FuncStoredAsVar("Leaving \"FuncStoredAsVar\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return nil
}
var _ = runtime.Caller // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = filepath.Clean // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = fmt.Println // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = strings.Split // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = os.PathSeparator // automatically added by printf-debugger. Do not change this comment. It is an identifier.
func printfdebug_Printf_FuncStoredAsVar(message string, pathDepthFromEnd int) {
minInt := func(first int, second int) (min int) {
if first < second {
return first
} else {
return second
}
}
_, file, line, ok := runtime.Caller(1)
if ok {
fileParts := strings.Split(file, string(os.PathSeparator))
pathFromEndSafe := minInt(len(fileParts), pathDepthFromEnd)
limited := filepath.Join(fileParts[len(fileParts)-pathFromEndSafe:]...)
limitedCleaned := "??"
if limited != "" {
limitedCleaned = limited
}
fmt.Printf("%v:%v %v\n", limitedCleaned, line, message)
} else {
fmt.Printf("unkown_file:? %v\n", message)
}
}
Function Stored As Variable Assignment (No Runtime)
Running printfdebug --file internal/tests/testassets/FuncStoredAsVarAssignment.go add --no-runtime
On a file containing
package testassest
func FuncStoredAsVarAssignment() {
FuncStoredAsVarInnerSingle := func() error {
return nil
}
FuncStoredAsVarInnerMulti, _ := func() error {
return nil
}, ""
_ = FuncStoredAsVarInnerMulti
_ = FuncStoredAsVarInnerSingle
}
Will produce the following result
package testassest
import "fmt"
func FuncStoredAsVarAssignment() {
fmt.Println("Entering \"FuncStoredAsVarAssignment\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
FuncStoredAsVarInnerSingle := func() error {
fmt.Println("Entering \"FuncStoredAsVarInnerSingle\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
fmt.Println("Leaving \"FuncStoredAsVarInnerSingle\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return nil
}
FuncStoredAsVarInnerMulti, _ := func() error {
fmt.Println("Entering \"FuncStoredAsVarInnerMulti\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
fmt.Println("Leaving \"FuncStoredAsVarInnerMulti\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return nil
}, ""
_ = FuncStoredAsVarInnerMulti
_ = FuncStoredAsVarInnerSingle
fmt.Println("Leaving \"FuncStoredAsVarAssignment\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
Function Stored As Variable Assignment (With Runtime)
Running printfdebug --file internal/tests/testassets/FuncStoredAsVarAssignment.go add
On a file containing
package testassest
func FuncStoredAsVarAssignment() {
FuncStoredAsVarInnerSingle := func() error {
return nil
}
FuncStoredAsVarInnerMulti, _ := func() error {
return nil
}, ""
_ = FuncStoredAsVarInnerMulti
_ = FuncStoredAsVarInnerSingle
}
Will produce the following result
package testassest
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
)
func FuncStoredAsVarAssignment() {
printfdebug_Printf_FuncStoredAsVarAssignment("Entering \"FuncStoredAsVarAssignment\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
FuncStoredAsVarInnerSingle := func() error {
printfdebug_Printf_FuncStoredAsVarAssignment("Entering \"FuncStoredAsVarInnerSingle\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
printfdebug_Printf_FuncStoredAsVarAssignment("Leaving \"FuncStoredAsVarInnerSingle\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return nil
}
FuncStoredAsVarInnerMulti, _ := func() error {
printfdebug_Printf_FuncStoredAsVarAssignment("Entering \"FuncStoredAsVarInnerMulti\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
printfdebug_Printf_FuncStoredAsVarAssignment("Leaving \"FuncStoredAsVarInnerMulti\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return nil
}, ""
_ = FuncStoredAsVarInnerMulti
_ = FuncStoredAsVarInnerSingle
printfdebug_Printf_FuncStoredAsVarAssignment("Leaving \"FuncStoredAsVarAssignment\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
var _ = runtime.Caller // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = filepath.Clean // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = fmt.Println // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = strings.Split // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = os.PathSeparator // automatically added by printf-debugger. Do not change this comment. It is an identifier.
func printfdebug_Printf_FuncStoredAsVarAssignment(message string, pathDepthFromEnd int) {
minInt := func(first int, second int) (min int) {
if first < second {
return first
} else {
return second
}
}
_, file, line, ok := runtime.Caller(1)
if ok {
fileParts := strings.Split(file, string(os.PathSeparator))
pathFromEndSafe := minInt(len(fileParts), pathDepthFromEnd)
limited := filepath.Join(fileParts[len(fileParts)-pathFromEndSafe:]...)
limitedCleaned := "??"
if limited != "" {
limitedCleaned = limited
}
fmt.Printf("%v:%v %v\n", limitedCleaned, line, message)
} else {
fmt.Printf("unkown_file:? %v\n", message)
}
}
Function Stored As Variable Value Spec (No Runtime)
Running printfdebug --file internal/tests/testassets/FuncStoredAsVarValueSpec.go add --no-runtime
On a file containing
package testassest
func FuncStoredAsVarValueSpec() {
var FuncStoredAsVarInnerSingle = func() error {
return nil
}
var FuncStoredAsVarInnerMutli, _ = func() error {
return nil
}, ""
_ = FuncStoredAsVarInnerSingle
_ = FuncStoredAsVarInnerMutli
}
Will produce the following result
package testassest
import "fmt"
func FuncStoredAsVarValueSpec() {
fmt.Println("Entering \"FuncStoredAsVarValueSpec\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var FuncStoredAsVarInnerSingle = func() error {
fmt.Println("Entering \"FuncStoredAsVarInnerSingle\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
fmt.Println("Leaving \"FuncStoredAsVarInnerSingle\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return nil
}
var FuncStoredAsVarInnerMutli, _ = func() error {
fmt.Println("Entering \"FuncStoredAsVarInnerMutli\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
fmt.Println("Leaving \"FuncStoredAsVarInnerMutli\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return nil
}, ""
_ = FuncStoredAsVarInnerSingle
_ = FuncStoredAsVarInnerMutli
fmt.Println("Leaving \"FuncStoredAsVarValueSpec\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
Function Stored As Variable Value Spec (With Runtime)
Running printfdebug --file internal/tests/testassets/FuncStoredAsVarValueSpec.go add
On a file containing
package testassest
func FuncStoredAsVarValueSpec() {
var FuncStoredAsVarInnerSingle = func() error {
return nil
}
var FuncStoredAsVarInnerMutli, _ = func() error {
return nil
}, ""
_ = FuncStoredAsVarInnerSingle
_ = FuncStoredAsVarInnerMutli
}
Will produce the following result
package testassest
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
)
func FuncStoredAsVarValueSpec() {
printfdebug_Printf_FuncStoredAsVarValueSpec("Entering \"FuncStoredAsVarValueSpec\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var FuncStoredAsVarInnerSingle = func() error {
printfdebug_Printf_FuncStoredAsVarValueSpec("Entering \"FuncStoredAsVarInnerSingle\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
printfdebug_Printf_FuncStoredAsVarValueSpec("Leaving \"FuncStoredAsVarInnerSingle\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return nil
}
var FuncStoredAsVarInnerMutli, _ = func() error {
printfdebug_Printf_FuncStoredAsVarValueSpec("Entering \"FuncStoredAsVarInnerMutli\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
printfdebug_Printf_FuncStoredAsVarValueSpec("Leaving \"FuncStoredAsVarInnerMutli\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return nil
}, ""
_ = FuncStoredAsVarInnerSingle
_ = FuncStoredAsVarInnerMutli
printfdebug_Printf_FuncStoredAsVarValueSpec("Leaving \"FuncStoredAsVarValueSpec\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
var _ = filepath.Clean // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = fmt.Println // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = strings.Split // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = os.PathSeparator // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = runtime.Caller // automatically added by printf-debugger. Do not change this comment. It is an identifier.
func printfdebug_Printf_FuncStoredAsVarValueSpec(message string, pathDepthFromEnd int) {
minInt := func(first int, second int) (min int) {
if first < second {
return first
} else {
return second
}
}
_, file, line, ok := runtime.Caller(1)
if ok {
fileParts := strings.Split(file, string(os.PathSeparator))
pathFromEndSafe := minInt(len(fileParts), pathDepthFromEnd)
limited := filepath.Join(fileParts[len(fileParts)-pathFromEndSafe:]...)
limitedCleaned := "??"
if limited != "" {
limitedCleaned = limited
}
fmt.Printf("%v:%v %v\n", limitedCleaned, line, message)
} else {
fmt.Printf("unkown_file:? %v\n", message)
}
}
Function With Arguments And Return (No Runtime)
Running printfdebug --file internal/tests/testassets/FuncWithArgsAndReturn.go add --no-runtime
On a file containing
package testassest
func FuncWithArgsAndReturn(s2 string) error {
// this is a comment on its own line
/*
This is a multi line
comment
*/
return nil //This is inline comment
}
Will produce the following result
package testassest
import "fmt"
func FuncWithArgsAndReturn(s2 string) error {
fmt.Println("Entering \"FuncWithArgsAndReturn\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
fmt.Println("Leaving \"FuncWithArgsAndReturn\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
// this is a comment on its own line
/*
This is a multi line
comment
*/
return nil //This is inline comment
}
Function With Arguments And Return (With Runtime)
Running printfdebug --file internal/tests/testassets/FuncWithArgsAndReturn.go add
On a file containing
package testassest
func FuncWithArgsAndReturn(s2 string) error {
// this is a comment on its own line
/*
This is a multi line
comment
*/
return nil //This is inline comment
}
Will produce the following result
package testassest
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
)
func FuncWithArgsAndReturn(s2 string) error {
printfdebug_Printf_FuncWithArgsAndReturn("Entering \"FuncWithArgsAndReturn\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
printfdebug_Printf_FuncWithArgsAndReturn("Leaving \"FuncWithArgsAndReturn\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
// this is a comment on its own line
/*
This is a multi line
comment
*/
return nil //This is inline comment
}
var _ = runtime.Caller // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = filepath.Clean // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = fmt.Println // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = strings.Split // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = os.PathSeparator // automatically added by printf-debugger. Do not change this comment. It is an identifier.
func printfdebug_Printf_FuncWithArgsAndReturn(message string, pathDepthFromEnd int) {
minInt := func(first int, second int) (min int) {
if first < second {
return first
} else {
return second
}
}
_, file, line, ok := runtime.Caller(1)
if ok {
fileParts := strings.Split(file, string(os.PathSeparator))
pathFromEndSafe := minInt(len(fileParts), pathDepthFromEnd)
limited := filepath.Join(fileParts[len(fileParts)-pathFromEndSafe:]...)
limitedCleaned := "??"
if limited != "" {
limitedCleaned = limited
}
fmt.Printf("%v:%v %v\n", limitedCleaned, line, message)
} else {
fmt.Printf("unkown_file:? %v\n", message)
}
}
Function With Explicit Return (No Runtime)
Running printfdebug --file internal/tests/testassets/FuncWithExplicitReturn.go add --no-runtime
On a file containing
package testassest
func FuncWithExplicitReturn() {
return
}
Will produce the following result
package testassest
import "fmt"
func FuncWithExplicitReturn() {
fmt.Println("Entering \"FuncWithExplicitReturn\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
fmt.Println("Leaving \"FuncWithExplicitReturn\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return
}
Function With Explicit Return (With Runtime)
Running printfdebug --file internal/tests/testassets/FuncWithExplicitReturn.go add
On a file containing
package testassest
func FuncWithExplicitReturn() {
return
}
Will produce the following result
package testassest
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
)
func FuncWithExplicitReturn() {
printfdebug_Printf_FuncWithExplicitReturn("Entering \"FuncWithExplicitReturn\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
printfdebug_Printf_FuncWithExplicitReturn("Leaving \"FuncWithExplicitReturn\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return
}
var _ = strings.Split // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = os.PathSeparator // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = runtime.Caller // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = filepath.Clean // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = fmt.Println // automatically added by printf-debugger. Do not change this comment. It is an identifier.
func printfdebug_Printf_FuncWithExplicitReturn(message string, pathDepthFromEnd int) {
minInt := func(first int, second int) (min int) {
if first < second {
return first
} else {
return second
}
}
_, file, line, ok := runtime.Caller(1)
if ok {
fileParts := strings.Split(file, string(os.PathSeparator))
pathFromEndSafe := minInt(len(fileParts), pathDepthFromEnd)
limited := filepath.Join(fileParts[len(fileParts)-pathFromEndSafe:]...)
limitedCleaned := "??"
if limited != "" {
limitedCleaned = limited
}
fmt.Printf("%v:%v %v\n", limitedCleaned, line, message)
} else {
fmt.Printf("unkown_file:? %v\n", message)
}
}
Function With Many Return Statements (No Runtime)
Running printfdebug --file internal/tests/testassets/FuncWithManyReturnStatements.go add --no-runtime
On a file containing
package testassest
func FuncWithManyReturnStatements() {
if false {
return
}
if false {
return
}
if false {
return
}
}
Will produce the following result
package testassest
import "fmt"
func FuncWithManyReturnStatements() {
fmt.Println("Entering \"FuncWithManyReturnStatements\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
if false {
fmt.Println("Leaving \"FuncWithManyReturnStatements\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return
}
if false {
fmt.Println("Leaving \"FuncWithManyReturnStatements\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return
}
if false {
fmt.Println("Leaving \"FuncWithManyReturnStatements\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return
}
fmt.Println("Leaving \"FuncWithManyReturnStatements\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
Function With Many Return Statements (With Runtime)
Running printfdebug --file internal/tests/testassets/FuncWithManyReturnStatements.go add
On a file containing
package testassest
func FuncWithManyReturnStatements() {
if false {
return
}
if false {
return
}
if false {
return
}
}
Will produce the following result
package testassest
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
)
func FuncWithManyReturnStatements() {
printfdebug_Printf_FuncWithManyReturnStatements("Entering \"FuncWithManyReturnStatements\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
if false {
printfdebug_Printf_FuncWithManyReturnStatements("Leaving \"FuncWithManyReturnStatements\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return
}
if false {
printfdebug_Printf_FuncWithManyReturnStatements("Leaving \"FuncWithManyReturnStatements\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return
}
if false {
printfdebug_Printf_FuncWithManyReturnStatements("Leaving \"FuncWithManyReturnStatements\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return
}
printfdebug_Printf_FuncWithManyReturnStatements("Leaving \"FuncWithManyReturnStatements\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
var _ = runtime.Caller // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = filepath.Clean // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = fmt.Println // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = strings.Split // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = os.PathSeparator // automatically added by printf-debugger. Do not change this comment. It is an identifier.
func printfdebug_Printf_FuncWithManyReturnStatements(message string, pathDepthFromEnd int) {
minInt := func(first int, second int) (min int) {
if first < second {
return first
} else {
return second
}
}
_, file, line, ok := runtime.Caller(1)
if ok {
fileParts := strings.Split(file, string(os.PathSeparator))
pathFromEndSafe := minInt(len(fileParts), pathDepthFromEnd)
limited := filepath.Join(fileParts[len(fileParts)-pathFromEndSafe:]...)
limitedCleaned := "??"
if limited != "" {
limitedCleaned = limited
}
fmt.Printf("%v:%v %v\n", limitedCleaned, line, message)
} else {
fmt.Printf("unkown_file:? %v\n", message)
}
}
Function With Nested Anonymous Functions (No Runtime)
Running printfdebug --file internal/tests/testassets/FuncWithNestedAnonymousFuncs.go add --no-runtime
On a file containing
package testassest
func FuncWithNestedAnonymousFuncs() {
innerFunc := func() {
nestedInnerFunc := func() {}
nestedInnerFunc()
}
_ = innerFunc
}
Will produce the following result
package testassest
import "fmt"
func FuncWithNestedAnonymousFuncs() {
fmt.Println("Entering \"FuncWithNestedAnonymousFuncs\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
innerFunc := func() {
fmt.Println("Entering \"innerFunc\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
nestedInnerFunc := func() {
fmt.Println("Entering \"nestedInnerFunc\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
fmt.Println("Leaving \"nestedInnerFunc\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
nestedInnerFunc()
fmt.Println("Leaving \"innerFunc\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
_ = innerFunc
fmt.Println("Leaving \"FuncWithNestedAnonymousFuncs\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
Function With Nested Anonymous Functions (With Runtime)
Running printfdebug --file internal/tests/testassets/FuncWithNestedAnonymousFuncs.go add
On a file containing
package testassest
func FuncWithNestedAnonymousFuncs() {
innerFunc := func() {
nestedInnerFunc := func() {}
nestedInnerFunc()
}
_ = innerFunc
}
Will produce the following result
package testassest
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
)
func FuncWithNestedAnonymousFuncs() {
printfdebug_Printf_FuncWithNestedAnonymousFuncs("Entering \"FuncWithNestedAnonymousFuncs\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
innerFunc := func() {
printfdebug_Printf_FuncWithNestedAnonymousFuncs("Entering \"innerFunc\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
nestedInnerFunc := func() {
printfdebug_Printf_FuncWithNestedAnonymousFuncs("Entering \"nestedInnerFunc\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
printfdebug_Printf_FuncWithNestedAnonymousFuncs("Leaving \"nestedInnerFunc\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
nestedInnerFunc()
printfdebug_Printf_FuncWithNestedAnonymousFuncs("Leaving \"innerFunc\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
_ = innerFunc
printfdebug_Printf_FuncWithNestedAnonymousFuncs("Leaving \"FuncWithNestedAnonymousFuncs\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
var _ = os.PathSeparator // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = runtime.Caller // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = filepath.Clean // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = fmt.Println // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = strings.Split // automatically added by printf-debugger. Do not change this comment. It is an identifier.
func printfdebug_Printf_FuncWithNestedAnonymousFuncs(message string, pathDepthFromEnd int) {
minInt := func(first int, second int) (min int) {
if first < second {
return first
} else {
return second
}
}
_, file, line, ok := runtime.Caller(1)
if ok {
fileParts := strings.Split(file, string(os.PathSeparator))
pathFromEndSafe := minInt(len(fileParts), pathDepthFromEnd)
limited := filepath.Join(fileParts[len(fileParts)-pathFromEndSafe:]...)
limitedCleaned := "??"
if limited != "" {
limitedCleaned = limited
}
fmt.Printf("%v:%v %v\n", limitedCleaned, line, message)
} else {
fmt.Printf("unkown_file:? %v\n", message)
}
}
Struct Method (No Runtime)
Running printfdebug --file internal/tests/testassets/StructMethod.go add --no-runtime
On a file containing
package testassest
func (s *S) StructMethod() {
}
Will produce the following result
package testassest
import "fmt"
func (s *S) StructMethod() {
fmt.Println("Entering \"StructMethod\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
fmt.Println("Leaving \"StructMethod\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
Struct Method (With Runtime)
Running printfdebug --file internal/tests/testassets/StructMethod.go add
On a file containing
package testassest
func (s *S) StructMethod() {
}
Will produce the following result
package testassest
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
)
func (s *S) StructMethod() {
printfdebug_Printf_StructMethod("Entering \"StructMethod\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
printfdebug_Printf_StructMethod("Leaving \"StructMethod\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
var _ = filepath.Clean // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = fmt.Println // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = strings.Split // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = os.PathSeparator // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = runtime.Caller // automatically added by printf-debugger. Do not change this comment. It is an identifier.
func printfdebug_Printf_StructMethod(message string, pathDepthFromEnd int) {
minInt := func(first int, second int) (min int) {
if first < second {
return first
} else {
return second
}
}
_, file, line, ok := runtime.Caller(1)
if ok {
fileParts := strings.Split(file, string(os.PathSeparator))
pathFromEndSafe := minInt(len(fileParts), pathDepthFromEnd)
limited := filepath.Join(fileParts[len(fileParts)-pathFromEndSafe:]...)
limitedCleaned := "??"
if limited != "" {
limitedCleaned = limited
}
fmt.Printf("%v:%v %v\n", limitedCleaned, line, message)
} else {
fmt.Printf("unkown_file:? %v\n", message)
}
}
Struct Method With Arguments (No Runtime)
Running printfdebug --file internal/tests/testassets/StructMethodWithArgs.go add --no-runtime
On a file containing
package testassest
func (s *S) StructMethodWithArgs(s2 string) {
}
Will produce the following result
package testassest
import "fmt"
func (s *S) StructMethodWithArgs(s2 string) {
fmt.Println("Entering \"StructMethodWithArgs\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
fmt.Println("Leaving \"StructMethodWithArgs\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
Struct Method With Arguments (With Runtime)
Running printfdebug --file internal/tests/testassets/StructMethodWithArgs.go add
On a file containing
package testassest
func (s *S) StructMethodWithArgs(s2 string) {
}
Will produce the following result
package testassest
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
)
func (s *S) StructMethodWithArgs(s2 string) {
printfdebug_Printf_StructMethodWithArgs("Entering \"StructMethodWithArgs\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
printfdebug_Printf_StructMethodWithArgs("Leaving \"StructMethodWithArgs\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
}
var _ = strings.Split // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = os.PathSeparator // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = runtime.Caller // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = filepath.Clean // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = fmt.Println // automatically added by printf-debugger. Do not change this comment. It is an identifier.
func printfdebug_Printf_StructMethodWithArgs(message string, pathDepthFromEnd int) {
minInt := func(first int, second int) (min int) {
if first < second {
return first
} else {
return second
}
}
_, file, line, ok := runtime.Caller(1)
if ok {
fileParts := strings.Split(file, string(os.PathSeparator))
pathFromEndSafe := minInt(len(fileParts), pathDepthFromEnd)
limited := filepath.Join(fileParts[len(fileParts)-pathFromEndSafe:]...)
limitedCleaned := "??"
if limited != "" {
limitedCleaned = limited
}
fmt.Printf("%v:%v %v\n", limitedCleaned, line, message)
} else {
fmt.Printf("unkown_file:? %v\n", message)
}
}
Struct Method With Arguments And Return (No Runtime)
Running printfdebug --file internal/tests/testassets/StructMethodWithArgsAndReturn.go add --no-runtime
On a file containing
package testassest
func (s *S) StructMethodWithArgsAndReturn(s2 string) error {
return nil
}
Will produce the following result
package testassest
import "fmt"
func (s *S) StructMethodWithArgsAndReturn(s2 string) error {
fmt.Println("Entering \"StructMethodWithArgsAndReturn\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
fmt.Println("Leaving \"StructMethodWithArgsAndReturn\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return nil
}
Struct Method With Arguments And Return (With Runtime)
Running printfdebug --file internal/tests/testassets/StructMethodWithArgsAndReturn.go add
On a file containing
package testassest
func (s *S) StructMethodWithArgsAndReturn(s2 string) error {
return nil
}
Will produce the following result
package testassest
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
)
func (s *S) StructMethodWithArgsAndReturn(s2 string) error {
printfdebug_Printf_StructMethodWithArgsAndReturn("Entering \"StructMethodWithArgsAndReturn\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
printfdebug_Printf_StructMethodWithArgsAndReturn("Leaving \"StructMethodWithArgsAndReturn\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return nil
}
var _ = strings.Split // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = os.PathSeparator // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = runtime.Caller // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = filepath.Clean // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = fmt.Println // automatically added by printf-debugger. Do not change this comment. It is an identifier.
func printfdebug_Printf_StructMethodWithArgsAndReturn(message string, pathDepthFromEnd int) {
minInt := func(first int, second int) (min int) {
if first < second {
return first
} else {
return second
}
}
_, file, line, ok := runtime.Caller(1)
if ok {
fileParts := strings.Split(file, string(os.PathSeparator))
pathFromEndSafe := minInt(len(fileParts), pathDepthFromEnd)
limited := filepath.Join(fileParts[len(fileParts)-pathFromEndSafe:]...)
limitedCleaned := "??"
if limited != "" {
limitedCleaned = limited
}
fmt.Printf("%v:%v %v\n", limitedCleaned, line, message)
} else {
fmt.Printf("unkown_file:? %v\n", message)
}
}
Struct Method With Return (No Runtime)
Running printfdebug --file internal/tests/testassets/StructMethodWithReturn.go add --no-runtime
On a file containing
package testassest
func (s *S) StructMethodWithReturn() error {
return nil
}
Will produce the following result
package testassest
import "fmt"
func (s *S) StructMethodWithReturn() error {
fmt.Println("Entering \"StructMethodWithReturn\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
fmt.Println("Leaving \"StructMethodWithReturn\"\n") // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return nil
}
Struct Method With Return (With Runtime)
Running printfdebug --file internal/tests/testassets/StructMethodWithReturn.go add
On a file containing
package testassest
func (s *S) StructMethodWithReturn() error {
return nil
}
Will produce the following result
package testassest
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
)
func (s *S) StructMethodWithReturn() error {
printfdebug_Printf_StructMethodWithReturn("Entering \"StructMethodWithReturn\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
printfdebug_Printf_StructMethodWithReturn("Leaving \"StructMethodWithReturn\"\n", 1) // automatically added by printf-debugger. Do not change this comment. It is an identifier.
return nil
}
var _ = runtime.Caller // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = filepath.Clean // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = fmt.Println // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = strings.Split // automatically added by printf-debugger. Do not change this comment. It is an identifier.
var _ = os.PathSeparator // automatically added by printf-debugger. Do not change this comment. It is an identifier.
func printfdebug_Printf_StructMethodWithReturn(message string, pathDepthFromEnd int) {
minInt := func(first int, second int) (min int) {
if first < second {
return first
} else {
return second
}
}
_, file, line, ok := runtime.Caller(1)
if ok {
fileParts := strings.Split(file, string(os.PathSeparator))
pathFromEndSafe := minInt(len(fileParts), pathDepthFromEnd)
limited := filepath.Join(fileParts[len(fileParts)-pathFromEndSafe:]...)
limitedCleaned := "??"
if limited != "" {
limitedCleaned = limited
}
fmt.Printf("%v:%v %v\n", limitedCleaned, line, message)
} else {
fmt.Printf("unkown_file:? %v\n", message)
}
}
https://github.com/yuuki0xff/printfdebug
I actually only found this project after I wrote this tool and was looking for a name. yuuki0xff's printfdebug is not maintained and less complete.
yuuki0xff, If you're reading this let me know if you'd like to combine forces!