1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

compiler: produce errors in C "filepath:line:column:" format

This commit is contained in:
Delyan Angelov 2019-08-22 14:15:11 +03:00 committed by Alexander Medvednikov
parent 9b3b22d6b3
commit 77b31de117
5 changed files with 47 additions and 10 deletions

View File

@ -332,7 +332,7 @@ fn (s mut Scanner) scan() ScanRes {
// TODO allow double quotes // TODO allow double quotes
// case QUOTE: // case QUOTE:
// return scan_res(.str, s.ident_string()) // return scan_res(.str, s.ident_string())
case `\``: case `\``: // ` // apostrophe balance comment. do not remove
return scan_res(.chartoken, s.ident_char()) return scan_res(.chartoken, s.ident_char())
case `(`: case `(`:
return scan_res(.lpar, '') return scan_res(.lpar, '')
@ -563,9 +563,26 @@ fn (s mut Scanner) scan() ScanRes {
return scan_res(.eof, '') return scan_res(.eof, '')
} }
fn (s &Scanner) find_current_line_start_position() int {
mut linestart := s.pos
for {
if linestart <= 0 {break}
if s.text[linestart] == 10 || s.text[linestart] == 13 { break }
linestart--
}
return linestart
}
fn (s &Scanner) error(msg string) { fn (s &Scanner) error(msg string) {
file := s.file_path.all_after('/') fullpath := os.realpath( s.file_path )
println('$file:${s.line_nr + 1} $msg') column := s.pos - s.find_current_line_start_position()
// The filepath:line:col: format is the default C compiler
// error output format. It allows editors and IDE's like
// emacs to quickly find the errors in the output
// and jump to their source with a keyboard shortcut.
// Using only the filename leads to inability of IDE/editors
// to find the source file, when it is in another folder.
println('${fullpath}:${s.line_nr + 1}:$column: $msg')
exit(1) exit(1)
} }
@ -655,7 +672,7 @@ fn (s mut Scanner) ident_char() string {
len++ len++
} }
double_slash := s.expect('\\\\', s.pos - 2) double_slash := s.expect('\\\\', s.pos - 2)
if s.text[s.pos] == `\`` && (s.text[s.pos - 1] != slash || double_slash) { if s.text[s.pos] == `\`` && (s.text[s.pos - 1] != slash || double_slash) { // ` // apostrophe balance comment. do not remove
if double_slash { if double_slash {
len++ len++
} }
@ -754,7 +771,7 @@ fn (s mut Scanner) get_opening_bracket() int {
if s.text[pos] == `(` && !inside_string { if s.text[pos] == `(` && !inside_string {
parentheses-- parentheses--
} }
if s.text[pos] == `\'` && s.text[pos - 1] != `\\` && s.text[pos - 1] != `\`` { if s.text[pos] == `\'` && s.text[pos - 1] != `\\` && s.text[pos - 1] != `\`` { // ` // apostrophe balance comment. do not remove
inside_string = !inside_string inside_string = !inside_string
} }
if parentheses == 0 { if parentheses == 0 {

View File

@ -1,3 +1,3 @@
println(a) println(a)
===output=== ===output===
.vrepl.v:2 undefined: `a` .vrepl.v:2:9: undefined: `a`

View File

@ -1,5 +1,5 @@
a a
33 33
===output=== ===output===
.vrepl_temp.v:2 undefined: `a` .vrepl_temp.v:2:9: undefined: `a`
33 33

View File

@ -2,7 +2,7 @@ import os
fn test_repl() { fn test_repl() {
test_files := os.walk_ext('.', '.repl') test_files := os.walk_ext('.', '.repl')
wd := os.getwd() + '/'
for file in test_files { for file in test_files {
content := os.read_file(file) or { content := os.read_file(file) or {
assert false assert false
@ -19,7 +19,7 @@ fn test_repl() {
assert false assert false
break break
} }
result := r.output.replace('>>> ', '').replace('>>>', '').replace('... ', '').all_after('Use Ctrl-C or `exit` to exit\n') result := r.output.replace('>>> ', '').replace('>>>', '').replace('... ', '').all_after('Use Ctrl-C or `exit` to exit\n').replace( wd, '' )
assert result == output assert result == output
if result != output { if result != output {
println(file) println(file)

View File

@ -739,6 +739,26 @@ pub fn getwd() string {
} }
} }
// Returns the full absolute path for fpath, with all relative ../../, symlinks and so on resolved.
// See http://pubs.opengroup.org/onlinepubs/9699919799/functions/realpath.html
// Also https://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
// and https://insanecoding.blogspot.com/2007/11/implementing-realpath-in-c.html
// NB: this particular rabbit hole is *deep* ...
pub fn realpath(fpath string) string {
mut fullpath := malloc( MAX_PATH )
mut res := 0
$if windows {
res = int( C._fullpath( fullpath, fpath.str, MAX_PATH ) )
}
$else{
res = int( C.realpath( fpath.str, fullpath ) )
}
if res != 0 {
return string(fullpath, strlen(fullpath))
}
return fpath
}
// walk_ext returns a recursive list of all file paths ending with `ext`. // walk_ext returns a recursive list of all file paths ending with `ext`.
pub fn walk_ext(path, ext string) []string { pub fn walk_ext(path, ext string) []string {
if !os.is_dir(path) { if !os.is_dir(path) {