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  }