github.com/amarpal/go-tools@v0.0.0-20240422043104-40142f59f616/cmd/keyify/position.go (about)

     1  // Copyright 2013 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package main
     6  
     7  import (
     8  	"fmt"
     9  	"go/token"
    10  	"strconv"
    11  	"strings"
    12  )
    13  
    14  func parseOctothorpDecimal(s string) int {
    15  	if s != "" && s[0] == '#' {
    16  		if s, err := strconv.ParseInt(s[1:], 10, 32); err == nil {
    17  			return int(s)
    18  		}
    19  	}
    20  	return -1
    21  }
    22  
    23  func parsePos(pos string) (filename string, startOffset, endOffset int, err error) {
    24  	if pos == "" {
    25  		err = fmt.Errorf("no source position specified")
    26  		return
    27  	}
    28  
    29  	colon := strings.LastIndex(pos, ":")
    30  	if colon < 0 {
    31  		err = fmt.Errorf("bad position syntax %q", pos)
    32  		return
    33  	}
    34  	filename, offset := pos[:colon], pos[colon+1:]
    35  	startOffset = -1
    36  	endOffset = -1
    37  	if hyphen := strings.Index(offset, ","); hyphen < 0 {
    38  		// e.g. "foo.go:#123"
    39  		startOffset = parseOctothorpDecimal(offset)
    40  		endOffset = startOffset
    41  	} else {
    42  		// e.g. "foo.go:#123,#456"
    43  		startOffset = parseOctothorpDecimal(offset[:hyphen])
    44  		endOffset = parseOctothorpDecimal(offset[hyphen+1:])
    45  	}
    46  	if startOffset < 0 || endOffset < 0 {
    47  		err = fmt.Errorf("invalid offset %q in query position", offset)
    48  		return
    49  	}
    50  	return
    51  }
    52  
    53  func fileOffsetToPos(file *token.File, startOffset, endOffset int) (start, end token.Pos, err error) {
    54  	// Range check [start..end], inclusive of both end-points.
    55  
    56  	if 0 <= startOffset && startOffset <= file.Size() {
    57  		start = file.Pos(int(startOffset))
    58  	} else {
    59  		err = fmt.Errorf("start position is beyond end of file")
    60  		return
    61  	}
    62  
    63  	if 0 <= endOffset && endOffset <= file.Size() {
    64  		end = file.Pos(int(endOffset))
    65  	} else {
    66  		err = fmt.Errorf("end position is beyond end of file")
    67  		return
    68  	}
    69  
    70  	return
    71  }