Skip to content

Commit

Permalink
[strutil] Add method 'IndexByteSkip'
Browse files Browse the repository at this point in the history
  • Loading branch information
andyone committed Mar 15, 2024
1 parent 50899d9 commit 9ce7232
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 10 deletions.
7 changes: 4 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

### 12.105.0

* [`log`] Added JSON output format
* [`log`] Added caller info to messages
* [`log`] Code refactoring
* `[log]` Added JSON output format
* `[log]` Added caller info to messages
* `[strutil]` Added method `IndexByteSkip`
* `[log]` Code refactoring

### 12.104.0

Expand Down
32 changes: 25 additions & 7 deletions log/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -814,9 +814,9 @@ func splitPayload(payload []any) ([]any, []any) {
// getCallerFromStack returns caller function and line from stack
func getCallerFromStack() string {
pcs := make([]uintptr, 64)
n := runtime.Callers(4, pcs)
n := runtime.Callers(2, pcs)

foundNil := false
file := ""
frames := runtime.CallersFrames(pcs[:n])

for {
Expand All @@ -826,14 +826,32 @@ func getCallerFromStack() string {
break
}

if frame.Func == nil {
foundNil = true
if file == "" {
file = frame.File
}

if foundNil && frame.Func != nil {
return frame.File + ":" + strconv.Itoa(frame.Line)
if file == frame.File {
continue
}

return extractCallerFromFrame(frame)
}

return "unknown"
}

func extractCallerFromFrame(f runtime.Frame) string {
index, sepCount := 0, 0

for index = len(f.File) - 1; index > 0; index-- {
if f.File[index] == '/' {
sepCount++
}

if sepCount == 2 {
break
}
}

return "unknown:0"
return f.File[index+1:] + ":" + strconv.Itoa(f.Line)
}
12 changes: 12 additions & 0 deletions strutil/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,15 @@ func ExampleHasSuffixAny() {
// true
// false
}

func ExampleIndexByteSkip() {
// Index from left
fmt.Println(IndexByteSkip("/home/john/projects/test.log", '/', 2))

// Index from right
fmt.Println(IndexByteSkip("/home/john/projects/test.log", '/', -1))

// Output:
// 10
// 10
}
36 changes: 36 additions & 0 deletions strutil/strutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,42 @@ func HasSuffixAny(s string, suffix ...string) bool {
return false
}

// IndexByteSkip returns the index of the given byte in the string after skipping
// the first or the last N occurrences
func IndexByteSkip(s string, c byte, skip int) int {
if skip == 0 {
return strings.IndexByte(s, c)
}

counter := 0

if skip > 0 {
for i := 0; i < len(s); i++ {
if s[i] == c {
counter++
}

if counter > skip {
return i
}
}
} else {
skip *= -1

for i := len(s) - 1; i > 0; i-- {
if s[i] == c {
counter++
}

if counter > skip {
return i
}
}
}

return -1
}

// ////////////////////////////////////////////////////////////////////////////////// //

func appendField(data []string, item string) []string {
Expand Down
10 changes: 10 additions & 0 deletions strutil/strutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,16 @@ func (s *StrUtilSuite) TestHasSuffixAny(c *C) {
c.Assert(HasSuffixAny("abcd#", "$", "@"), Equals, false)
}

func (s *StrUtilSuite) TestIndexByteSkip(c *C) {
c.Assert(IndexByteSkip("", '/', 0), Equals, -1)
c.Assert(IndexByteSkip("", '/', 1), Equals, -1)
c.Assert(IndexByteSkip("/", '/', 1), Equals, -1)
c.Assert(IndexByteSkip("/home/john/projects/test.log", '/', 2), Equals, 10)
c.Assert(IndexByteSkip("/home/john/projects/test.log", '/', -1), Equals, 10)
}

// ////////////////////////////////////////////////////////////////////////////////// //

func (s *StrUtilSuite) BenchmarkSubstr(c *C) {
for i := 0; i < c.N; i++ {
Substr("test1234TEST", 4, 8)
Expand Down

0 comments on commit 9ce7232

Please sign in to comment.