github.com/enetx/g@v1.0.80/pkg/dbg/dbg.go (about) 1 package dbg 2 3 import ( 4 "bufio" 5 "fmt" 6 "os" 7 "path/filepath" 8 "runtime" 9 "strings" 10 ) 11 12 // CallerInfo retrieves and formats the file name and line number of the caller's 13 // location in the source code. 14 // 15 // It uses the runtime.Caller function to determine the caller's file and line 16 // information. 17 // 18 // Example usage: 19 // 20 // callerInfo := CallerInfo() 21 // fmt.Println("Caller:", callerInfo) 22 // 23 // The output will look like this: 24 // 25 // Caller: [filename:line] 26 // 27 // Where "filename" is the name of the file where the caller is located, and 28 // "line" is the line number in that file. 29 func CallerInfo() string { 30 pc, file, line, ok := runtime.Caller(1) 31 if !ok { 32 fmt.Fprintln(os.Stderr, "dbg.CallerInfo: Unable to parse runtime caller") 33 return "" 34 } 35 36 out := fmt.Sprintf("[%s:%d] [%s]", filepath.Base(file), line, runtime.FuncForPC(pc).Name()) 37 38 return out 39 } 40 41 // Dbg is a debugging utility function that prints the given expression and its 42 // location in the source code to standard output. It also prints the file name 43 // and line number where the Dbg function is called. 44 // 45 // Parameters: 46 // 47 // exp - The expression or value to be printed. 48 // 49 // Example: 50 // 51 // Dbg(someValue) 52 // 53 // The output will look like this: 54 // 55 // [filename:line] variable = value 56 // 57 // Where "filename" is the name of the file where Dbg is called, "line" is the 58 // line number in that file, "variable" is the variable or expression being 59 // debugged, and "value" is the value of the expression. 60 func Dbg(exp any) { 61 pc, file, line, ok := runtime.Caller(1) 62 if !ok { 63 fmt.Fprintln(os.Stderr, "dbg.Dbg: Unable to parse runtime caller") 64 return 65 } 66 67 f, err := os.Open(file) 68 if err != nil { 69 fmt.Fprintln(os.Stderr, "dbg.Dbg: Unable to open expected file") 70 return 71 } 72 73 defer f.Close() 74 75 scanner := bufio.NewScanner(f) 76 scanner.Split(bufio.ScanLines) 77 78 var out string 79 for i := 1; scanner.Scan(); i++ { 80 if i == line { 81 v := scanner.Text()[strings.Index(scanner.Text(), "(")+1 : strings.LastIndex(scanner.Text(), ")")] 82 out = fmt.Sprintf("[%s:%d] [%s] %s = %+v", filepath.Base(file), line, runtime.FuncForPC(pc).Name(), v, exp) 83 break 84 } 85 } 86 87 if err := scanner.Err(); err != nil { 88 fmt.Fprintln(os.Stderr, "error:", err) 89 return 90 } 91 92 switch exp.(type) { 93 case error: 94 fmt.Fprintln(os.Stderr, out) 95 default: 96 fmt.Fprintln(os.Stdout, out) 97 } 98 }