github.com/gotranspile/cxgo@v0.3.7/modules.go (about) 1 package cxgo 2 3 import "bytes" 4 5 type SrcFunc struct { 6 File string `json:"file,omitempty"` 7 Line int `json:"line,omitempty"` 8 OffsetStart int `json:"offset_start,omitempty"` 9 OffsetEnd int `json:"offset_end,omitempty"` 10 Func string `json:"func"` 11 Src string `json:"src,omitempty"` 12 Proto string `json:"proto,omitempty"` 13 } 14 15 func SourceFunc(fname string, src []byte, fd *CFuncDecl) SrcFunc { 16 fsrc := "" 17 psrc := "" 18 var ( 19 istart int 20 iend int 21 line int 22 ) 23 if rng := fd.Range; rng != nil && rng.Start > 0 { 24 line = rng.StartLine 25 start := rng.Start 26 end := rng.End 27 if e, f := findEnd(src[start:]); e > 0 { 28 e += start 29 f += start 30 end = e 31 psrc = string(bytes.TrimSpace(src[start:f])) + ";\n" 32 } 33 if s := findCommentStart(src[:start]); s > 0 { 34 start = s 35 } 36 if end > 0 { 37 istart = start 38 iend = end 39 fsrc = string(src[start:end]) 40 } 41 } 42 return SrcFunc{ 43 File: fname, 44 Func: fd.Name.Name, 45 Src: fsrc, 46 Proto: psrc, 47 Line: line, 48 OffsetStart: istart, 49 OffsetEnd: iend, 50 } 51 } 52 53 func findCommentStart(src []byte) int { 54 if len(src) == 0 || src[len(src)-1] != '\n' { 55 return -1 56 } 57 src = src[:len(src)-1] 58 i := bytes.LastIndex(src, []byte("//")) 59 if i < 0 || bytes.ContainsAny(src[i:], "\n\r") { 60 return -1 61 } 62 return i 63 } 64 65 func findEnd(src []byte) (int, int) { 66 started := false 67 level := 0 68 first := -1 69 i := 0 70 for ; (!started || level > 0) && i < len(src); i++ { 71 switch src[i] { 72 case '{': 73 if !started { 74 started = true 75 first = i 76 } 77 level++ 78 case '}': 79 level-- 80 if level == 0 { 81 break 82 } 83 } 84 } 85 if i >= len(src) { 86 return -1, -1 87 } 88 for j := 0; j < 2; j++ { 89 if i+1 < len(src) && src[i+1] == '\n' { 90 i++ 91 } 92 } 93 return i, first 94 }