v2: compile vfmt again; consistent colored error messages
parent
52f096f5d9
commit
31c4b1cda6
118
cmd/tools/vfmt.v
118
cmd/tools/vfmt.v
|
@ -6,9 +6,9 @@ module main
|
||||||
import (
|
import (
|
||||||
os
|
os
|
||||||
os.cmdline
|
os.cmdline
|
||||||
compiler
|
|
||||||
v.pref
|
v.pref
|
||||||
v.fmt
|
v.fmt
|
||||||
|
v.util
|
||||||
v.parser
|
v.parser
|
||||||
v.table
|
v.table
|
||||||
vhelp
|
vhelp
|
||||||
|
@ -43,7 +43,7 @@ const (
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
toolexe := os.executable()
|
toolexe := os.executable()
|
||||||
compiler.set_vroot_folder(os.dir(os.dir(os.dir(toolexe))))
|
util.set_vroot_folder(os.dir(os.dir(os.dir(toolexe))))
|
||||||
args := join_flags_and_argument()
|
args := join_flags_and_argument()
|
||||||
foptions := FormatOptions{
|
foptions := FormatOptions{
|
||||||
is_2: '-2' in args
|
is_2: '-2' in args
|
||||||
|
@ -81,17 +81,17 @@ fn main() {
|
||||||
for file in possible_files {
|
for file in possible_files {
|
||||||
if foptions.is_2 {
|
if foptions.is_2 {
|
||||||
if !file.ends_with('.v') && !file.ends_with('.vv') {
|
if !file.ends_with('.v') && !file.ends_with('.vv') {
|
||||||
compiler.verror('v fmt -2 can only be used on .v or .vv files.\nOffending file: "$file" .')
|
verror('v fmt -2 can only be used on .v or .vv files.\nOffending file: "$file" .')
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if !file.ends_with('.v') {
|
if !file.ends_with('.v') {
|
||||||
compiler.verror('v fmt can only be used on .v files.\nOffending file: "$file" .')
|
verror('v fmt can only be used on .v files.\nOffending file: "$file" .')
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !os.exists(file) {
|
if !os.exists(file) {
|
||||||
compiler.verror('"$file" does not exist.')
|
verror('"$file" does not exist.')
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
files << file
|
files << file
|
||||||
|
@ -151,89 +151,20 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (foptions &FormatOptions) format_file(file string) {
|
fn (foptions &FormatOptions) format_file(file string) {
|
||||||
if foptions.is_2 {
|
prefs := pref.new_preferences()
|
||||||
if foptions.is_verbose {
|
|
||||||
eprintln('vfmt2 running fmt.fmt over file: $file')
|
|
||||||
}
|
|
||||||
table := table.new_table()
|
|
||||||
file_ast := parser.parse_file(file, table, .parse_comments, &pref.Preferences{})
|
|
||||||
formatted_content := fmt.fmt(file_ast, table)
|
|
||||||
file_name := os.file_name(file)
|
|
||||||
vfmt_output_path := os.join_path(os.temp_dir(), 'vfmt_' + file_name)
|
|
||||||
os.write_file(vfmt_output_path, formatted_content )
|
|
||||||
if foptions.is_verbose {
|
|
||||||
eprintln('vfmt2 fmt.fmt worked and ${formatted_content.len} bytes were written to ${vfmt_output_path} .')
|
|
||||||
}
|
|
||||||
eprintln('${FORMATTED_FILE_TOKEN}${vfmt_output_path}')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
tmpfolder := os.temp_dir()
|
|
||||||
mut compiler_params := &pref.Preferences{}
|
|
||||||
target_os := file_to_target_os(file)
|
|
||||||
if target_os != '' {
|
|
||||||
//TODO Remove temporary variable once it compiles correctly in C
|
|
||||||
tmp := pref.os_from_string(target_os) or {
|
|
||||||
eprintln('unknown operating system $target_os')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
compiler_params.os = tmp
|
|
||||||
}
|
|
||||||
mut cfile := file
|
|
||||||
mut mod_folder_parent := tmpfolder
|
|
||||||
is_test_file := file.ends_with('_test.v')
|
|
||||||
mod_name,is_module_file := file_to_mod_name_and_is_module_file(file)
|
|
||||||
use_tmp_main_program := is_module_file && !is_test_file
|
|
||||||
mod_folder := os.base_dir(file)
|
|
||||||
if use_tmp_main_program {
|
|
||||||
// TODO: remove the need for this
|
|
||||||
// This makes a small program that imports the module,
|
|
||||||
// so that the module files will get processed by the
|
|
||||||
// vfmt implementation.
|
|
||||||
mod_folder_parent = os.base_dir(mod_folder)
|
|
||||||
mut main_program_content := if mod_name == 'builtin' || mod_name == 'main' { 'fn main(){}\n' } else { 'import ${mod_name}\n' + 'fn main(){}\n' }
|
|
||||||
main_program_file := os.join_path(tmpfolder,'vfmt_tmp_${mod_name}_program.v')
|
|
||||||
if os.exists(main_program_file) {
|
|
||||||
os.rm(main_program_file)
|
|
||||||
}
|
|
||||||
os.write_file(main_program_file, main_program_content)
|
|
||||||
cfile = main_program_file
|
|
||||||
compiler_params.lookup_path = [mod_folder_parent, '@vlib', '@vmodule']
|
|
||||||
}
|
|
||||||
if !is_test_file && mod_name == 'main' {
|
|
||||||
// NB: here, file is guaranteed to be a main. We do not know however
|
|
||||||
// whether it is a standalone v program, or is it a part of a bigger
|
|
||||||
// project, like vorum or vid.
|
|
||||||
cfile = get_compile_name_of_potential_v_project(cfile)
|
|
||||||
}
|
|
||||||
compiler_params.path = cfile
|
|
||||||
compiler_params.mod = mod_name
|
|
||||||
compiler_params.is_test = is_test_file
|
|
||||||
compiler_params.is_script = file.ends_with('.v') || file.ends_with('.vsh')
|
|
||||||
if foptions.is_verbose {
|
if foptions.is_verbose {
|
||||||
eprintln('vfmt format_file: file: $file')
|
eprintln('vfmt2 running fmt.fmt over file: $file')
|
||||||
eprintln('vfmt format_file: cfile: $cfile')
|
|
||||||
eprintln('vfmt format_file: is_test_file: $is_test_file')
|
|
||||||
eprintln('vfmt format_file: is_module_file: $is_module_file')
|
|
||||||
eprintln('vfmt format_file: mod_name: $mod_name')
|
|
||||||
eprintln('vfmt format_file: mod_folder: $mod_folder')
|
|
||||||
eprintln('vfmt format_file: mod_folder_parent: $mod_folder_parent')
|
|
||||||
eprintln('vfmt format_file: use_tmp_main_program: $use_tmp_main_program')
|
|
||||||
eprintln('vfmt format_file: compiler_params: ')
|
|
||||||
print_compiler_options( compiler_params )
|
|
||||||
eprintln('-------------------------------------------')
|
|
||||||
}
|
}
|
||||||
compiler_params.fill_with_defaults()
|
table := table.new_table()
|
||||||
|
file_ast := parser.parse_file(file, table, .parse_comments, prefs)
|
||||||
|
formatted_content := fmt.fmt(file_ast, table)
|
||||||
|
file_name := os.file_name(file)
|
||||||
|
vfmt_output_path := os.join_path(os.temp_dir(), 'vfmt_' + file_name)
|
||||||
|
os.write_file(vfmt_output_path, formatted_content )
|
||||||
if foptions.is_verbose {
|
if foptions.is_verbose {
|
||||||
eprintln('vfmt format_file: compiler_params: AFTER fill_with_defaults() ')
|
eprintln('vfmt2 fmt.fmt worked and ${formatted_content.len} bytes were written to ${vfmt_output_path} .')
|
||||||
print_compiler_options( compiler_params )
|
|
||||||
}
|
}
|
||||||
formatted_file_path := foptions.compile_file(file, compiler_params)
|
eprintln('${FORMATTED_FILE_TOKEN}${vfmt_output_path}')
|
||||||
if use_tmp_main_program {
|
|
||||||
if !foptions.is_debug {
|
|
||||||
os.rm(cfile)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
eprintln('${FORMATTED_FILE_TOKEN}${formatted_file_path}')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_compiler_options( compiler_params &pref.Preferences ) {
|
fn print_compiler_options( compiler_params &pref.Preferences ) {
|
||||||
|
@ -311,21 +242,6 @@ fn find_working_diff_command() ?string {
|
||||||
return error('no working diff command found')
|
return error('no working diff command found')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (foptions &FormatOptions) compile_file(file string, compiler_params &pref.Preferences) string {
|
|
||||||
if foptions.is_verbose {
|
|
||||||
eprintln('> new_v_compiler_with_args file: $file')
|
|
||||||
eprintln('> new_v_compiler_with_args compiler_params:')
|
|
||||||
print_compiler_options( compiler_params )
|
|
||||||
}
|
|
||||||
mut v := compiler.new_v(compiler_params)
|
|
||||||
v.v_fmt_file = file
|
|
||||||
if foptions.is_all {
|
|
||||||
v.v_fmt_all = true
|
|
||||||
}
|
|
||||||
v.compile()
|
|
||||||
return v.v_fmt_file_result
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (f FormatOptions) str() string {
|
pub fn (f FormatOptions) str() string {
|
||||||
return 'FormatOptions{ ' + ' is_2: $f.is_2' + ' is_l: $f.is_l' + ' is_w: $f.is_w' + ' is_diff: $f.is_diff' + ' is_verbose: $f.is_verbose' + ' is_all: $f.is_all' + ' is_worker: $f.is_worker' + ' is_debug: $f.is_debug' + ' }'
|
return 'FormatOptions{ ' + ' is_2: $f.is_2' + ' is_l: $f.is_l' + ' is_w: $f.is_w' + ' is_diff: $f.is_diff' + ' is_verbose: $f.is_verbose' + ' is_all: $f.is_all' + ' is_worker: $f.is_worker' + ' is_debug: $f.is_debug' + ' }'
|
||||||
}
|
}
|
||||||
|
@ -435,3 +351,7 @@ fn join_flags_and_argument() []string {
|
||||||
fn non_empty(arg []string) []string {
|
fn non_empty(arg []string) []string {
|
||||||
return arg.filter(it != '')
|
return arg.filter(it != '')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn verror(s string){
|
||||||
|
util.verror('vfmt error', s)
|
||||||
|
}
|
||||||
|
|
|
@ -7,10 +7,6 @@ import (
|
||||||
v.pref
|
v.pref
|
||||||
)
|
)
|
||||||
|
|
||||||
pub const (
|
|
||||||
v_modules_path = os.home_dir() + '.vmodules'
|
|
||||||
)
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
args := os.args
|
args := os.args
|
||||||
args_string := args[1..].join(' ')
|
args_string := args[1..].join(' ')
|
||||||
|
@ -62,7 +58,8 @@ fn v_test_compiler(vargs string) {
|
||||||
if ret != 0 {
|
if ret != 0 {
|
||||||
eprintln('failed to run v install')
|
eprintln('failed to run v install')
|
||||||
}
|
}
|
||||||
if !os.exists(v_modules_path + '/nedpals/args') {
|
desired_path := os.join_path(pref.default_module_path, 'nedpals', 'args')
|
||||||
|
if !(os.exists( desired_path ) && os.is_dir( desired_path )) {
|
||||||
eprintln('v failed to install a test module')
|
eprintln('v failed to install a test module')
|
||||||
}
|
}
|
||||||
vmark.stop()
|
vmark.stop()
|
||||||
|
|
|
@ -11,10 +11,6 @@ import (
|
||||||
term
|
term
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
v_modules_path = pref.default_module_path
|
|
||||||
)
|
|
||||||
|
|
||||||
fn todo() {
|
fn todo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +153,7 @@ fn (v mut V) cc() {
|
||||||
}
|
}
|
||||||
if v.pref.build_mode == .build_module {
|
if v.pref.build_mode == .build_module {
|
||||||
// Create the modules & out directory if it's not there.
|
// Create the modules & out directory if it's not there.
|
||||||
mut out_dir := if v.pref.path.starts_with('vlib') { '$v_modules_path${os.path_separator}cache${os.path_separator}$v.pref.path' } else { '$v_modules_path${os.path_separator}$v.pref.path' }
|
mut out_dir := if v.pref.path.starts_with('vlib') { '${pref.default_module_path}${os.path_separator}cache${os.path_separator}$v.pref.path' } else { '${pref.default_module_path}${os.path_separator}$v.pref.path' }
|
||||||
pdir := out_dir.all_before_last(os.path_separator)
|
pdir := out_dir.all_before_last(os.path_separator)
|
||||||
if !os.is_dir(pdir) {
|
if !os.is_dir(pdir) {
|
||||||
os.mkdir_all(pdir)
|
os.mkdir_all(pdir)
|
||||||
|
@ -226,7 +222,7 @@ fn (v mut V) cc() {
|
||||||
else if v.pref.is_cache {
|
else if v.pref.is_cache {
|
||||||
/*
|
/*
|
||||||
QTODO
|
QTODO
|
||||||
builtin_o_path := os.join_path(v_modules_path, 'cache', 'vlib', 'builtin.o')
|
builtin_o_path := os.join_path(pref.default_module_path, 'cache', 'vlib', 'builtin.o')
|
||||||
a << builtin_o_path.replace('builtin.o', 'strconv.o') // TODO hack no idea why this is needed
|
a << builtin_o_path.replace('builtin.o', 'strconv.o') // TODO hack no idea why this is needed
|
||||||
if os.exists(builtin_o_path) {
|
if os.exists(builtin_o_path) {
|
||||||
libs = builtin_o_path
|
libs = builtin_o_path
|
||||||
|
@ -243,7 +239,7 @@ fn (v mut V) cc() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
imp_path := imp.replace('.', os.path_separator)
|
imp_path := imp.replace('.', os.path_separator)
|
||||||
path := '$v_modules_path${os.path_separator}cache${os.path_separator}vlib${os.path_separator}${imp_path}.o'
|
path := '${pref.default_module_path}${os.path_separator}cache${os.path_separator}vlib${os.path_separator}${imp_path}.o'
|
||||||
// println('adding ${imp_path}.o')
|
// println('adding ${imp_path}.o')
|
||||||
if os.exists(path) {
|
if os.exists(path) {
|
||||||
libs += ' ' + path
|
libs += ' ' + path
|
||||||
|
@ -255,7 +251,7 @@ fn (v mut V) cc() {
|
||||||
os.cp('$vdir/thirdparty/ui/ui.o', path)or{
|
os.cp('$vdir/thirdparty/ui/ui.o', path)or{
|
||||||
panic('error copying ui files')
|
panic('error copying ui files')
|
||||||
}
|
}
|
||||||
os.cp('$vdir/thirdparty/ui/ui.vh', v_modules_path + '/vlib/ui.vh')or{
|
os.cp('$vdir/thirdparty/ui/ui.vh', pref.default_module_path + '/vlib/ui.vh')or{
|
||||||
panic('error copying ui files')
|
panic('error copying ui files')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -484,13 +480,13 @@ fn (c mut V) cc_windows_cross() {
|
||||||
args += if c.pref.ccompiler == 'msvc' { cflags.c_options_before_target_msvc() } else { cflags.c_options_before_target() }
|
args += if c.pref.ccompiler == 'msvc' { cflags.c_options_before_target_msvc() } else { cflags.c_options_before_target() }
|
||||||
mut libs := ''
|
mut libs := ''
|
||||||
if false && c.pref.build_mode == .default_mode {
|
if false && c.pref.build_mode == .default_mode {
|
||||||
libs = '"$v_modules_path/vlib/builtin.o"'
|
libs = '"${pref.default_module_path}/vlib/builtin.o"'
|
||||||
if !os.exists(libs) {
|
if !os.exists(libs) {
|
||||||
println('`$libs` not found')
|
println('`$libs` not found')
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
for imp in c.table.imports {
|
for imp in c.table.imports {
|
||||||
libs += ' "$v_modules_path/vlib/${imp}.o"'
|
libs += ' "${pref.default_module_path}/vlib/${imp}.o"'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
args += ' $c.out_name_c '
|
args += ' $c.out_name_c '
|
||||||
|
@ -498,11 +494,11 @@ fn (c mut V) cc_windows_cross() {
|
||||||
args += if c.pref.ccompiler == 'msvc' { cflags.c_options_after_target_msvc() } else { cflags.c_options_after_target() }
|
args += if c.pref.ccompiler == 'msvc' { cflags.c_options_after_target_msvc() } else { cflags.c_options_after_target() }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
winroot := '$v_modules_path/winroot'
|
winroot := '${pref.default_module_path}/winroot'
|
||||||
if !os.is_dir(winroot) {
|
if !os.is_dir(winroot) {
|
||||||
winroot_url := 'https://github.com/vlang/v/releases/download/v0.1.10/winroot.zip'
|
winroot_url := 'https://github.com/vlang/v/releases/download/v0.1.10/winroot.zip'
|
||||||
println('"$winroot" not found.')
|
println('"$winroot" not found.')
|
||||||
println('Download it from $winroot_url and save it in $v_modules_path')
|
println('Download it from $winroot_url and save it in ${pref.default_module_path}')
|
||||||
println('Unzip it afterwards.\n')
|
println('Unzip it afterwards.\n')
|
||||||
println('winroot.zip contains all library and header files needed ' + 'to cross-compile for Windows.')
|
println('winroot.zip contains all library and header files needed ' + 'to cross-compile for Windows.')
|
||||||
exit(1)
|
exit(1)
|
||||||
|
@ -522,7 +518,7 @@ fn (c mut V) cc_windows_cross() {
|
||||||
}
|
}
|
||||||
|
|
||||||
println(cmd)
|
println(cmd)
|
||||||
//cmd := 'clang -o $obj_name -w $include -m32 -c -target x86_64-win32 $v_modules_path/$c.out_name_c'
|
//cmd := 'clang -o $obj_name -w $include -m32 -c -target x86_64-win32 ${pref.default_module_path}/$c.out_name_c'
|
||||||
if c.pref.verbosity.is_higher_or_equal(.level_one) {
|
if c.pref.verbosity.is_higher_or_equal(.level_one) {
|
||||||
println(cmd)
|
println(cmd)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
os
|
os
|
||||||
v.builder
|
v.builder
|
||||||
v.pref
|
v.pref
|
||||||
|
v.util
|
||||||
strings
|
strings
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -216,13 +217,6 @@ fn (v mut V) set_module_lookup_paths() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn verror(s string) {
|
|
||||||
println('V error: $s')
|
|
||||||
os.flush()
|
|
||||||
exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (v &V) get_builtin_files() []string {
|
pub fn (v &V) get_builtin_files() []string {
|
||||||
// Lookup for built-in folder in lookup path.
|
// Lookup for built-in folder in lookup path.
|
||||||
// Assumption: `builtin/` folder implies usable implementation of builtin
|
// Assumption: `builtin/` folder implies usable implementation of builtin
|
||||||
|
@ -405,4 +399,6 @@ pub fn (v &V) v_files_from_dir(dir string) []string {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn verror(s string) {
|
||||||
|
util.verror('compiler error', s)
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
internal.flag
|
internal.flag
|
||||||
os.cmdline
|
os.cmdline
|
||||||
v.pref
|
v.pref
|
||||||
|
v.util
|
||||||
)
|
)
|
||||||
|
|
||||||
fn parse_arguments(args []string) (pref.Preferences, []string) {
|
fn parse_arguments(args []string) (pref.Preferences, []string) {
|
||||||
|
@ -72,6 +73,14 @@ fn parse_arguments(args []string) (pref.Preferences, []string) {
|
||||||
|
|
||||||
fn parse_options(flag string, f mut flag.Instance, prefs mut pref.Preferences) {
|
fn parse_options(flag string, f mut flag.Instance, prefs mut pref.Preferences) {
|
||||||
match flag {
|
match flag {
|
||||||
|
'color' {
|
||||||
|
f.is_equivalent_to(['color','nocolor'])
|
||||||
|
util.emanager.set_support_color(true)
|
||||||
|
}
|
||||||
|
'nocolor' {
|
||||||
|
f.is_equivalent_to(['color','nocolor'])
|
||||||
|
util.emanager.set_support_color(false)
|
||||||
|
}
|
||||||
'path' {
|
'path' {
|
||||||
// -path
|
// -path
|
||||||
path_str := f.string() or {
|
path_str := f.string() or {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
module compile
|
module compile
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import v.pref
|
||||||
|
|
||||||
#flag windows -l shell32
|
#flag windows -l shell32
|
||||||
#flag windows -l dbghelp
|
#flag windows -l dbghelp
|
||||||
|
@ -225,7 +226,7 @@ pub fn (v mut V) cc_msvc() {
|
||||||
}
|
}
|
||||||
else if v.pref.build_mode == .default_mode {
|
else if v.pref.build_mode == .default_mode {
|
||||||
/*
|
/*
|
||||||
b := os.real_path( '$v_modules_path/vlib/builtin.obj' )
|
b := os.real_path( '${pref.default_module_path}/vlib/builtin.obj' )
|
||||||
alibs << '"$b"'
|
alibs << '"$b"'
|
||||||
if !os.exists(b) {
|
if !os.exists(b) {
|
||||||
println('`builtin.obj` not found')
|
println('`builtin.obj` not found')
|
||||||
|
@ -235,7 +236,7 @@ pub fn (v mut V) cc_msvc() {
|
||||||
if imp == 'webview' {
|
if imp == 'webview' {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
alibs << '"' + os.real_path( '$v_modules_path/vlib/${imp}.obj' ) + '"'
|
alibs << '"' + os.real_path( '${pref.default_module_path}/vlib/${imp}.obj' ) + '"'
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,91 +0,0 @@
|
||||||
// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved.
|
|
||||||
// Use of this source code is governed by an MIT license
|
|
||||||
// that can be found in the LICENSE file.
|
|
||||||
module main
|
|
||||||
|
|
||||||
import (
|
|
||||||
os
|
|
||||||
v.pref
|
|
||||||
)
|
|
||||||
|
|
||||||
fn set_vroot_folder(vroot_path string) {
|
|
||||||
// Preparation for the compiler module:
|
|
||||||
// VEXE env variable is needed so that compiler.vexe_path()
|
|
||||||
// can return it later to whoever needs it:
|
|
||||||
vname := if os.user_os() == 'windows' { 'v.exe' } else { 'v' }
|
|
||||||
os.setenv('VEXE', os.real_path([vroot_path, vname].join(os.path_separator)), true)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn launch_tool(is_verbose bool, tool_name string) {
|
|
||||||
vexe := pref.vexe_path()
|
|
||||||
vroot := os.dir(vexe)
|
|
||||||
set_vroot_folder(vroot)
|
|
||||||
|
|
||||||
tool_args := os.args[1..].join(' ')
|
|
||||||
tool_exe := path_of_executable(os.real_path('$vroot/cmd/tools/$tool_name'))
|
|
||||||
tool_source := os.real_path('$vroot/cmd/tools/${tool_name}.v')
|
|
||||||
tool_command := '"$tool_exe" $tool_args'
|
|
||||||
if is_verbose {
|
|
||||||
eprintln('launch_tool vexe : $vroot')
|
|
||||||
eprintln('launch_tool vroot : $vroot')
|
|
||||||
eprintln('launch_tool tool_args : $tool_args')
|
|
||||||
eprintln('launch_tool tool_command: $tool_command')
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Caching should be done on the `vlib/v` level.
|
|
||||||
mut should_compile := false
|
|
||||||
if !os.exists(tool_exe) {
|
|
||||||
should_compile = true
|
|
||||||
} else {
|
|
||||||
if os.file_last_mod_unix(tool_exe) <= os.file_last_mod_unix(vexe) {
|
|
||||||
// v was recompiled, maybe after v up ...
|
|
||||||
// rebuild the tool too just in case
|
|
||||||
should_compile = true
|
|
||||||
|
|
||||||
if tool_name == 'vself' || tool_name == 'vup' {
|
|
||||||
// The purpose of vself/up is to update and recompile v itself.
|
|
||||||
// After the first 'v self' execution, v will be modified, so
|
|
||||||
// then a second 'v self' will detect, that v is newer than the
|
|
||||||
// vself executable, and try to recompile vself/up again, which
|
|
||||||
// will slow down the next v recompilation needlessly.
|
|
||||||
should_compile = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if os.file_last_mod_unix(tool_exe) <= os.file_last_mod_unix(tool_source) {
|
|
||||||
// the user changed the source code of the tool, or git updated it:
|
|
||||||
should_compile = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if is_verbose {
|
|
||||||
eprintln('launch_tool should_compile: $should_compile')
|
|
||||||
}
|
|
||||||
|
|
||||||
if should_compile {
|
|
||||||
mut compilation_command := '"$vexe" '
|
|
||||||
if tool_name == 'vfmt' {
|
|
||||||
// TODO Remove when it's no longer required by fmt
|
|
||||||
compilation_command += '-d vfmt '
|
|
||||||
}
|
|
||||||
compilation_command += '"$tool_source"'
|
|
||||||
if is_verbose {
|
|
||||||
eprintln('Compiling $tool_name with: "$compilation_command"')
|
|
||||||
}
|
|
||||||
tool_compilation := os.exec(compilation_command) or { panic(err) }
|
|
||||||
if tool_compilation.exit_code != 0 {
|
|
||||||
panic('V tool "$tool_source" could not be compiled\n' + tool_compilation.output)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if is_verbose {
|
|
||||||
eprintln('launch_tool running tool command: $tool_command ...')
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(os.system(tool_command))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn path_of_executable(path string) string {
|
|
||||||
$if windows {
|
|
||||||
return path + '.exe'
|
|
||||||
}
|
|
||||||
return path
|
|
||||||
}
|
|
|
@ -30,7 +30,7 @@ fn main() {
|
||||||
if args.len == 0 || args[0] in ['-', 'repl'] {
|
if args.len == 0 || args[0] in ['-', 'repl'] {
|
||||||
// Running `./v` without args launches repl
|
// Running `./v` without args launches repl
|
||||||
println('For usage information, quit V REPL using `exit` and use `v help`')
|
println('For usage information, quit V REPL using `exit` and use `v help`')
|
||||||
launch_tool(false, 'vrepl')
|
util.launch_tool(false, 'vrepl')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if args.len > 0 && (args[0] in ['version', '-V', '-version', '--version'] || (args[0] == '-v' && args.len == 1) ) {
|
if args.len > 0 && (args[0] in ['version', '-V', '-version', '--version'] || (args[0] == '-v' && args.len == 1) ) {
|
||||||
|
@ -53,7 +53,7 @@ fn main() {
|
||||||
// Note for future contributors: Please add new subcommands in the `match` block below.
|
// Note for future contributors: Please add new subcommands in the `match` block below.
|
||||||
if command in simple_cmd {
|
if command in simple_cmd {
|
||||||
// External tools
|
// External tools
|
||||||
launch_tool(prefs2.is_verbose, 'v' + command)
|
util.launch_tool(prefs2.is_verbose, 'v' + command)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
match command {
|
match command {
|
||||||
|
@ -61,7 +61,7 @@ fn main() {
|
||||||
invoke_help_and_exit(args)
|
invoke_help_and_exit(args)
|
||||||
}
|
}
|
||||||
'create', 'init' {
|
'create', 'init' {
|
||||||
launch_tool(prefs2.is_verbose, 'vcreate')
|
util.launch_tool(prefs2.is_verbose, 'vcreate')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
'translate' {
|
'translate' {
|
||||||
|
@ -69,7 +69,7 @@ fn main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
'search', 'install', 'update', 'remove' {
|
'search', 'install', 'update', 'remove' {
|
||||||
launch_tool(prefs2.is_verbose, 'vpm')
|
util.launch_tool(prefs2.is_verbose, 'vpm')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
'get' {
|
'get' {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
v.ast
|
v.ast
|
||||||
v.table
|
v.table
|
||||||
v.pref
|
v.pref
|
||||||
|
v.util
|
||||||
v.checker
|
v.checker
|
||||||
v.parser
|
v.parser
|
||||||
v.gen
|
v.gen
|
||||||
|
@ -195,10 +196,6 @@ pub fn (b &Builder) v_files_from_dir(dir string) []string {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verror(err string) {
|
|
||||||
panic('v error: $err')
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (b &Builder) log(s string) {
|
pub fn (b &Builder) log(s string) {
|
||||||
if b.pref.verbosity.is_higher_or_equal(.level_two) {
|
if b.pref.verbosity.is_higher_or_equal(.level_two) {
|
||||||
println(s)
|
println(s)
|
||||||
|
@ -233,3 +230,7 @@ pub fn (b &Builder) find_module_path(mod string) ?string {
|
||||||
}
|
}
|
||||||
return error('module "$mod" not found')
|
return error('module "$mod" not found')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn verror(s string) {
|
||||||
|
util.verror('builder error', s)
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
v.table
|
v.table
|
||||||
v.token
|
v.token
|
||||||
v.pref
|
v.pref
|
||||||
|
v.util
|
||||||
os
|
os
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -922,15 +923,6 @@ pub fn (c mut Checker) ident(ident mut ast.Ident) table.Type {
|
||||||
if !name.contains('.') && !(c.file.mod.name in ['builtin', 'main']) {
|
if !name.contains('.') && !(c.file.mod.name in ['builtin', 'main']) {
|
||||||
name = '${c.file.mod.name}.$ident.name'
|
name = '${c.file.mod.name}.$ident.name'
|
||||||
}
|
}
|
||||||
// hack - const until consts are fixed properly
|
|
||||||
if ident.name == 'v_modules_path' {
|
|
||||||
ident.name = name
|
|
||||||
ident.kind = .constant
|
|
||||||
ident.info = ast.IdentVar{
|
|
||||||
typ: table.string_type
|
|
||||||
}
|
|
||||||
return table.string_type
|
|
||||||
}
|
|
||||||
// constant
|
// constant
|
||||||
if constant := c.table.find_const(name) {
|
if constant := c.table.find_const(name) {
|
||||||
ident.name = name
|
ident.name = name
|
||||||
|
@ -1180,28 +1172,17 @@ pub fn (c mut Checker) error(s string, pos token.Position) {
|
||||||
if c.pref.verbosity.is_higher_or_equal(.level_one) {
|
if c.pref.verbosity.is_higher_or_equal(.level_one) {
|
||||||
print_backtrace()
|
print_backtrace()
|
||||||
}
|
}
|
||||||
mut path := c.file.path
|
kind := if c.pref.verbosity.is_higher_or_equal(.level_one) {
|
||||||
// Get relative path
|
'checker error #$c.nr_errors:'
|
||||||
workdir := os.getwd() + os.path_separator
|
} else {
|
||||||
if path.starts_with(workdir) {
|
'error:'
|
||||||
path = path.replace(workdir, '')
|
|
||||||
}
|
}
|
||||||
mut final_msg_line := '$path:$pos.line_nr: $s'
|
ferror := util.formated_error(kind, s, c.file.path, pos)
|
||||||
if c.pref.verbosity.is_higher_or_equal(.level_one) {
|
c.errors << ferror
|
||||||
final_msg_line = '$path:$pos.line_nr: checker error #$c.nr_errors: $s'
|
|
||||||
}
|
|
||||||
c.errors << final_msg_line
|
|
||||||
if !(pos.line_nr in c.error_lines) {
|
if !(pos.line_nr in c.error_lines) {
|
||||||
eprintln(final_msg_line)
|
eprintln(ferror)
|
||||||
}
|
}
|
||||||
c.error_lines << pos.line_nr
|
c.error_lines << pos.line_nr
|
||||||
/*
|
|
||||||
if colored_output {
|
|
||||||
eprintln(term.bold(term.red(final_msg_line)))
|
|
||||||
}else{
|
|
||||||
eprintln(final_msg_line)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if c.pref.verbosity.is_higher_or_equal(.level_one) {
|
if c.pref.verbosity.is_higher_or_equal(.level_one) {
|
||||||
println('\n\n')
|
println('\n\n')
|
||||||
}
|
}
|
||||||
|
|
|
@ -2022,8 +2022,7 @@ fn (g mut Gen) ref_or_deref_arg(arg ast.CallArg, expected_type table.Type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verror(s string) {
|
fn verror(s string) {
|
||||||
println('cgen error: $s')
|
util.verror('cgen error', s)
|
||||||
exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (g mut Gen) write_init_function() {
|
fn (g mut Gen) write_init_function() {
|
||||||
|
|
|
@ -5,6 +5,7 @@ module x64
|
||||||
|
|
||||||
import (
|
import (
|
||||||
v.ast
|
v.ast
|
||||||
|
v.util
|
||||||
// term
|
// term
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -387,11 +388,10 @@ fn (g mut Gen) expr(node ast.Expr) {
|
||||||
ast.IfExpr {}
|
ast.IfExpr {}
|
||||||
else {
|
else {
|
||||||
// println(term.red('x64.expr(): bad node'))
|
// println(term.red('x64.expr(): bad node'))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn verror(s string) {
|
fn verror(s string) {
|
||||||
println(s)
|
util.verror('x64 gen error', s)
|
||||||
exit(1)
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
v.token
|
v.token
|
||||||
v.table
|
v.table
|
||||||
v.pref
|
v.pref
|
||||||
|
v.util
|
||||||
term
|
term
|
||||||
os
|
os
|
||||||
// runtime
|
// runtime
|
||||||
|
@ -16,10 +17,6 @@ import (
|
||||||
// time
|
// time
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
colored_output = term.can_show_color_on_stderr()
|
|
||||||
)
|
|
||||||
|
|
||||||
struct Parser {
|
struct Parser {
|
||||||
scanner &scanner.Scanner
|
scanner &scanner.Scanner
|
||||||
file_name string
|
file_name string
|
||||||
|
@ -235,7 +232,7 @@ fn (p mut Parser) check(expected token.Kind) {
|
||||||
// p.next()
|
// p.next()
|
||||||
// }
|
// }
|
||||||
if p.tok.kind != expected {
|
if p.tok.kind != expected {
|
||||||
s := 'syntax error: unexpected `${p.tok.kind.str()}`, expecting `${expected.str()}`'
|
s := 'unexpected `${p.tok.kind.str()}`, expecting `${expected.str()}`'
|
||||||
p.error(s)
|
p.error(s)
|
||||||
}
|
}
|
||||||
p.next()
|
p.next()
|
||||||
|
@ -328,7 +325,7 @@ pub fn (p mut Parser) top_stmt() ast.Stmt {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// #printf("");
|
// #printf("");
|
||||||
p.error('parser: bad top level statement ' + p.tok.str())
|
p.error('bad top level statement ' + p.tok.str())
|
||||||
return ast.Stmt{}
|
return ast.Stmt{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -499,42 +496,19 @@ fn (p mut Parser) range_expr(low ast.Expr) ast.Expr {
|
||||||
|
|
||||||
|
|
||||||
pub fn (p &Parser) error(s string) {
|
pub fn (p &Parser) error(s string) {
|
||||||
print_backtrace()
|
mut kind := 'error:'
|
||||||
mut path := p.file_name
|
if p.pref.verbosity.is_higher_or_equal(.level_one) {
|
||||||
// Get relative path
|
print_backtrace()
|
||||||
workdir := os.getwd() + os.path_separator
|
kind = 'parser error:'
|
||||||
if path.starts_with(workdir) {
|
|
||||||
path = path.replace(workdir, '')
|
|
||||||
}
|
|
||||||
final_msg_line := '$path:$p.tok.line_nr: error: $s'
|
|
||||||
if colored_output {
|
|
||||||
eprintln(term.bold(term.red(final_msg_line)))
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
eprintln(final_msg_line)
|
|
||||||
}
|
|
||||||
exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (p &Parser) error_at_line(s string, line_nr int) {
|
|
||||||
final_msg_line := '$p.file_name:$line_nr: error: $s'
|
|
||||||
if colored_output {
|
|
||||||
eprintln(term.bold(term.red(final_msg_line)))
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
eprintln(final_msg_line)
|
|
||||||
}
|
}
|
||||||
|
ferror := util.formated_error(kind, s, p.file_name, p.tok.position())
|
||||||
|
eprintln(ferror)
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (p &Parser) warn(s string) {
|
pub fn (p &Parser) warn(s string) {
|
||||||
final_msg_line := '$p.file_name:$p.tok.line_nr: warning: $s'
|
ferror := util.formated_error('warning:', s, p.file_name, p.tok.position())
|
||||||
if colored_output {
|
eprintln(ferror)
|
||||||
eprintln(term.bold(term.blue(final_msg_line)))
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
eprintln(final_msg_line)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (p mut Parser) parse_ident(is_c bool) ast.Ident {
|
pub fn (p mut Parser) parse_ident(is_c bool) ast.Ident {
|
||||||
|
@ -839,7 +813,7 @@ pub fn (p mut Parser) expr(precedence int) ast.Expr {
|
||||||
p.check(.rcbr)
|
p.check(.rcbr)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p.error('parser: expr(): bad token `$p.tok.str()`')
|
p.error('expr(): bad token `$p.tok.str()`')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Infix
|
// Infix
|
||||||
|
@ -2003,6 +1977,5 @@ fn (p &Parser) new_true_expr() ast.Expr {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verror(s string) {
|
fn verror(s string) {
|
||||||
println(s)
|
util.verror('parser error', s)
|
||||||
exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,22 @@
|
||||||
module pref
|
module pref
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import term
|
||||||
|
|
||||||
pub const (
|
pub const (
|
||||||
default_module_path = os.home_dir() + '.vmodules'
|
default_module_path = mpath()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fn mpath() string {
|
||||||
|
return os.home_dir() + '.vmodules'
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_preferences() Preferences {
|
||||||
|
p := Preferences{}
|
||||||
|
p.fill_with_defaults()
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (p mut Preferences) fill_with_defaults() {
|
pub fn (p mut Preferences) fill_with_defaults() {
|
||||||
if p.vroot == '' {
|
if p.vroot == '' {
|
||||||
// Location of all vlib files
|
// Location of all vlib files
|
||||||
|
@ -22,7 +33,7 @@ pub fn (p mut Preferences) fill_with_defaults() {
|
||||||
p.lookup_path[i] = path.replace('@vlib', vlib_path).replace('@vmodules', default_module_path)
|
p.lookup_path[i] = path.replace('@vlib', vlib_path).replace('@vmodules', default_module_path)
|
||||||
}
|
}
|
||||||
rpath := os.real_path(p.path)
|
rpath := os.real_path(p.path)
|
||||||
if p.out_name == ''{
|
if p.out_name == '' {
|
||||||
filename := os.file_name(rpath).trim_space()
|
filename := os.file_name(rpath).trim_space()
|
||||||
mut base := filename.all_before_last('.')
|
mut base := filename.all_before_last('.')
|
||||||
if base == '' {
|
if base == '' {
|
||||||
|
@ -60,6 +71,7 @@ pub fn (p mut Preferences) fill_with_defaults() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
p.enable_globals = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_c_compiler() string {
|
fn default_c_compiler() string {
|
||||||
|
|
|
@ -13,8 +13,6 @@ import (
|
||||||
const (
|
const (
|
||||||
single_quote = `\'`
|
single_quote = `\'`
|
||||||
double_quote = `"`
|
double_quote = `"`
|
||||||
error_context_before = 2 // how many lines of source context to print before the pointer line
|
|
||||||
error_context_after = 2 // ^^^ same, but after
|
|
||||||
is_fmt = os.getenv('VEXE').contains('vfmt')
|
is_fmt = os.getenv('VEXE').contains('vfmt')
|
||||||
num_sep = `_` // char used as number separator
|
num_sep = `_` // char used as number separator
|
||||||
)
|
)
|
||||||
|
@ -1027,9 +1025,7 @@ pub fn (s &Scanner) error(msg string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn verror(s string) {
|
pub fn verror(s string) {
|
||||||
println('V error: $s')
|
util.verror('scanner error', s)
|
||||||
os.flush()
|
|
||||||
exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cescaped_path(s string) string {
|
pub fn cescaped_path(s string) string {
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved.
|
||||||
|
// Use of this source code is governed by an MIT license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
module util
|
||||||
|
|
||||||
|
import os
|
||||||
|
import term
|
||||||
|
import v.token
|
||||||
|
import v.util
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
// NB: using only the filename may lead to inability of IDE/editors
|
||||||
|
// to find the source file, when the IDE has a different working folder than
|
||||||
|
// v itself.
|
||||||
|
|
||||||
|
const (
|
||||||
|
error_context_before = 2 // how many lines of source context to print before the pointer line
|
||||||
|
error_context_after = 2 // ^^^ same, but after
|
||||||
|
)
|
||||||
|
|
||||||
|
pub const (
|
||||||
|
emanager = new_error_manager()
|
||||||
|
)
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
pub struct EManager {
|
||||||
|
pub mut:
|
||||||
|
support_color bool // should the error and other messages
|
||||||
|
// have ANSI terminal escape color codes in them.
|
||||||
|
// By default, v tries to autodetect, if the terminal supports colors.
|
||||||
|
// Use -color and -nocolor options to override the detection decision.
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (e &EManager) set_support_color(b bool) {
|
||||||
|
e.support_color = b
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_error_manager() &EManager {
|
||||||
|
return &EManager{ support_color: term.can_show_color_on_stderr() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn formated_error(kind string /*error or warn*/, emsg string, filepath string, pos token.Position) string {
|
||||||
|
mut path := filepath
|
||||||
|
verror_paths_override := os.getenv('VERROR_PATHS')
|
||||||
|
if verror_paths_override == 'absolute' {
|
||||||
|
path = os.real_path( path )
|
||||||
|
}else{
|
||||||
|
// Get relative path
|
||||||
|
workdir := os.getwd() + os.path_separator
|
||||||
|
if path.starts_with(workdir) {
|
||||||
|
path = path.replace(workdir, '')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
column := 0
|
||||||
|
position := '${path}:${pos.line_nr+1}:$column:'
|
||||||
|
// QTODO: retrieve source lines around pos.line_nr and add them here
|
||||||
|
mut source_context := ''
|
||||||
|
//
|
||||||
|
final_position := if emanager.support_color {
|
||||||
|
term.bold(term.white(position))
|
||||||
|
} else {
|
||||||
|
position
|
||||||
|
}
|
||||||
|
mut final_kind := kind
|
||||||
|
if emanager.support_color {
|
||||||
|
final_kind = if kind.contains('error') {
|
||||||
|
term.bold(term.red(kind))
|
||||||
|
}else{
|
||||||
|
term.bold(term.bright_blue(kind))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final_msg := emsg
|
||||||
|
final_context := if source_context.len > 0 { '\n$source_context' } else { '' }
|
||||||
|
//
|
||||||
|
return '$final_position $final_kind $final_msg $final_context'.trim_space()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn verror(kind string, s string) {
|
||||||
|
if emanager.support_color {
|
||||||
|
eprintln( term.bold(term.red(kind)) + ': $s' )
|
||||||
|
}else{
|
||||||
|
eprintln('${kind}: $s')
|
||||||
|
}
|
||||||
|
exit(1)
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
module util
|
module util
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import v.pref
|
||||||
|
|
||||||
pub const (
|
pub const (
|
||||||
v_version = '0.1.26'
|
v_version = '0.1.26'
|
||||||
|
@ -75,3 +76,82 @@ pub fn githash(should_get_from_filesystem bool) string {
|
||||||
C.snprintf(charptr(buf), 50, '%s', C.V_CURRENT_COMMIT_HASH)
|
C.snprintf(charptr(buf), 50, '%s', C.V_CURRENT_COMMIT_HASH)
|
||||||
return tos_clone(buf)
|
return tos_clone(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
fn set_vroot_folder(vroot_path string) {
|
||||||
|
// Preparation for the compiler module:
|
||||||
|
// VEXE env variable is needed so that compiler.vexe_path()
|
||||||
|
// can return it later to whoever needs it:
|
||||||
|
vname := if os.user_os() == 'windows' { 'v.exe' } else { 'v' }
|
||||||
|
os.setenv('VEXE', os.real_path(os.join_path( vroot_path, vname)), true)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn launch_tool(is_verbose bool, tool_name string) {
|
||||||
|
vexe := pref.vexe_path()
|
||||||
|
vroot := os.dir(vexe)
|
||||||
|
set_vroot_folder(vroot)
|
||||||
|
|
||||||
|
tool_args := os.args[1..].join(' ')
|
||||||
|
tool_exe := path_of_executable(os.real_path('$vroot/cmd/tools/$tool_name'))
|
||||||
|
tool_source := os.real_path('$vroot/cmd/tools/${tool_name}.v')
|
||||||
|
tool_command := '"$tool_exe" $tool_args'
|
||||||
|
if is_verbose {
|
||||||
|
eprintln('launch_tool vexe : $vroot')
|
||||||
|
eprintln('launch_tool vroot : $vroot')
|
||||||
|
eprintln('launch_tool tool_args : $tool_args')
|
||||||
|
eprintln('launch_tool tool_command: $tool_command')
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Caching should be done on the `vlib/v` level.
|
||||||
|
mut should_compile := false
|
||||||
|
if !os.exists(tool_exe) {
|
||||||
|
should_compile = true
|
||||||
|
} else {
|
||||||
|
if os.file_last_mod_unix(tool_exe) <= os.file_last_mod_unix(vexe) {
|
||||||
|
// v was recompiled, maybe after v up ...
|
||||||
|
// rebuild the tool too just in case
|
||||||
|
should_compile = true
|
||||||
|
|
||||||
|
if tool_name == 'vself' || tool_name == 'vup' {
|
||||||
|
// The purpose of vself/up is to update and recompile v itself.
|
||||||
|
// After the first 'v self' execution, v will be modified, so
|
||||||
|
// then a second 'v self' will detect, that v is newer than the
|
||||||
|
// vself executable, and try to recompile vself/up again, which
|
||||||
|
// will slow down the next v recompilation needlessly.
|
||||||
|
should_compile = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if os.file_last_mod_unix(tool_exe) <= os.file_last_mod_unix(tool_source) {
|
||||||
|
// the user changed the source code of the tool, or git updated it:
|
||||||
|
should_compile = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if is_verbose {
|
||||||
|
eprintln('launch_tool should_compile: $should_compile')
|
||||||
|
}
|
||||||
|
|
||||||
|
if should_compile {
|
||||||
|
mut compilation_command := '"$vexe" '
|
||||||
|
compilation_command += '"$tool_source"'
|
||||||
|
if is_verbose {
|
||||||
|
eprintln('Compiling $tool_name with: "$compilation_command"')
|
||||||
|
}
|
||||||
|
tool_compilation := os.exec(compilation_command) or { panic(err) }
|
||||||
|
if tool_compilation.exit_code != 0 {
|
||||||
|
panic('V tool "$tool_source" could not be compiled\n' + tool_compilation.output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if is_verbose {
|
||||||
|
eprintln('launch_tool running tool command: $tool_command ...')
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(os.system(tool_command))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn path_of_executable(path string) string {
|
||||||
|
$if windows {
|
||||||
|
return path + '.exe'
|
||||||
|
}
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue