compiler: support storing temporary files under TMPDIR/v/
Fix for filepath.join not \0 terminating its resultpull/2791/head
parent
200fcd41ce
commit
be7cf3e812
|
@ -799,6 +799,7 @@ pub fn new_v(args[]string) &V {
|
|||
vgen_buf.writeln('module vgen\nimport strings')
|
||||
|
||||
joined_args := args.join(' ')
|
||||
|
||||
target_os := get_arg(joined_args, 'os', '')
|
||||
comptime_define := get_arg(joined_args, 'd', '')
|
||||
//println('comptimedefine=$comptime_define')
|
||||
|
@ -930,8 +931,8 @@ pub fn new_v(args[]string) &V {
|
|||
println('Go to https://vlang.io to install V.')
|
||||
exit(1)
|
||||
}
|
||||
// println('out_name:$out_name')
|
||||
mut out_name_c := os.realpath('${out_name}.tmp.c')
|
||||
|
||||
mut out_name_c := get_vtmp_filename( out_name, '.tmp.c')
|
||||
|
||||
cflags := get_cmdline_cflags(args)
|
||||
|
||||
|
@ -978,7 +979,7 @@ pub fn new_v(args[]string) &V {
|
|||
println('C compiler=$pref.ccompiler')
|
||||
}
|
||||
if pref.is_so {
|
||||
out_name_c = out_name.all_after(os.path_separator) + '_shared_lib.c'
|
||||
out_name_c = get_vtmp_filename( out_name, '.tmp.so.c')
|
||||
}
|
||||
$if !linux {
|
||||
if pref.is_bare && !out_name.ends_with('.c') {
|
||||
|
|
|
@ -28,6 +28,9 @@ pub const (
|
|||
You can set it like this: `export VFLAGS="-cc clang -debug"` on *nix,
|
||||
`set VFLAGS=-cc msvc` on Windows.
|
||||
|
||||
V respects the TMPDIR environment variable, and will put .tmp.c files in TMPDIR/v/ .
|
||||
If you have not set it, a suitable platform specific folder (like /tmp) will be used.
|
||||
|
||||
Options/commands:
|
||||
-h, help Display this information.
|
||||
-o <file> Write output to <file>.
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright (c) 2019 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 compiler
|
||||
|
||||
import os
|
||||
import filepath
|
||||
|
||||
pub fn get_vtmp_folder() string {
|
||||
vtmp := filepath.join(os.tmpdir(),'v')
|
||||
if !os.dir_exists( vtmp ) {
|
||||
os.mkdir(vtmp)
|
||||
}
|
||||
return vtmp
|
||||
}
|
||||
|
||||
pub fn get_vtmp_filename(base_file_name string, postfix string) string {
|
||||
vtmp := get_vtmp_folder()
|
||||
return os.realpath( filepath.join(vtmp, os.filename( base_file_name ) + postfix) )
|
||||
}
|
|
@ -2,7 +2,6 @@ module filepath
|
|||
|
||||
import(
|
||||
os
|
||||
strings
|
||||
)
|
||||
|
||||
// return the extension in the file `path`
|
||||
|
@ -26,11 +25,8 @@ pub fn is_abs(path string) bool {
|
|||
// pass directories as parameters, returns path as string
|
||||
// TODO use []string.join once ...string becomes "[]string"
|
||||
pub fn join(base string, dirs ...string) string {
|
||||
mut path := strings.new_builder(50)
|
||||
path.write(base.trim_right('\\/'))
|
||||
for d in dirs {
|
||||
path.write(os.path_separator)
|
||||
path.write(d)
|
||||
}
|
||||
return path.str()
|
||||
mut result := []string
|
||||
result << base.trim_right('\\/')
|
||||
for d in dirs { result << d }
|
||||
return result.join( os.path_separator )
|
||||
}
|
||||
|
|
51
vlib/os/os.v
51
vlib/os/os.v
|
@ -145,17 +145,26 @@ pub fn cp(old, new string) ?bool {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn cp_r(source_path, dest_path string, overwrite bool) ?bool{
|
||||
pub fn cp_r(osource_path, odest_path string, overwrite bool) ?bool{
|
||||
source_path := os.realpath( osource_path )
|
||||
dest_path := os.realpath( odest_path )
|
||||
if !os.file_exists(source_path) {
|
||||
return error('Source path doesn\'t exist')
|
||||
}
|
||||
//single file copy
|
||||
if !os.is_dir(source_path) {
|
||||
adjasted_path := if os.is_dir(dest_path) {
|
||||
filepath.join(dest_path, os.basedir(source_path)) } else { dest_path }
|
||||
filepath.join(dest_path, os.filename(source_path))
|
||||
} else {
|
||||
dest_path
|
||||
}
|
||||
if os.file_exists(adjasted_path) {
|
||||
if overwrite { os.rm(adjasted_path) }
|
||||
else { return error('Destination file path already exist') }
|
||||
if overwrite {
|
||||
os.rm(adjasted_path)
|
||||
}
|
||||
else {
|
||||
return error('Destination file path already exist')
|
||||
}
|
||||
}
|
||||
os.cp(source_path, adjasted_path) or { return error(err) }
|
||||
return true
|
||||
|
@ -558,7 +567,7 @@ pub fn basedir(path string) string {
|
|||
if pos == -1 {
|
||||
return path
|
||||
}
|
||||
return path[..pos + 1]
|
||||
return path[..pos ] // NB: *without* terminating /
|
||||
}
|
||||
|
||||
pub fn filename(path string) string {
|
||||
|
@ -835,10 +844,6 @@ pub fn realpath(fpath string) string {
|
|||
res = int( !isnil(C._fullpath( fullpath, fpath.str, MAX_PATH )) )
|
||||
}
|
||||
$else{
|
||||
if fpath.len != strlen(fpath.str) {
|
||||
l := strlen(fpath.str)
|
||||
println('FIXME realpath diff len $fpath.len strlen=$l')
|
||||
}
|
||||
ret := C.realpath(fpath.str, fullpath)
|
||||
if ret == 0 {
|
||||
return fpath
|
||||
|
@ -965,3 +970,31 @@ pub fn join(base string, dirs ...string) string {
|
|||
println('use filepath.join')
|
||||
return filepath.join(base, dirs)
|
||||
}
|
||||
|
||||
// tmpdir returns the path to a folder, that is suitable for storing temporary files
|
||||
pub fn tmpdir() string {
|
||||
mut path := os.getenv('TMPDIR')
|
||||
$if linux {
|
||||
if path == '' { path = '/tmp' }
|
||||
}
|
||||
$if mac {
|
||||
/*
|
||||
if path == '' {
|
||||
// TODO untested
|
||||
path = C.NSTemporaryDirectory()
|
||||
}
|
||||
*/
|
||||
if path == '' { path = '/tmp' }
|
||||
}
|
||||
$if windows {
|
||||
if path == '' {
|
||||
// TODO see Qt's implementation?
|
||||
// https://doc.qt.io/qt-5/qdir.html#tempPath
|
||||
// https://github.com/qt/qtbase/blob/e164d61ca8263fc4b46fdd916e1ea77c7dd2b735/src/corelib/io/qfilesystemengine_win.cpp#L1275
|
||||
path = os.getenv('TEMP')
|
||||
if path == '' { path = os.getenv('TMP') }
|
||||
if path == '' { path = 'C:/tmp' }
|
||||
}
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
|
|
@ -152,6 +152,24 @@ fn test_cp_r() {
|
|||
os.cp_r('ex', './', true) or { panic(err) }
|
||||
}
|
||||
|
||||
fn test_tmpdir(){
|
||||
t := os.tmpdir()
|
||||
assert t.len > 0
|
||||
assert os.is_dir(t)
|
||||
|
||||
tfile := t + os.path_separator + 'tmpfile.txt'
|
||||
|
||||
os.rm(tfile) // just in case
|
||||
|
||||
tfile_content := 'this is a temporary file'
|
||||
os.write_file(tfile, tfile_content)
|
||||
|
||||
tfile_content_read := os.read_file(tfile) or { panic(err) }
|
||||
assert tfile_content_read == tfile_content
|
||||
|
||||
os.rm(tfile)
|
||||
}
|
||||
|
||||
//fn test_fork() {
|
||||
// pid := os.fork()
|
||||
// if pid == 0 {
|
||||
|
@ -179,7 +197,6 @@ fn test_zzz_cleanup(){
|
|||
cleanup_leftovers() assert true
|
||||
}
|
||||
|
||||
|
||||
// this function is called by both test_aaa_setup & test_zzz_cleanup
|
||||
// it ensures that os tests do not polute the filesystem with leftover
|
||||
// files so that they can be run several times in a row.
|
||||
|
|
Loading…
Reference in New Issue