From fda345577a0b03978e1a6ca9b41120323e6779ac Mon Sep 17 00:00:00 2001 From: john Date: Fri, 9 Aug 2019 20:05:36 +0800 Subject: [PATCH] add package gdebug; improve gconv/gfile/gset --- .example/debug/gdebug/gdebug.go | 11 +++++ container/gset/gset_z_unit_int_test.go | 4 +- container/gset/gset_z_unit_string_test.go | 2 +- container/gset/gset_z_unit_test.go | 2 +- .../debug/debug.go => debug/gdebug/gdebug.go | 42 +++++++++++++++++-- net/ghttp/ghttp_server_router.go | 5 +-- os/gfile/gfile_source.go | 15 +------ os/gfile/gfile_z_scan_test.go | 11 ++++- os/gfile/gfile_z_test.go | 6 +++ os/glog/glog_logger.go | 9 ++-- test/gtest/gtest.go | 7 ++-- util/gconv/gconv.go | 8 ++-- util/gconv/gconv_unsafe.go | 2 + util/gutil/gutil_debug.go | 28 ------------- 14 files changed, 84 insertions(+), 68 deletions(-) create mode 100644 .example/debug/gdebug/gdebug.go rename internal/debug/debug.go => debug/gdebug/gdebug.go (74%) delete mode 100644 util/gutil/gutil_debug.go diff --git a/.example/debug/gdebug/gdebug.go b/.example/debug/gdebug/gdebug.go new file mode 100644 index 000000000..ad767d3c7 --- /dev/null +++ b/.example/debug/gdebug/gdebug.go @@ -0,0 +1,11 @@ +package main + +import ( + "fmt" + "github.com/gogf/gf/debug/gdebug" +) + +func main() { + fmt.Println(gdebug.CallerPackage()) + fmt.Println(gdebug.CallerFunction()) +} diff --git a/container/gset/gset_z_unit_int_test.go b/container/gset/gset_z_unit_int_test.go index 5369743d1..d95d593c1 100644 --- a/container/gset/gset_z_unit_int_test.go +++ b/container/gset/gset_z_unit_int_test.go @@ -210,8 +210,8 @@ func TestIntSet_Pop(t *testing.T) { gtest.Case(t, func() { s1 := gset.NewIntSet() s1.Add(4).Add(2).Add(3) - gtest.AssertIN(s1.Pop(1), []int{4, 2, 3}) - gtest.AssertIN(s1.Pop(5), []int{4, 2, 3}) + gtest.AssertIN(s1.Pop(), []int{4, 2, 3}) + gtest.AssertIN(s1.Pop(), []int{4, 2, 3}) gtest.Assert(s1.Size(), 3) }) } diff --git a/container/gset/gset_z_unit_string_test.go b/container/gset/gset_z_unit_string_test.go index a7f985fa7..408e5744e 100644 --- a/container/gset/gset_z_unit_string_test.go +++ b/container/gset/gset_z_unit_string_test.go @@ -240,7 +240,7 @@ func TestStringSet_Remove(t *testing.T) { func TestStringSet_Pop(t *testing.T) { gtest.Case(t, func() { s1 := gset.NewStringSetFrom([]string{"a", "b", "c"}, true) - str1 := s1.Pop(1) + str1 := s1.Pop() gtest.Assert(strings.Contains("a,b,c", str1), true) }) } diff --git a/container/gset/gset_z_unit_test.go b/container/gset/gset_z_unit_test.go index 6a3982e46..efa173398 100644 --- a/container/gset/gset_z_unit_test.go +++ b/container/gset/gset_z_unit_test.go @@ -254,7 +254,7 @@ func TestSet_Pop(t *testing.T) { gtest.Case(t, func() { s1 := gset.New(true) s1.Add(1).Add(2).Add(3).Add(4) - gtest.AssertIN(s1.Pop(1), []int{1, 2, 3, 4}) + gtest.AssertIN(s1.Pop(), []int{1, 2, 3, 4}) }) } diff --git a/internal/debug/debug.go b/debug/gdebug/gdebug.go similarity index 74% rename from internal/debug/debug.go rename to debug/gdebug/gdebug.go index 9b92f5dbd..e021ed325 100644 --- a/internal/debug/debug.go +++ b/debug/gdebug/gdebug.go @@ -4,9 +4,8 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://github.com/gogf/gf. -// Package debug contains facilities for programs to debug themselves while -// they are running. -package debug +// Package gdebug contains facilities for programs to debug themselves while they are running. +package gdebug import ( "bytes" @@ -17,7 +16,7 @@ import ( const ( gMAX_DEPTH = 1000 - gFILTER_KEY = "/gf/internal/debug/debug.go" + gFILTER_KEY = "/gf/debug/gdebug/gdebug.go" ) var ( @@ -134,3 +133,38 @@ func callerFromIndex(filter string) int { } return 0 } + +// CallerPackage returns the package name of the caller. +func CallerPackage() string { + function, _, _ := Caller() + indexSplit := strings.LastIndexByte(function, '/') + if indexSplit == -1 { + return function[:strings.IndexByte(function, '.')] + } else { + leftPart := function[:indexSplit+1] + rightPart := function[indexSplit+1:] + indexDot := strings.IndexByte(function, '.') + rightPart = rightPart[:indexDot-1] + return leftPart + rightPart + } +} + +// CallerFunction returns the function name of the caller. +func CallerFunction() string { + function, _, _ := Caller() + function = function[strings.LastIndexByte(function, '/')+1:] + function = function[strings.IndexByte(function, '.')+1:] + return function +} + +// CallerFilePath returns the file path of the caller. +func CallerFilePath() string { + _, path, _ := Caller() + return path +} + +// CallerFileLine returns the file path along with the line number of the caller. +func CallerFileLine() string { + _, path, line := Caller() + return fmt.Sprintf(`%s:%d`, path, line) +} diff --git a/net/ghttp/ghttp_server_router.go b/net/ghttp/ghttp_server_router.go index 778dce816..cc70b6d63 100644 --- a/net/ghttp/ghttp_server_router.go +++ b/net/ghttp/ghttp_server_router.go @@ -9,11 +9,10 @@ package ghttp import ( "errors" "fmt" + "github.com/gogf/gf/debug/gdebug" "strings" "github.com/gogf/gf/container/glist" - "github.com/gogf/gf/internal/debug" - "github.com/gogf/gf/os/glog" "github.com/gogf/gf/text/gregex" "github.com/gogf/gf/text/gstr" @@ -169,7 +168,7 @@ func (s *Server) setHandler(pattern string, handler *handlerItem) { if _, ok := s.routesMap[regKey]; !ok { s.routesMap[regKey] = make([]registeredRouteItem, 0) } - _, file, line := debug.CallerWithFilter(gFILTER_KEY) + _, file, line := gdebug.CallerWithFilter(gFILTER_KEY) s.routesMap[regKey] = append(s.routesMap[regKey], registeredRouteItem{ file: fmt.Sprintf(`%s:%d`, file, line), handler: handler, diff --git a/os/gfile/gfile_source.go b/os/gfile/gfile_source.go index 3fda8eb2f..88a5abce6 100644 --- a/os/gfile/gfile_source.go +++ b/os/gfile/gfile_source.go @@ -1,4 +1,4 @@ -// Copyright 2017-2018 gf Author(https://github.com/gogf/gf). All Rights Reserved. +// Copyright 2017 gf Author(https://github.com/gogf/gf). All Rights Reserved. // // This Source Code Form is subject to the terms of the MIT License. // If a copy of the MIT was not distributed with this file, @@ -10,23 +10,10 @@ import ( "os" "runtime" - "github.com/gogf/gf/internal/debug" "github.com/gogf/gf/text/gregex" "github.com/gogf/gf/text/gstr" ) -const ( - gPATH_FILTER_KEY = "/gf/os/gfile/gfile" -) - -// SourcePath returns absolute file path of the current source file path. -// -// Note that it's only available in develop environment. -func SourcePath(skip ...int) string { - _, path, _ := debug.CallerWithFilter(gPATH_FILTER_KEY, skip...) - return path -} - // MainPkgPath returns absolute file path of package main, // which contains the entrance function main. // diff --git a/os/gfile/gfile_z_scan_test.go b/os/gfile/gfile_z_scan_test.go index c7b0defd1..a164cc80a 100644 --- a/os/gfile/gfile_z_scan_test.go +++ b/os/gfile/gfile_z_scan_test.go @@ -1,6 +1,13 @@ +// Copyright 2017-2018 gf Author(https://github.com/gogf/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://github.com/gogf/gf. + package gfile_test import ( + "github.com/gogf/gf/debug/gdebug" "testing" "github.com/gogf/gf/os/gfile" @@ -9,7 +16,7 @@ import ( ) func Test_ScanDir(t *testing.T) { - teatPath := gfile.Dir(gfile.SourcePath()) + gfile.Separator + "testdata" + teatPath := gfile.Dir(gdebug.CallerFilePath()) + gfile.Separator + "testdata" gtest.Case(t, func() { files, err := gfile.ScanDir(teatPath, "*", false) gtest.Assert(err, nil) @@ -28,7 +35,7 @@ func Test_ScanDir(t *testing.T) { } func Test_ScanDirFile(t *testing.T) { - teatPath := gfile.Dir(gfile.SourcePath()) + gfile.Separator + "testdata" + teatPath := gfile.Dir(gdebug.CallerFilePath()) + gfile.Separator + "testdata" gtest.Case(t, func() { files, err := gfile.ScanDirFile(teatPath, "*", false) gtest.Assert(err, nil) diff --git a/os/gfile/gfile_z_test.go b/os/gfile/gfile_z_test.go index 42f9aad01..36dac3c5e 100644 --- a/os/gfile/gfile_z_test.go +++ b/os/gfile/gfile_z_test.go @@ -1,3 +1,9 @@ +// Copyright 2019 gf Author(https://github.com/gogf/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://github.com/gogf/gf. + package gfile_test import ( diff --git a/os/glog/glog_logger.go b/os/glog/glog_logger.go index c23965f0b..db20ac069 100644 --- a/os/glog/glog_logger.go +++ b/os/glog/glog_logger.go @@ -10,13 +10,12 @@ import ( "bytes" "errors" "fmt" + "github.com/gogf/gf/debug/gdebug" "io" "os" "strings" "time" - "github.com/gogf/gf/internal/debug" - "github.com/gogf/gf/os/gfile" "github.com/gogf/gf/os/gfpool" "github.com/gogf/gf/os/gtime" @@ -244,11 +243,11 @@ func (l *Logger) print(std io.Writer, lead string, value ...interface{}) { // Caller path. callerPath := "" if l.flags&F_FILE_LONG > 0 { - _, path, line := debug.CallerWithFilter(gPATH_FILTER_KEY, l.stSkip) + _, path, line := gdebug.CallerWithFilter(gPATH_FILTER_KEY, l.stSkip) callerPath = fmt.Sprintf(`%s:%d: `, path, line) } if l.flags&F_FILE_SHORT > 0 { - _, path, line := debug.CallerWithFilter(gPATH_FILTER_KEY, l.stSkip) + _, path, line := gdebug.CallerWithFilter(gPATH_FILTER_KEY, l.stSkip) callerPath = fmt.Sprintf(`%s:%d: `, gfile.Basename(path), line) } if len(callerPath) > 0 { @@ -349,5 +348,5 @@ func (l *Logger) PrintStack(skip ...int) { // GetStack returns the caller stack content, // the optional parameter specify the skipped stack offset from the end point. func (l *Logger) GetStack(skip ...int) string { - return debug.StackWithFilter(gPATH_FILTER_KEY, skip...) + return gdebug.StackWithFilter(gPATH_FILTER_KEY, skip...) } diff --git a/test/gtest/gtest.go b/test/gtest/gtest.go index ef5ee9767..4c297c590 100644 --- a/test/gtest/gtest.go +++ b/test/gtest/gtest.go @@ -9,12 +9,11 @@ package gtest import ( "fmt" + "github.com/gogf/gf/debug/gdebug" "os" "reflect" "testing" - "github.com/gogf/gf/internal/debug" - "github.com/gogf/gf/util/gconv" ) @@ -28,7 +27,7 @@ const ( func Case(t *testing.T, f func()) { defer func() { if err := recover(); err != nil { - fmt.Fprintf(os.Stderr, "%v\n%s", err, debug.StackWithFilter(gPATH_FILTER_KEY)) + fmt.Fprintf(os.Stderr, "%v\n%s", err, gdebug.StackWithFilter(gPATH_FILTER_KEY)) t.Fail() } }() @@ -271,7 +270,7 @@ func Error(message ...interface{}) { // Fatal prints to stderr and exit the process. func Fatal(message ...interface{}) { - fmt.Fprintf(os.Stderr, "[FATAL] %s\n%s", fmt.Sprint(message...), debug.StackWithFilter(gPATH_FILTER_KEY)) + fmt.Fprintf(os.Stderr, "[FATAL] %s\n%s", fmt.Sprint(message...), gdebug.StackWithFilter(gPATH_FILTER_KEY)) os.Exit(1) } diff --git a/util/gconv/gconv.go b/util/gconv/gconv.go index 10e44019d..8baf3b42a 100644 --- a/util/gconv/gconv.go +++ b/util/gconv/gconv.go @@ -33,10 +33,10 @@ const ( var ( // Empty strings. emptyStringMap = map[string]struct{}{ - "": struct{}{}, - "0": struct{}{}, - "off": struct{}{}, - "false": struct{}{}, + "": {}, + "0": {}, + "off": {}, + "false": {}, } // Priority tags for Map*/Struct* functions. diff --git a/util/gconv/gconv_unsafe.go b/util/gconv/gconv_unsafe.go index 65bddcf26..08f8b3c6e 100644 --- a/util/gconv/gconv_unsafe.go +++ b/util/gconv/gconv_unsafe.go @@ -8,10 +8,12 @@ package gconv import "unsafe" +// UnsafeStrToBytes converts string to []byte without memory copy. func UnsafeStrToBytes(s string) []byte { return *(*[]byte)(unsafe.Pointer(&s)) } +// UnsafeBytesToStr converts []byte to string without memory copy. func UnsafeBytesToStr(b []byte) string { return *(*string)(unsafe.Pointer(&b)) } diff --git a/util/gutil/gutil_debug.go b/util/gutil/gutil_debug.go deleted file mode 100644 index 97efa0beb..000000000 --- a/util/gutil/gutil_debug.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2017 gf Author(https://github.com/gogf/gf). All Rights Reserved. -// -// This Source Code Form is subject to the terms of the MIT License. -// If a copy of the MIT was not distributed with this file, -// You can obtain one at https://github.com/gogf/gf. - -package gutil - -import ( - "fmt" - - "github.com/gogf/gf/internal/debug" -) - -const ( - gFILTER_KEY = "/gf/util/gutil/gutil" -) - -// PrintStack prints to standard error the stack trace returned by runtime.Stack. -func PrintStack(skip ...int) { - fmt.Print(Stack(skip...)) -} - -// Stack returns a formatted stack trace of the goroutine that calls it. -// It calls runtime.Stack with a large enough buffer to capture the entire trace. -func Stack(skip ...int) string { - return debug.StackWithFilter(gFILTER_KEY, skip...) -}