initial Implementation of ls() for windows

pull/1049/head
joe-conigliaro 2019-07-04 10:16:39 +10:00 committed by Alexander Medvednikov
parent 155e1fa961
commit 4d9c6197fd
1 changed files with 83 additions and 24 deletions

View File

@ -549,6 +549,7 @@ pub fn getexepath() string {
pub fn is_dir(path string) bool {
$if windows {
val := int(C.GetFileAttributes(path.cstr()))
// Note: this return is broke (wrong). we have dir_exists already how will this differ?
return val &FILE_ATTRIBUTE_DIRECTORY > 0
}
$else {
@ -585,33 +586,91 @@ pub fn getwd() string {
return string(buf)
}
// windows
const(
INVALID_HANDLE_VALUE = -1
)
// win: FILETIME
// https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
struct filetime {
dwLowDateTime u32
dwHighDateTime u32
}
// win: WIN32_FIND_DATA
// https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-_win32_find_dataa
struct win32finddata {
mut:
dwFileAttributes u32
ftCreationTime filetime
ftLastAccessTime filetime
ftLastWriteTime filetime
nFileSizeHigh u32
nFileSizeLow u32
dwReserved0 u32
dwReserved1 u32
cFileName [260]u16 // MAX_PATH = 260
cAlternateFileName [14]u16 // 14
dwFileType u32
dwCreatorType u32
wFinderFlags u16
}
pub fn ls(path string) []string {
$if windows {
return []string
}
$else {
mut res := []string
dir := C.opendir(path.str)
if isnil(dir) {
println('ls() couldnt open dir "$path"')
print_c_errno()
mut find_file_data := win32finddata{}
mut dir_files := []string
if !dir_exists(path) {
println('ls() couldnt open dir "$path" (does not exist).')
}
// 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.cstr(), &find_file_data)
// If we want to check the handle we can use this, but we already did dir_exists
// if (INVALID_HANDLE_VALUE == h_find_files) {
// println('ls() couldnt open dir "$path"')
// return dir_files
// }
first_filename := tos(&find_file_data.cFileName, strlen(find_file_data.cFileName))
if first_filename != '.' && first_filename != '..' {
dir_files << first_filename
}
for C.FindNextFile(h_find_files, &find_file_data) {
filename := tos(&find_file_data.cFileName, strlen(find_file_data.cFileName))
if filename != '.' && filename != '..' {
dir_files << filename.clone()
}
}
C.FindClose(h_find_files)
return dir_files
}
$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 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
}
}
}
pub fn signal(signum int, handler voidptr) {