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
5package main
6
7import (
8	"fmt"
9	"go/token"
10	"strconv"
11	"strings"
12)
13
14func 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
23func 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
53func 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}
72