os: fix is_abs_path function for Windows systems (#14397)
parent
689f3f7128
commit
6a87650935
|
@ -0,0 +1,86 @@
|
||||||
|
module os
|
||||||
|
|
||||||
|
// Collection of useful functions for manipulation, validation and analysis of system paths.
|
||||||
|
// The following functions handle paths depending on the operating system,
|
||||||
|
// therefore results may be different for certain operating systems.
|
||||||
|
|
||||||
|
const (
|
||||||
|
fslash = `/`
|
||||||
|
bslash = `\\`
|
||||||
|
dot = `.`
|
||||||
|
)
|
||||||
|
|
||||||
|
// is_abs_path returns `true` if the given `path` is absolute.
|
||||||
|
pub fn is_abs_path(path string) bool {
|
||||||
|
if path.len == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
$if windows {
|
||||||
|
return is_device_path(path) || is_drive_rooted(path) || is_normal_path(path)
|
||||||
|
}
|
||||||
|
return path[0] == os.fslash
|
||||||
|
}
|
||||||
|
|
||||||
|
// win_volume_len returns the length of the
|
||||||
|
// Windows volume/drive from the given `path`.
|
||||||
|
fn win_volume_len(path string) int {
|
||||||
|
plen := path.len
|
||||||
|
if plen < 2 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if has_drive_letter(path) {
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
// its UNC path / DOS device path?
|
||||||
|
if path.len >= 5 && starts_w_slash_slash(path) && !is_slash(path[2]) {
|
||||||
|
for i := 3; i < plen; i++ {
|
||||||
|
if is_slash(path[i]) {
|
||||||
|
if i + 1 >= plen || is_slash(path[i + 1]) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
for ; i < plen; i++ {
|
||||||
|
if is_slash(path[i]) {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_slash(b u8) bool {
|
||||||
|
$if windows {
|
||||||
|
return b == os.bslash || b == os.fslash
|
||||||
|
}
|
||||||
|
return b == os.fslash
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_device_path(path string) bool {
|
||||||
|
return win_volume_len(path) >= 5 && starts_w_slash_slash(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_drive_letter(path string) bool {
|
||||||
|
return path.len >= 2 && path[0].is_letter() && path[1] == `:`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn starts_w_slash_slash(path string) bool {
|
||||||
|
return path.len >= 2 && is_slash(path[0]) && is_slash(path[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_drive_rooted(path string) bool {
|
||||||
|
return path.len >= 3 && has_drive_letter(path) && is_slash(path[2])
|
||||||
|
}
|
||||||
|
|
||||||
|
// is_normal_path returns `true` if the given
|
||||||
|
// `path` is NOT a network or Windows device path.
|
||||||
|
fn is_normal_path(path string) bool {
|
||||||
|
plen := path.len
|
||||||
|
if plen == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return (plen == 1 && is_slash(path[0])) || (plen >= 2 && is_slash(path[0])
|
||||||
|
&& !is_slash(path[1]))
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
module os
|
||||||
|
|
||||||
|
fn test_is_abs_path() {
|
||||||
|
$if windows {
|
||||||
|
assert is_abs_path('/')
|
||||||
|
assert is_abs_path('\\')
|
||||||
|
assert !is_abs_path('\\\\')
|
||||||
|
assert is_abs_path(r'C:\path\to\files\file.v')
|
||||||
|
assert is_abs_path(r'\\Host\share')
|
||||||
|
assert is_abs_path(r'//Host\share\files\file.v')
|
||||||
|
assert is_abs_path(r'\\.\BootPartition\Windows')
|
||||||
|
assert !is_abs_path(r'\\.\')
|
||||||
|
assert !is_abs_path(r'\\?\\')
|
||||||
|
assert !is_abs_path(r'C:path\to\dir')
|
||||||
|
assert !is_abs_path(r'dir')
|
||||||
|
assert !is_abs_path(r'.\')
|
||||||
|
assert !is_abs_path(r'.')
|
||||||
|
assert !is_abs_path(r'\\Host')
|
||||||
|
assert !is_abs_path(r'\\Host\')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert is_abs_path('/')
|
||||||
|
assert is_abs_path('/path/to/files/file.v')
|
||||||
|
assert !is_abs_path('\\')
|
||||||
|
assert !is_abs_path('path/to/files/file.v')
|
||||||
|
assert !is_abs_path('dir')
|
||||||
|
assert !is_abs_path('./')
|
||||||
|
assert !is_abs_path('.')
|
||||||
|
}
|
12
vlib/os/os.v
12
vlib/os/os.v
|
@ -454,18 +454,6 @@ pub fn is_file(path string) bool {
|
||||||
return exists(path) && !is_dir(path)
|
return exists(path) && !is_dir(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// is_abs_path returns `true` if `path` is absolute.
|
|
||||||
pub fn is_abs_path(path string) bool {
|
|
||||||
if path.len == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
$if windows {
|
|
||||||
return path[0] == `/` || // incase we're in MingGW bash
|
|
||||||
(path[0].is_letter() && path.len > 1 && path[1] == `:`)
|
|
||||||
}
|
|
||||||
return path[0] == `/`
|
|
||||||
}
|
|
||||||
|
|
||||||
// join_path returns a path as string from input string parameter(s).
|
// join_path returns a path as string from input string parameter(s).
|
||||||
[manualfree]
|
[manualfree]
|
||||||
pub fn join_path(base string, dirs ...string) string {
|
pub fn join_path(base string, dirs ...string) string {
|
||||||
|
|
|
@ -590,14 +590,6 @@ fn test_ext() {
|
||||||
assert os.file_ext('file') == ''
|
assert os.file_ext('file') == ''
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_is_abs() {
|
|
||||||
assert os.is_abs_path('/home/user')
|
|
||||||
assert os.is_abs_path('v/vlib') == false
|
|
||||||
$if windows {
|
|
||||||
assert os.is_abs_path('C:\\Windows\\')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_join() {
|
fn test_join() {
|
||||||
$if windows {
|
$if windows {
|
||||||
assert os.join_path('v', 'vlib', 'os') == 'v\\vlib\\os'
|
assert os.join_path('v', 'vlib', 'os') == 'v\\vlib\\os'
|
||||||
|
|
Loading…
Reference in New Issue