1package main 2 3import ( 4 "path/filepath" 5 "strconv" 6 "strings" 7) 8 9type ( 10 // LineNumber is a number from 1 to the last line (counts lines from 1) 11 LineNumber int 12 13 // LineIndex is a number from 0 to the last line (counts lines from 0) 14 LineIndex int 15 16 // CharacterPosition is a number from 0 to the last character (counts characters from 0) 17 CharacterPosition int 18 19 // ColNumber is a number from 1 and up (counts columns from 1) 20 ColNumber int 21 22 // ColIndex is a number from 0 and up (counts lines from 0) 23 ColIndex int 24) 25 26// String converts a LineNumber to a string 27func (ln LineNumber) String() string { 28 return strconv.Itoa(int(ln)) 29} 30 31// String converts a LineIndex to a string 32func (li LineIndex) String() string { 33 return strconv.Itoa(int(li)) 34} 35 36// String converts a ColIndex to a string 37func (ci ColIndex) String() string { 38 return strconv.Itoa(int(ci)) 39} 40 41// LineIndex converts a LineNumber to a LineIndex by subtracting 1 42func (ln LineNumber) LineIndex() LineIndex { 43 return LineIndex(ln - 1) 44} 45 46// ColIndex converts a ColNumber to a ColIndex by subtracting 1 47func (cn ColNumber) ColIndex() ColIndex { 48 return ColIndex(cn - 1) 49} 50 51// LineNumber converts a LineIndex to a LineNumber by adding 1 52func (li LineIndex) LineNumber() LineNumber { 53 return LineNumber(li + 1) 54} 55 56// ColNumber converts a ColIndex to a ColNumber by adding 1 57func (ci ColIndex) ColNumber() ColNumber { 58 return ColNumber(ci + 1) 59} 60 61// FilenameAndLineNumberAndColNumber will take the first two arguments and return a filename and a line number (can be 0) 62// If the second argument is a number, that will be used as the line number. Or: 63// If the second argument is a number prefixed with a "+", that will be used as the line number. Or: 64// If the filename ends with a ":" and a number, that will be used as the line number. 65func FilenameAndLineNumberAndColNumber(filename, lineNumberString, colNumberString string) (string, LineNumber, ColNumber) { 66 lineNumber := 0 67 colNumber := 0 68 if lineNumberConverted, err := strconv.Atoi(lineNumberString); err == nil { // no error 69 lineNumber = lineNumberConverted 70 } else if strings.HasPrefix(lineNumberString, "+") { 71 if lineNumberConverted, err := strconv.Atoi(lineNumberString[1:]); err == nil { // no error 72 lineNumber = lineNumberConverted 73 } 74 } else if strings.Contains(filepath.Base(filename), ":") { 75 fields := strings.SplitN(filename, ":", 2) 76 if lineNumberConverted, err := strconv.Atoi(fields[1]); err == nil { // no error 77 lineNumber = lineNumberConverted 78 filename = fields[0] 79 } 80 } else if strings.Contains(filepath.Base(filename), "+") { 81 fields := strings.SplitN(filename, "+", 2) 82 if lineNumberConverted, err := strconv.Atoi(fields[1]); err == nil { // no error 83 lineNumber = lineNumberConverted 84 filename = fields[0] 85 } 86 } 87 if colNumberConverted, err := strconv.Atoi(colNumberString); err == nil { // no error 88 colNumber = colNumberConverted 89 } else if strings.HasPrefix(colNumberString, "+") { 90 if colNumberConverted, err := strconv.Atoi(colNumberString[1:]); err == nil { // no error 91 colNumber = colNumberConverted 92 } 93 } 94 return filename, LineNumber(lineNumber), ColNumber(colNumber) 95} 96