Repository navigation
Expand file tree
/
Copy patherrors.v
More file actions
109 lines (91 loc) · 2.48 KB
/
Copy patherrors.v
File metadata and controls
109 lines (91 loc) · 2.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
module dotenv
// LoadError describes a malformed `.env` file. It carries both the byte offset
// and the human-readable position of the offending character.
pub struct LoadError {
Error
pub:
// reason is a short, human-readable description of what went wrong.
reason string
// offset is the zero-based byte offset of the offending character.
offset int
// line is the one-based line number.
line int
// column is the one-based column number.
column int
// line_text is the full text of the offending line, without a trailing newline.
line_text string
}
// msg implements the `IError` interface.
pub fn (e LoadError) msg() string {
return '${e.reason} on line ${e.line}, column ${e.column}'
}
// msg_full returns a multi-line message that points at the offending character.
pub fn (e LoadError) msg_full() string {
prefix := ' ${e.line} | '
pad := ' '.repeat(prefix.len)
spaces := ' '.repeat(e.column - 1)
caret := '${pad}${spaces}^'
return '${e.reason}:\n${prefix}${e.line_text}\n${caret}'
}
// SourceError describes a failure of `source` that has no position inside a
// parsed file, e.g. a missing file when `require_files` is enabled.
pub struct SourceError {
Error
pub:
reason string
}
// msg implements the `IError` interface.
pub fn (e SourceError) msg() string {
return e.reason
}
// error_at builds a LoadError for the given byte offset.
fn error_at(reason string, data []u8, pos int) IError {
mut line := 1
mut last_newline := -1
for i in 0 .. pos {
if data[i] == `\n` {
line++
last_newline = i
}
}
return LoadError{
reason: reason
offset: pos
line: line
column: char_column(data, last_newline + 1, pos)
line_text: line_text_at(data, pos)
}
}
// char_column counts UTF-8 characters (runes) between `start` (included) and
// `end` (excluded), so error columns and carets stay aligned on lines that
// contain multibyte text.
fn char_column(data []u8, start int, end int) int {
mut col := 1
for i := start; i < end; {
if data[i] < 0x80 {
i++
} else if data[i] < 0xC0 {
i++ // stray continuation byte counts as its own unit
} else if data[i] < 0xE0 {
i += 2
} else if data[i] < 0xF0 {
i += 3
} else {
i += 4
}
col++
}
return col
}
// line_text_at returns the contents of the line containing `pos`.
fn line_text_at(data []u8, pos int) string {
mut start := pos
for start > 0 && data[start - 1] != `\n` {
start--
}
mut end := pos
for end < data.len && data[end] != `\n` {
end++
}
return data[start..end].bytestr()
}