From b188ecf6809b0dfadb7f507b70ed404ff4030356 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Fri, 16 Aug 2019 15:05:11 +0300 Subject: [PATCH] Makefile: re-write `make test` in V --- .travis.yml | 2 +- Makefile | 8 ----- compiler/main.v | 22 +++++++++++- vlib/builtin/string.v | 4 +-- vlib/os/os.v | 78 +++++++++++-------------------------------- vlib/os/os_nix.v | 30 +++++++++++++++++ vlib/os/os_win.v | 33 ++++++++++++++++++ 7 files changed, 106 insertions(+), 71 deletions(-) diff --git a/.travis.yml b/.travis.yml index b4f890906d..eb5b660c4e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -48,7 +48,7 @@ script: if [[ "${TRAVIS_OS_NAME}" != "windows" ]]; then make ./v install glfw - make test + ./v test v fi - | if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then diff --git a/Makefile b/Makefile index e77af9b2a7..87a767d6d3 100644 --- a/Makefile +++ b/Makefile @@ -9,13 +9,5 @@ all: rm v.c @echo "V has been successfully built" -test: v - ./v -prod -o vprod compiler # Test prod build - echo "Running V tests..." - find . -name '*_test.v' -print0 | xargs -0 -n1 ./v - echo "Building V examples..." - find examples -name '*.v' -print0 | xargs -0 -n1 ./v - bash ./compiler/tests/repl/repl.sh - symlink: v ln -sf `pwd`/v ${PREFIX}/bin/v diff --git a/compiler/main.v b/compiler/main.v index 2e070936e9..5344de578f 100644 --- a/compiler/main.v +++ b/compiler/main.v @@ -1434,6 +1434,26 @@ fn update_v() { } fn test_v() { - + test_files := os.walk_ext('.', '_test.v') + for file in test_files { + print(file + ' ') + if os.system('v $file') != 0 { + println('failed') + exit(1) + } else { + println('OK') + } + } + println('\nBuilding examples...') + examples := os.walk_ext('examples', '.v') + for file in examples { + print(file + ' ') + if os.system('v $file') != 0 { + println('failed') + exit(1) + } else { + println('OK') + } + } } diff --git a/vlib/builtin/string.v b/vlib/builtin/string.v index aa99651706..538dd3bdcb 100644 --- a/vlib/builtin/string.v +++ b/vlib/builtin/string.v @@ -41,9 +41,7 @@ pub fn tos_clone(s byteptr) string { if isnil(s) { panic('tos: nil string') } - len := strlen(s) - res := tos(s, len) - return res.clone() + return tos2(s).clone() } // Same as `tos`, but calculates the length. Called by `string(bytes)` casts. diff --git a/vlib/os/os.v b/vlib/os/os.v index ebfcc499fc..ff3b409ca7 100644 --- a/vlib/os/os.v +++ b/vlib/os/os.v @@ -20,10 +20,6 @@ struct dirent { } */ -struct C.dirent { - d_name byteptr -} - const ( args = []string MAX_PATH = 4096 @@ -804,62 +800,28 @@ mut: wFinderFlags u16 } -pub fn ls(path string) []string { - $if windows { - mut find_file_data := win32finddata{} - mut dir_files := []string - // We can also check if the handle is valid. but using dir_exists instead - // h_find_dir := C.FindFirstFile(path.str, &find_file_data) - // if (INVALID_HANDLE_VALUE == h_find_dir) { - // return dir_files - // } - // C.FindClose(h_find_dir) - if !dir_exists(path) { - println('ls() couldnt open dir "$path" (does not exist).') - return dir_files - } - // NOTE: Should eventually have path struct & os dependant path seperator (eg os.PATH_SEPERATOR) - // we need to add files to path eg. c:\windows\*.dll or :\windows\* - path_files := '$path\\*' - // NOTE:TODO: once we have a way to convert utf16 wide character to utf8 - // we should use FindFirstFileW and FindNextFileW - h_find_files := C.FindFirstFile(path_files.to_wide(), &find_file_data) - first_filename := string_from_wide(&u16(find_file_data.cFileName)) - if first_filename != '.' && first_filename != '..' { - dir_files << first_filename - } - for C.FindNextFile(h_find_files, &find_file_data) { - filename := string_from_wide(&u16(find_file_data.cFileName)) - if filename != '.' && filename != '..' { - dir_files << filename.clone() - } - } - C.FindClose(h_find_files) - return dir_files + +// walk_ext returns a recursive list of all file paths ending with `ext`. +pub fn walk_ext(path, ext string) []string { + if !os.is_dir(path) { + return []string } - $else { - mut res := []string - dir := C.opendir(path.str) - if isnil(dir) { - println('ls() couldnt open dir "$path"') - print_c_errno() - return res - } - mut ent := &C.dirent{!} - for { - ent = C.readdir(dir) - if isnil(ent) { - break - } - name := tos_clone(ent.d_name) - if name != '.' && name != '..' && name != '' { - res << name - } - } - C.closedir(dir) - return res + mut files := os.ls(path) + mut res := []string + for i, file in files { + if file.starts_with('.') { + continue + } + p := path + '/' + file + if os.is_dir(p) { + res << walk_ext(p, ext) + } + else if file.ends_with(ext) { + res << p + } } -} + return res +} pub fn signal(signum int, handler voidptr) { C.signal(signum, handler) diff --git a/vlib/os/os_nix.v b/vlib/os/os_nix.v index f20415fc80..52f1cf5853 100644 --- a/vlib/os/os_nix.v +++ b/vlib/os/os_nix.v @@ -7,6 +7,13 @@ const ( PathSeparator = '/' ) +struct C.dirent { + d_name byteptr +} + +fn C.readdir(voidptr) C.dirent + + // get_error_msg return error code representation in string. pub fn get_error_msg(code int) string { _ptr_text := C.strerror(code) // voidptr? @@ -15,3 +22,26 @@ pub fn get_error_msg(code int) string { } return tos(_ptr_text, C.strlen(_ptr_text)) } + +pub fn ls(path string) []string { + mut res := []string + dir := C.opendir(path.str) + if isnil(dir) { + println('ls() couldnt open dir "$path"') + print_c_errno() + return res + } + mut ent := &C.dirent{!} + for { + ent = C.readdir(dir) + if isnil(ent) { + break + } + name := tos_clone(ent.d_name) + if name != '.' && name != '..' && name != '' { + res << name + } + } + C.closedir(dir) + return res +} diff --git a/vlib/os/os_win.v b/vlib/os/os_win.v index cfb21b3bda..6a8c03f5d3 100644 --- a/vlib/os/os_win.v +++ b/vlib/os/os_win.v @@ -11,6 +11,39 @@ const ( // A handle to an object. type HANDLE voidptr +pub fn ls(path string) []string { + mut find_file_data := win32finddata{} + mut dir_files := []string + // We can also check if the handle is valid. but using dir_exists instead + // h_find_dir := C.FindFirstFile(path.str, &find_file_data) + // if (INVALID_HANDLE_VALUE == h_find_dir) { + // return dir_files + // } + // C.FindClose(h_find_dir) + if !dir_exists(path) { + println('ls() couldnt open dir "$path" (does not exist).') + return dir_files + } + // NOTE: Should eventually have path struct & os dependant path seperator (eg os.PATH_SEPERATOR) + // we need to add files to path eg. c:\windows\*.dll or :\windows\* + path_files := '$path\\*' + // NOTE:TODO: once we have a way to convert utf16 wide character to utf8 + // we should use FindFirstFileW and FindNextFileW + h_find_files := C.FindFirstFile(path_files.to_wide(), &find_file_data) + first_filename := string_from_wide(&u16(find_file_data.cFileName)) + if first_filename != '.' && first_filename != '..' { + dir_files << first_filename + } + for C.FindNextFile(h_find_files, &find_file_data) { + filename := string_from_wide(&u16(find_file_data.cFileName)) + if filename != '.' && filename != '..' { + dir_files << filename.clone() + } + } + C.FindClose(h_find_files) + return dir_files +} + // Ref - https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/get-osfhandle?view=vs-2019 // get_file_handle retrieves the operating-system file handle that is associated with the specified file descriptor. pub fn get_file_handle(path string) HANDLE {