mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
run vfmt
This commit is contained in:
@@ -1,10 +1,6 @@
|
||||
module os
|
||||
// (Must be realized in Syscall) (Must be specified)
|
||||
// File modes.
|
||||
|
||||
|
||||
|
||||
|
||||
const (
|
||||
O_RDONLY = 1 // open the file read-only.
|
||||
O_WRONLY = 2 // open the file write-only.
|
||||
|
465
vlib/os/os.v
465
vlib/os/os.v
@@ -1,15 +1,12 @@
|
||||
// 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 os
|
||||
|
||||
import filepath
|
||||
|
||||
#include <sys/stat.h>
|
||||
//#include <signal.h>
|
||||
#include <sys/stat.h> // #include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
/*
|
||||
struct dirent {
|
||||
d_ino int
|
||||
@@ -26,13 +23,14 @@ struct C.dirent {
|
||||
|
||||
fn C.readdir(voidptr) C.dirent
|
||||
|
||||
|
||||
pub const (
|
||||
args = []string
|
||||
MAX_PATH = 4096
|
||||
)
|
||||
|
||||
pub struct File {
|
||||
cfile voidptr // Using void* instead of FILE*
|
||||
cfile voidptr // Using void* instead of FILE*
|
||||
mut:
|
||||
opened bool
|
||||
}
|
||||
@@ -43,30 +41,33 @@ struct FileInfo {
|
||||
}
|
||||
|
||||
struct C.stat {
|
||||
st_size int
|
||||
st_mode u32
|
||||
st_size int
|
||||
st_mode u32
|
||||
st_mtime int
|
||||
}
|
||||
|
||||
struct C.DIR {
|
||||
|
||||
}
|
||||
|
||||
//struct C.dirent {
|
||||
//d_name byteptr
|
||||
|
||||
//}
|
||||
|
||||
// struct C.dirent {
|
||||
// d_name byteptr
|
||||
// }
|
||||
struct C.sigaction {
|
||||
mut:
|
||||
sa_mask int
|
||||
sa_mask int
|
||||
sa_sigaction int
|
||||
sa_flags int
|
||||
sa_flags int
|
||||
}
|
||||
|
||||
fn C.getline(voidptr, voidptr, voidptr) int
|
||||
|
||||
|
||||
fn C.ftell(fp voidptr) int
|
||||
|
||||
|
||||
fn C.getenv(byteptr) &char
|
||||
|
||||
|
||||
fn C.sigaction(int, voidptr, int)
|
||||
|
||||
|
||||
@@ -81,7 +82,7 @@ pub fn (f mut File) read_bytes(size int) []byte {
|
||||
|
||||
// read_bytes_at reads an amount of bytes at the given position in the file
|
||||
pub fn (f mut File) read_bytes_at(size, pos int) []byte {
|
||||
mut arr := [`0`].repeat(size)
|
||||
mut arr := [`0`].repeat(size)
|
||||
C.fseek(f.cfile, pos, C.SEEK_SET)
|
||||
nreadbytes := C.fread(arr.data, 1, size, f.cfile)
|
||||
C.fseek(f.cfile, 0, C.SEEK_SET)
|
||||
@@ -96,8 +97,7 @@ pub fn read_bytes(path string) ?[]byte {
|
||||
C.fseek(fp, 0, C.SEEK_END)
|
||||
fsize := C.ftell(fp)
|
||||
C.rewind(fp)
|
||||
|
||||
mut res := [`0`].repeat(fsize)
|
||||
mut res := [`0`].repeat(fsize)
|
||||
nr_read_elements := C.fread(res.data, fsize, 1, fp)
|
||||
C.fclose(fp)
|
||||
return res[0..nr_read_elements * fsize]
|
||||
@@ -118,12 +118,13 @@ pub fn read_file(path string) ?string {
|
||||
C.fread(str, fsize, 1, fp)
|
||||
C.fclose(fp)
|
||||
str[fsize] = 0
|
||||
return string(str, fsize)
|
||||
return string(str,fsize)
|
||||
}
|
||||
|
||||
// file_size returns the size of the file located in `path`.
|
||||
pub fn file_size(path string) int {
|
||||
mut s := C.stat{}
|
||||
mut s := C.stat{
|
||||
}
|
||||
$if windows {
|
||||
C._wstat(path.to_wide(), voidptr(&s))
|
||||
} $else {
|
||||
@@ -141,18 +142,17 @@ pub fn mv(old, new string) {
|
||||
}
|
||||
|
||||
fn C.CopyFile(&u32, &u32, int) int
|
||||
|
||||
// TODO implement actual cp for linux
|
||||
pub fn cp(old, new string) ?bool {
|
||||
$if windows {
|
||||
_old := old.replace('/', '\\')
|
||||
_new := new.replace('/', '\\')
|
||||
C.CopyFile(_old.to_wide(), _new.to_wide(), false)
|
||||
|
||||
result := C.GetLastError()
|
||||
if result == 0 {
|
||||
return true
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return error_with_code('failed to copy $old to $new', int(result))
|
||||
}
|
||||
} $else {
|
||||
@@ -161,19 +161,15 @@ pub fn cp(old, new string) ?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 )
|
||||
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.exists(source_path) {
|
||||
return error('Source path doesn\'t exist')
|
||||
return error("Source path doesn\'t exist")
|
||||
}
|
||||
//single file copy
|
||||
// single file copy
|
||||
if !os.is_dir(source_path) {
|
||||
adjasted_path := if os.is_dir(dest_path) {
|
||||
filepath.join(dest_path, os.filename(source_path))
|
||||
} else {
|
||||
dest_path
|
||||
}
|
||||
adjasted_path := if os.is_dir(dest_path) { filepath.join(dest_path,os.filename(source_path)) } else { dest_path }
|
||||
if os.exists(adjasted_path) {
|
||||
if overwrite {
|
||||
os.rm(adjasted_path)
|
||||
@@ -182,20 +178,26 @@ pub fn cp_r(osource_path, odest_path string, overwrite bool) ?bool{
|
||||
return error('Destination file path already exist')
|
||||
}
|
||||
}
|
||||
os.cp(source_path, adjasted_path) or { return error(err) }
|
||||
os.cp(source_path, adjasted_path)or{
|
||||
return error(err)
|
||||
}
|
||||
return true
|
||||
}
|
||||
if !os.is_dir(dest_path) {
|
||||
return error('Destination path is not a valid directory')
|
||||
}
|
||||
files := os.ls(source_path) or { return error(err) }
|
||||
files := os.ls(source_path)or{
|
||||
return error(err)
|
||||
}
|
||||
for file in files {
|
||||
sp := filepath.join(source_path, file)
|
||||
dp := filepath.join(dest_path, file)
|
||||
sp := filepath.join(source_path,file)
|
||||
dp := filepath.join(dest_path,file)
|
||||
if os.is_dir(sp) {
|
||||
os.mkdir(dp) or { panic(err) }
|
||||
os.mkdir(dp)or{
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
cp_r(sp, dp, overwrite) or {
|
||||
cp_r(sp, dp, overwrite)or{
|
||||
os.rmdir(dp)
|
||||
panic(err)
|
||||
}
|
||||
@@ -206,7 +208,9 @@ pub fn cp_r(osource_path, odest_path string, overwrite bool) ?bool{
|
||||
// mv_by_cp first copies the source file, and if it is copied successfully, deletes the source file.
|
||||
// mv_by_cp may be used when you are not sure that the source and target are on the same mount/partition.
|
||||
pub fn mv_by_cp(source string, target string) ?bool {
|
||||
os.cp(source, target) or { return error(err) }
|
||||
os.cp(source, target)or{
|
||||
return error(err)
|
||||
}
|
||||
os.rm(source)
|
||||
return true
|
||||
}
|
||||
@@ -224,13 +228,11 @@ pub fn read_lines(path string) ?[]string {
|
||||
mut res := []string
|
||||
mut buf_len := 1024
|
||||
mut buf := malloc(buf_len)
|
||||
|
||||
mode := 'rb'
|
||||
mut fp := vfopen(path, mode)
|
||||
if isnil(fp) {
|
||||
return error('read_lines() failed to open file "$path"')
|
||||
}
|
||||
|
||||
mut buf_index := 0
|
||||
for C.fgets(buf + buf_index, buf_len - buf_index, fp) != 0 {
|
||||
len := vstrlen(buf)
|
||||
@@ -257,7 +259,7 @@ pub fn read_lines(path string) ?[]string {
|
||||
}
|
||||
|
||||
fn read_ulines(path string) ?[]ustring {
|
||||
lines := read_lines(path) or {
|
||||
lines := read_lines(path)or{
|
||||
return err
|
||||
}
|
||||
// mut ulines := new_array(0, lines.len, sizeof(ustring))
|
||||
@@ -270,16 +272,17 @@ fn read_ulines(path string) ?[]ustring {
|
||||
}
|
||||
|
||||
pub fn open(path string) ?File {
|
||||
mut file := File{}
|
||||
mut file := File{
|
||||
}
|
||||
$if windows {
|
||||
wpath := path.to_wide()
|
||||
mode := 'rb'
|
||||
file = File {
|
||||
file = File{
|
||||
cfile: C._wfopen(wpath, mode.to_wide())
|
||||
}
|
||||
} $else {
|
||||
cpath := path.str
|
||||
file = File {
|
||||
file = File{
|
||||
cfile: C.fopen(charptr(cpath), 'rb')
|
||||
}
|
||||
}
|
||||
@@ -292,16 +295,17 @@ pub fn open(path string) ?File {
|
||||
|
||||
// create creates a file at a specified location and returns a writable `File` object.
|
||||
pub fn create(path string) ?File {
|
||||
mut file := File{}
|
||||
mut file := File{
|
||||
}
|
||||
$if windows {
|
||||
wpath := path.replace('/', '\\').to_wide()
|
||||
mode := 'wb'
|
||||
file = File {
|
||||
file = File{
|
||||
cfile: C._wfopen(wpath, mode.to_wide())
|
||||
}
|
||||
} $else {
|
||||
cpath := path.str
|
||||
file = File {
|
||||
file = File{
|
||||
cfile: C.fopen(charptr(cpath), 'wb')
|
||||
}
|
||||
}
|
||||
@@ -313,16 +317,17 @@ pub fn create(path string) ?File {
|
||||
}
|
||||
|
||||
pub fn open_append(path string) ?File {
|
||||
mut file := File{}
|
||||
mut file := File{
|
||||
}
|
||||
$if windows {
|
||||
wpath := path.replace('/', '\\').to_wide()
|
||||
mode := 'ab'
|
||||
file = File {
|
||||
file = File{
|
||||
cfile: C._wfopen(wpath, mode.to_wide())
|
||||
}
|
||||
} $else {
|
||||
cpath := path.str
|
||||
file = File {
|
||||
file = File{
|
||||
cfile: C.fopen(charptr(cpath), 'ab')
|
||||
}
|
||||
}
|
||||
@@ -337,7 +342,6 @@ pub fn (f mut File) write(s string) {
|
||||
C.fputs(s.str, f.cfile)
|
||||
// C.fwrite(s.str, 1, s.len, f.cfile)
|
||||
}
|
||||
|
||||
// convert any value to []byte (LittleEndian) and write it
|
||||
// for example if we have write(7, 4), "07 00 00 00" gets written
|
||||
// write(0x1234, 2) => "34 12"
|
||||
@@ -352,7 +356,9 @@ pub fn (f mut File) write_bytes_at(data voidptr, size, pos int) {
|
||||
}
|
||||
|
||||
pub fn (f mut File) writeln(s string) {
|
||||
if !f.opened { return }
|
||||
if !f.opened {
|
||||
return
|
||||
}
|
||||
// C.fwrite(s.str, 1, s.len, f.cfile)
|
||||
// ss := s.clone()
|
||||
// TODO perf
|
||||
@@ -362,25 +368,29 @@ pub fn (f mut File) writeln(s string) {
|
||||
}
|
||||
|
||||
pub fn (f mut File) flush() {
|
||||
if !f.opened { return }
|
||||
if !f.opened {
|
||||
return
|
||||
}
|
||||
C.fflush(f.cfile)
|
||||
}
|
||||
|
||||
pub fn (f mut File) close() {
|
||||
if !f.opened { return }
|
||||
if !f.opened {
|
||||
return
|
||||
}
|
||||
f.opened = false
|
||||
C.fflush(f.cfile)
|
||||
C.fclose(f.cfile)
|
||||
}
|
||||
|
||||
// system starts the specified command, waits for it to complete, and returns its code.
|
||||
fn vpopen(path string) voidptr {//*C.FILE {
|
||||
fn vpopen(path string) voidptr {
|
||||
// *C.FILE {
|
||||
$if windows {
|
||||
mode := 'rb'
|
||||
wpath := path.to_wide()
|
||||
return C._wpopen(wpath, mode.to_wide())
|
||||
}
|
||||
$else {
|
||||
} $else {
|
||||
cpath := path.str
|
||||
return C.popen(cpath, 'r')
|
||||
}
|
||||
@@ -388,29 +398,28 @@ fn vpopen(path string) voidptr {//*C.FILE {
|
||||
|
||||
fn posix_wait4_to_exit_status(waitret int) (int,bool) {
|
||||
$if windows {
|
||||
return waitret, false
|
||||
}
|
||||
$else {
|
||||
return waitret,false
|
||||
} $else {
|
||||
mut ret := 0
|
||||
mut is_signaled := true
|
||||
// (see man system, man 2 waitpid: C macro WEXITSTATUS section)
|
||||
if C.WIFEXITED( waitret ) {
|
||||
ret = C.WEXITSTATUS( waitret )
|
||||
if C.WIFEXITED(waitret) {
|
||||
ret = C.WEXITSTATUS(waitret)
|
||||
is_signaled = false
|
||||
} else if C.WIFSIGNALED( waitret ){
|
||||
ret = C.WTERMSIG( waitret )
|
||||
}
|
||||
else if C.WIFSIGNALED(waitret) {
|
||||
ret = C.WTERMSIG(waitret)
|
||||
is_signaled = true
|
||||
}
|
||||
return ret , is_signaled
|
||||
return ret,is_signaled
|
||||
}
|
||||
}
|
||||
|
||||
fn vpclose(f voidptr) int {
|
||||
$if windows {
|
||||
return C._pclose(f)
|
||||
}
|
||||
$else {
|
||||
ret , _ := posix_wait4_to_exit_status(C.pclose(f))
|
||||
} $else {
|
||||
ret,_ := posix_wait4_to_exit_status(C.pclose(f))
|
||||
return ret
|
||||
}
|
||||
}
|
||||
@@ -418,16 +427,15 @@ fn vpclose(f voidptr) int {
|
||||
pub struct Result {
|
||||
pub:
|
||||
exit_code int
|
||||
output string
|
||||
//stderr string // TODO
|
||||
output string
|
||||
// stderr string // TODO
|
||||
}
|
||||
|
||||
// `system` works like `exec()`, but only returns a return code.
|
||||
pub fn system(cmd string) int {
|
||||
//if cmd.contains(';') || cmd.contains('&&') || cmd.contains('||') || cmd.contains('\n') {
|
||||
// TODO remove panic
|
||||
//panic(';, &&, || and \\n are not allowed in shell commands')
|
||||
//}
|
||||
// if cmd.contains(';') || cmd.contains('&&') || cmd.contains('||') || cmd.contains('\n') {
|
||||
// TODO remove panic
|
||||
// panic(';, &&, || and \\n are not allowed in shell commands')
|
||||
// }
|
||||
mut ret := 0
|
||||
$if windows {
|
||||
// overcome bug in system & _wsystem (cmd) when first char is quote `"`
|
||||
@@ -439,11 +447,10 @@ pub fn system(cmd string) int {
|
||||
if ret == -1 {
|
||||
print_c_errno()
|
||||
}
|
||||
|
||||
$if !windows {
|
||||
pret , is_signaled := posix_wait4_to_exit_status( ret )
|
||||
pret,is_signaled := posix_wait4_to_exit_status(ret)
|
||||
if is_signaled {
|
||||
println('Terminated by signal ${ret:2d} (' + sigint_to_signal_name(pret) + ')' )
|
||||
println('Terminated by signal ${ret:2d} (' + sigint_to_signal_name(pret) + ')')
|
||||
}
|
||||
ret = pret
|
||||
}
|
||||
@@ -453,35 +460,77 @@ pub fn system(cmd string) int {
|
||||
pub fn sigint_to_signal_name(si int) string {
|
||||
// POSIX signals:
|
||||
match si {
|
||||
1 {return 'SIGHUP'}
|
||||
2 {return 'SIGINT'}
|
||||
3 {return 'SIGQUIT'}
|
||||
4 {return 'SIGILL'}
|
||||
6 {return 'SIGABRT'}
|
||||
8 {return 'SIGFPE'}
|
||||
9 {return 'SIGKILL'}
|
||||
11 {return 'SIGSEGV'}
|
||||
13 {return 'SIGPIPE'}
|
||||
14 {return 'SIGALRM'}
|
||||
15 {return 'SIGTERM'}
|
||||
else { }
|
||||
}
|
||||
1 {
|
||||
return 'SIGHUP'
|
||||
}
|
||||
2 {
|
||||
return 'SIGINT'
|
||||
}
|
||||
3 {
|
||||
return 'SIGQUIT'
|
||||
}
|
||||
4 {
|
||||
return 'SIGILL'
|
||||
}
|
||||
6 {
|
||||
return 'SIGABRT'
|
||||
}
|
||||
8 {
|
||||
return 'SIGFPE'
|
||||
}
|
||||
9 {
|
||||
return 'SIGKILL'
|
||||
}
|
||||
11 {
|
||||
return 'SIGSEGV'
|
||||
}
|
||||
13 {
|
||||
return 'SIGPIPE'
|
||||
}
|
||||
14 {
|
||||
return 'SIGALRM'
|
||||
}
|
||||
15 {
|
||||
return 'SIGTERM'
|
||||
}
|
||||
else {
|
||||
}}
|
||||
$if linux {
|
||||
// From `man 7 signal` on linux:
|
||||
match si {
|
||||
30,10,16{ return 'SIGUSR1'}
|
||||
31,12,17{ return 'SIGUSR2'}
|
||||
20,17,18{ return 'SIGCHLD'}
|
||||
19,18,25{ return 'SIGCONT'}
|
||||
17,19,23{ return 'SIGSTOP'}
|
||||
18,20,24{ return 'SIGTSTP'}
|
||||
21,21,26{ return 'SIGTTIN'}
|
||||
22,22,27{ return 'SIGTTOU'}
|
||||
///////////////////////////////
|
||||
5{ return 'SIGTRAP'}
|
||||
7{ return 'SIGBUS' }
|
||||
else {}
|
||||
}
|
||||
30, 10, 16 {
|
||||
return 'SIGUSR1'
|
||||
}
|
||||
31, 12, 17 {
|
||||
return 'SIGUSR2'
|
||||
}
|
||||
20, 17, 18 {
|
||||
return 'SIGCHLD'
|
||||
}
|
||||
19, 18, 25 {
|
||||
return 'SIGCONT'
|
||||
}
|
||||
17, 19, 23 {
|
||||
return 'SIGSTOP'
|
||||
}
|
||||
18, 20, 24 {
|
||||
return 'SIGTSTP'
|
||||
}
|
||||
21, 21, 26 {
|
||||
return 'SIGTTIN'
|
||||
}
|
||||
22, 22, 27 {
|
||||
return 'SIGTTOU'
|
||||
}
|
||||
// /////////////////////////////
|
||||
5 {
|
||||
return 'SIGTRAP'
|
||||
}
|
||||
7 {
|
||||
return 'SIGBUS'
|
||||
}
|
||||
else {
|
||||
}}
|
||||
}
|
||||
return 'unknown'
|
||||
}
|
||||
@@ -500,7 +549,7 @@ pub fn getenv(key string) string {
|
||||
return ''
|
||||
}
|
||||
// NB: C.getenv *requires* that the result be copied.
|
||||
return cstring_to_vstring( byteptr(s) )
|
||||
return cstring_to_vstring(byteptr(s))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -531,7 +580,7 @@ pub fn exists(path string) bool {
|
||||
p := path.replace('/', '\\')
|
||||
return C._waccess(p.to_wide(), 0) != -1
|
||||
} $else {
|
||||
return C.access(path.str, 0 ) != -1
|
||||
return C.access(path.str, 0) != -1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -544,30 +593,24 @@ pub fn file_exists(_path string) bool {
|
||||
pub fn rm(path string) {
|
||||
$if windows {
|
||||
C._wremove(path.to_wide())
|
||||
}
|
||||
$else {
|
||||
} $else {
|
||||
C.remove(path.str)
|
||||
}
|
||||
// C.unlink(path.cstr())
|
||||
}
|
||||
|
||||
|
||||
// rmdir removes a specified directory.
|
||||
pub fn rmdir(path string) {
|
||||
$if !windows {
|
||||
C.rmdir(path.str)
|
||||
}
|
||||
$else {
|
||||
} $else {
|
||||
C.RemoveDirectory(path.to_wide())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn print_c_errno() {
|
||||
//C.printf('errno=%d err="%s"\n', C.errno, C.strerror(C.errno))
|
||||
// C.printf('errno=%d err="%s"\n', C.errno, C.strerror(C.errno))
|
||||
}
|
||||
|
||||
|
||||
pub fn ext(path string) string {
|
||||
pos := path.last_index('.') or {
|
||||
return ''
|
||||
@@ -575,7 +618,6 @@ pub fn ext(path string) string {
|
||||
return path[pos..]
|
||||
}
|
||||
|
||||
|
||||
// dir returns all but the last element of path, typically the path's directory.
|
||||
pub fn dir(path string) string {
|
||||
if path == '.' {
|
||||
@@ -594,12 +636,11 @@ fn path_sans_ext(path string) string {
|
||||
return path[..pos]
|
||||
}
|
||||
|
||||
|
||||
pub fn basedir(path string) string {
|
||||
pos := path.last_index(path_separator) or {
|
||||
return path
|
||||
}
|
||||
return path[..pos ] // NB: *without* terminating /
|
||||
return path[..pos] // NB: *without* terminating /
|
||||
}
|
||||
|
||||
pub fn filename(path string) string {
|
||||
@@ -608,53 +649,54 @@ pub fn filename(path string) string {
|
||||
|
||||
// get_line returns a one-line string from stdin
|
||||
pub fn get_line() string {
|
||||
str := get_raw_line()
|
||||
str := get_raw_line()
|
||||
$if windows {
|
||||
return str.trim_right('\r\n')
|
||||
}
|
||||
$else {
|
||||
} $else {
|
||||
return str.trim_right('\n')
|
||||
}
|
||||
}
|
||||
|
||||
// get_raw_line returns a one-line string from stdin along with '\n' if there is any
|
||||
pub fn get_raw_line() string {
|
||||
$if windows {
|
||||
max_line_chars := 256
|
||||
buf := malloc(max_line_chars*2)
|
||||
if is_atty(0) > 0 {
|
||||
h_input := C.GetStdHandle(STD_INPUT_HANDLE)
|
||||
mut nr_chars := u32(0)
|
||||
C.ReadConsole(h_input, buf, max_line_chars * 2, voidptr(&nr_chars), 0)
|
||||
return string_from_wide2(&u16(buf), int(nr_chars))
|
||||
}
|
||||
res := C.fgetws(&u16(buf), max_line_chars, C.stdin )
|
||||
len := C.wcslen(&u16(buf))
|
||||
if !isnil(res) { return string_from_wide2( &u16(buf), len ) }
|
||||
return ''
|
||||
} $else {
|
||||
max := size_t(256)
|
||||
buf := charptr(malloc(int(max)))
|
||||
nr_chars := C.getline(&buf, &max, stdin)
|
||||
if nr_chars == 0 {
|
||||
return ''
|
||||
}
|
||||
return string(byteptr(buf), nr_chars)
|
||||
}
|
||||
$if windows {
|
||||
max_line_chars := 256
|
||||
buf := malloc(max_line_chars * 2)
|
||||
if is_atty(0) > 0 {
|
||||
h_input := C.GetStdHandle(STD_INPUT_HANDLE)
|
||||
mut nr_chars := u32(0)
|
||||
C.ReadConsole(h_input, buf, max_line_chars * 2, voidptr(&nr_chars), 0)
|
||||
return string_from_wide2(&u16(buf), int(nr_chars))
|
||||
}
|
||||
res := C.fgetws(&u16(buf), max_line_chars, C.stdin)
|
||||
len := C.wcslen(&u16(buf))
|
||||
if !isnil(res) {
|
||||
return string_from_wide2(&u16(buf), len)
|
||||
}
|
||||
return ''
|
||||
} $else {
|
||||
max := size_t(256)
|
||||
buf := charptr(malloc(int(max)))
|
||||
nr_chars := C.getline(&buf, &max, stdin)
|
||||
if nr_chars == 0 {
|
||||
return ''
|
||||
}
|
||||
return string(byteptr(buf),nr_chars)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_lines() []string {
|
||||
mut line := ''
|
||||
mut inputstr := []string
|
||||
for {
|
||||
line = get_line()
|
||||
if(line.len <= 0) {
|
||||
break
|
||||
}
|
||||
line = line.trim_space()
|
||||
inputstr << line
|
||||
}
|
||||
return inputstr
|
||||
mut line := ''
|
||||
mut inputstr := []string
|
||||
for {
|
||||
line = get_line()
|
||||
if (line.len <= 0) {
|
||||
break
|
||||
}
|
||||
line = line.trim_space()
|
||||
inputstr << line
|
||||
}
|
||||
return inputstr
|
||||
}
|
||||
|
||||
pub fn get_lines_joined() string {
|
||||
@@ -694,7 +736,7 @@ pub fn user_os() string {
|
||||
$if dragonfly {
|
||||
return 'dragonfly'
|
||||
}
|
||||
$if android{
|
||||
$if android {
|
||||
return 'android'
|
||||
}
|
||||
$if solaris {
|
||||
@@ -726,7 +768,7 @@ pub fn home_dir() string {
|
||||
|
||||
// write_file writes `text` data to a file in `path`.
|
||||
pub fn write_file(path, text string) {
|
||||
mut f := os.create(path) or {
|
||||
mut f := os.create(path)or{
|
||||
return
|
||||
}
|
||||
f.write(text)
|
||||
@@ -746,7 +788,8 @@ pub fn on_segfault(f voidptr) {
|
||||
return
|
||||
}
|
||||
$if macos {
|
||||
mut sa := C.sigaction{}
|
||||
mut sa := C.sigaction{
|
||||
}
|
||||
C.memset(&sa, 0, sizeof(sigaction))
|
||||
C.sigemptyset(&sa.sa_mask)
|
||||
sa.sa_sigaction = f
|
||||
@@ -756,10 +799,12 @@ pub fn on_segfault(f voidptr) {
|
||||
}
|
||||
|
||||
fn C.getpid() int
|
||||
fn C.proc_pidpath (int, byteptr, int) int
|
||||
|
||||
|
||||
fn C.proc_pidpath(int, byteptr, int) int
|
||||
|
||||
|
||||
fn C.readlink() int
|
||||
|
||||
|
||||
// executable returns the path name of the executable that started the current
|
||||
// process.
|
||||
pub fn executable() string {
|
||||
@@ -774,15 +819,15 @@ pub fn executable() string {
|
||||
}
|
||||
$if windows {
|
||||
max := 512
|
||||
mut result := &u16(calloc(max*2)) // MAX_PATH * sizeof(wchar_t)
|
||||
len := C.GetModuleFileName( 0, result, max )
|
||||
mut result := &u16(calloc(max * 2)) // MAX_PATH * sizeof(wchar_t)
|
||||
len := C.GetModuleFileName(0, result, max)
|
||||
return string_from_wide2(result, len)
|
||||
}
|
||||
$if macos {
|
||||
mut result := calloc(MAX_PATH)
|
||||
pid := C.getpid()
|
||||
ret := proc_pidpath (pid, result, MAX_PATH)
|
||||
if ret <= 0 {
|
||||
ret := proc_pidpath(pid, result, MAX_PATH)
|
||||
if ret <= 0 {
|
||||
eprintln('os.executable() failed at calling proc_pidpath with pid: $pid . proc_pidpath returned $ret ')
|
||||
return os.args[0]
|
||||
}
|
||||
@@ -790,7 +835,7 @@ pub fn executable() string {
|
||||
}
|
||||
$if freebsd {
|
||||
mut result := calloc(MAX_PATH)
|
||||
mib := [1 /* CTL_KERN */, 14 /* KERN_PROC */, 12 /* KERN_PROC_PATHNAME */, -1]
|
||||
mib := [1/* CTL_KERN */, 14/* KERN_PROC */, 12/* KERN_PROC_PATHNAME */, -1]
|
||||
size := MAX_PATH
|
||||
C.sysctl(mib.data, 4, result, &size, 0, 0)
|
||||
return string(result)
|
||||
@@ -806,21 +851,21 @@ pub fn executable() string {
|
||||
}
|
||||
$if netbsd {
|
||||
mut result := calloc(MAX_PATH)
|
||||
count := int(C.readlink('/proc/curproc/exe', result, MAX_PATH ))
|
||||
count := int(C.readlink('/proc/curproc/exe', result, MAX_PATH))
|
||||
if count < 0 {
|
||||
eprintln('os.executable() failed at reading /proc/curproc/exe to get exe path')
|
||||
return os.args[0]
|
||||
}
|
||||
return string(result, count)
|
||||
return string(result,count)
|
||||
}
|
||||
$if dragonfly {
|
||||
mut result := calloc(MAX_PATH)
|
||||
count := int(C.readlink('/proc/curproc/file', result, MAX_PATH ))
|
||||
count := int(C.readlink('/proc/curproc/file', result, MAX_PATH))
|
||||
if count < 0 {
|
||||
eprintln('os.executable() failed at reading /proc/curproc/file to get exe path')
|
||||
return os.args[0]
|
||||
}
|
||||
return string(result, count)
|
||||
return string(result,count)
|
||||
}
|
||||
return os.args[0]
|
||||
}
|
||||
@@ -828,9 +873,8 @@ pub fn executable() string {
|
||||
[deprecated]
|
||||
pub fn dir_exists(path string) bool {
|
||||
panic('use os.is_dir()')
|
||||
//return false
|
||||
// return false
|
||||
}
|
||||
|
||||
// is_dir returns a boolean indicating whether the given path is a directory.
|
||||
pub fn is_dir(path string) bool {
|
||||
$if windows {
|
||||
@@ -843,9 +887,9 @@ pub fn is_dir(path string) bool {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
$else {
|
||||
statbuf := C.stat{}
|
||||
} $else {
|
||||
statbuf := C.stat{
|
||||
}
|
||||
if C.stat(path.str, &statbuf) != 0 {
|
||||
return false
|
||||
}
|
||||
@@ -859,7 +903,8 @@ pub fn is_link(path string) bool {
|
||||
$if windows {
|
||||
return false // TODO
|
||||
} $else {
|
||||
statbuf := C.stat{}
|
||||
statbuf := C.stat{
|
||||
}
|
||||
if C.lstat(path.str, &statbuf) != 0 {
|
||||
return false
|
||||
}
|
||||
@@ -871,8 +916,7 @@ pub fn is_link(path string) bool {
|
||||
pub fn chdir(path string) {
|
||||
$if windows {
|
||||
C._wchdir(path.to_wide())
|
||||
}
|
||||
$else {
|
||||
} $else {
|
||||
C.chdir(path.str)
|
||||
}
|
||||
}
|
||||
@@ -881,13 +925,12 @@ pub fn chdir(path string) {
|
||||
pub fn getwd() string {
|
||||
$if windows {
|
||||
max := 512 // MAX_PATH * sizeof(wchar_t)
|
||||
buf := &u16(calloc(max*2))
|
||||
buf := &u16(calloc(max * 2))
|
||||
if C._wgetcwd(buf, max) == 0 {
|
||||
return ''
|
||||
}
|
||||
return string_from_wide(buf)
|
||||
}
|
||||
$else {
|
||||
} $else {
|
||||
buf := calloc(512)
|
||||
if C.getcwd(buf, 512) == 0 {
|
||||
return ''
|
||||
@@ -899,7 +942,7 @@ pub fn getwd() string {
|
||||
// Returns the full absolute path for fpath, with all relative ../../, symlinks and so on resolved.
|
||||
// See http://pubs.opengroup.org/onlinepubs/9699919799/functions/realpath.html
|
||||
// Also https://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
|
||||
// and https://insanecoding.blogspot.com/2007/11/implementing-realpath-in-c.html
|
||||
// and https://insanecoding.blogspot.com/2007/11/implementing-realpath-in-c.html
|
||||
// NB: this particular rabbit hole is *deep* ...
|
||||
pub fn realpath(fpath string) string {
|
||||
mut fullpath := calloc(MAX_PATH)
|
||||
@@ -923,9 +966,11 @@ pub fn walk_ext(path, ext string) []string {
|
||||
if !os.is_dir(path) {
|
||||
return []
|
||||
}
|
||||
mut files := os.ls(path) or { panic(err) }
|
||||
mut files := os.ls(path)or{
|
||||
panic(err)
|
||||
}
|
||||
mut res := []string
|
||||
separator := if path.ends_with(path_separator) { '' } else { path_separator}
|
||||
separator := if path.ends_with(path_separator) { '' } else { path_separator }
|
||||
for i, file in files {
|
||||
if file.starts_with('.') {
|
||||
continue
|
||||
@@ -947,7 +992,9 @@ pub fn walk(path string, fnc fn(path string)) {
|
||||
if !os.is_dir(path) {
|
||||
return
|
||||
}
|
||||
mut files := os.ls(path) or { panic(err) }
|
||||
mut files := os.ls(path)or{
|
||||
panic(err)
|
||||
}
|
||||
for file in files {
|
||||
p := path + os.path_separator + file
|
||||
if os.is_dir(p) {
|
||||
@@ -964,10 +1011,12 @@ pub fn signal(signum int, handler voidptr) {
|
||||
C.signal(signum, handler)
|
||||
}
|
||||
|
||||
|
||||
fn C.fork() int
|
||||
|
||||
|
||||
fn C.wait() int
|
||||
|
||||
|
||||
pub fn fork() int {
|
||||
mut pid := -1
|
||||
$if !windows {
|
||||
@@ -991,15 +1040,15 @@ pub fn wait() int {
|
||||
}
|
||||
|
||||
pub fn file_last_mod_unix(path string) int {
|
||||
attr := C.stat{}
|
||||
//# struct stat attr;
|
||||
attr := C.stat{
|
||||
}
|
||||
// # struct stat attr;
|
||||
C.stat(path.str, &attr)
|
||||
//# stat(path.str, &attr);
|
||||
// # stat(path.str, &attr);
|
||||
return attr.st_mtime
|
||||
//# return attr.st_mtime ;
|
||||
// # return attr.st_mtime ;
|
||||
}
|
||||
|
||||
|
||||
pub fn log(s string) {
|
||||
println('os.log: ' + s)
|
||||
}
|
||||
@@ -1009,7 +1058,7 @@ pub fn flush_stdout() {
|
||||
}
|
||||
|
||||
pub fn print_backtrace() {
|
||||
/*
|
||||
/*
|
||||
# void *buffer[100];
|
||||
nptrs := 0
|
||||
# nptrs = backtrace(buffer, 100);
|
||||
@@ -1023,24 +1072,30 @@ pub fn mkdir_all(path string) {
|
||||
for subdir in path.split(os.path_separator) {
|
||||
p += subdir + os.path_separator
|
||||
if !os.is_dir(p) {
|
||||
os.mkdir(p) or { panic(err) }
|
||||
os.mkdir(p)or{
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn join(base string, dirs ...string) string {
|
||||
println('use filepath.join')
|
||||
return filepath.join(base, dirs)
|
||||
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 path == '' {
|
||||
path = '/tmp'
|
||||
}
|
||||
}
|
||||
$if freebsd {
|
||||
if path == '' { path = '/tmp' }
|
||||
if path == '' {
|
||||
path = '/tmp'
|
||||
}
|
||||
}
|
||||
$if macos {
|
||||
/*
|
||||
@@ -1049,7 +1104,9 @@ pub fn tmpdir() string {
|
||||
path = C.NSTemporaryDirectory()
|
||||
}
|
||||
*/
|
||||
if path == '' { path = '/tmp' }
|
||||
if path == '' {
|
||||
path = '/tmp'
|
||||
}
|
||||
}
|
||||
$if windows {
|
||||
if path == '' {
|
||||
@@ -1057,18 +1114,22 @@ pub fn tmpdir() string {
|
||||
// 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' }
|
||||
if path == '' {
|
||||
path = os.getenv('TMP')
|
||||
}
|
||||
if path == '' {
|
||||
path = 'C:/tmp'
|
||||
}
|
||||
}
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
|
||||
pub fn chmod(path string, mode int) {
|
||||
C.chmod(path.str, mode)
|
||||
}
|
||||
|
||||
pub const (
|
||||
wd_at_startup = getwd()
|
||||
wd_at_startup = getwd()
|
||||
)
|
||||
|
||||
|
@@ -2,7 +2,6 @@ module os
|
||||
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
pub const (
|
||||
path_separator = '/'
|
||||
)
|
||||
@@ -15,7 +14,6 @@ pub fn init_os_args(argc int, argv &byteptr) []string {
|
||||
return args
|
||||
}
|
||||
|
||||
|
||||
// get_error_msg return error code representation in string.
|
||||
pub fn get_error_msg(code int) string {
|
||||
ptr_text := C.strerror(code) // voidptr?
|
||||
@@ -32,7 +30,7 @@ pub fn ls(path string) ?[]string {
|
||||
return error('ls() couldnt open dir "$path"')
|
||||
}
|
||||
mut ent := &C.dirent(0)
|
||||
//mut ent := &C.dirent{!}
|
||||
// mut ent := &C.dirent{!}
|
||||
for {
|
||||
ent = C.readdir(dir)
|
||||
if isnil(ent) {
|
||||
@@ -63,8 +61,10 @@ pub fn is_dir(path string) bool {
|
||||
|
||||
// mkdir creates a new directory with the specified path.
|
||||
pub fn mkdir(path string) ?bool {
|
||||
if path == '.' { return true }
|
||||
apath := os.realpath( path )
|
||||
if path == '.' {
|
||||
return true
|
||||
}
|
||||
apath := os.realpath(path)
|
||||
r := C.mkdir(apath.str, 511)
|
||||
if r == -1 {
|
||||
return error(get_error_msg(C.errno))
|
||||
@@ -74,9 +74,9 @@ pub fn mkdir(path string) ?bool {
|
||||
|
||||
// exec starts the specified command, waits for it to complete, and returns its output.
|
||||
pub fn exec(cmd string) ?Result {
|
||||
//if cmd.contains(';') || cmd.contains('&&') || cmd.contains('||') || cmd.contains('\n') {
|
||||
//return error(';, &&, || and \\n are not allowed in shell commands')
|
||||
//}
|
||||
// if cmd.contains(';') || cmd.contains('&&') || cmd.contains('||') || cmd.contains('\n') {
|
||||
// return error(';, &&, || and \\n are not allowed in shell commands')
|
||||
// }
|
||||
pcmd := '$cmd 2>&1'
|
||||
f := vpopen(pcmd)
|
||||
if isnil(f) {
|
||||
@@ -89,11 +89,12 @@ pub fn exec(cmd string) ?Result {
|
||||
}
|
||||
res = res.trim_space()
|
||||
exit_code := vpclose(f)
|
||||
//if exit_code != 0 {
|
||||
//return error(res)
|
||||
//}
|
||||
return Result {
|
||||
// if exit_code != 0 {
|
||||
// return error(res)
|
||||
// }
|
||||
return Result{
|
||||
output: res
|
||||
exit_code: exit_code
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user