mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
os: add os.open_stdin/0 and os.File.get_line/0
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
module os
|
||||
|
||||
import strings
|
||||
|
||||
pub struct File {
|
||||
cfile voidptr // Using void* instead of FILE*
|
||||
pub:
|
||||
@@ -88,3 +90,63 @@ pub fn (mut f File) flush() {
|
||||
}
|
||||
C.fflush(f.cfile)
|
||||
}
|
||||
|
||||
// open_stdin - return an os.File for stdin, so that you can use .get_line on it too.
|
||||
pub fn open_stdin() File {
|
||||
return File{
|
||||
fd: 0
|
||||
cfile: C.stdin
|
||||
is_opened: true
|
||||
}
|
||||
}
|
||||
|
||||
// File.get_line - get a single line from the file. NB: the ending newline is *included*.
|
||||
pub fn (mut f File) get_line() ?string {
|
||||
if !f.is_opened {
|
||||
return error('file is closed')
|
||||
}
|
||||
$if !windows {
|
||||
mut zbuf := byteptr(0)
|
||||
mut zblen := size_t(0)
|
||||
mut zx := 0
|
||||
unsafe {
|
||||
zx = C.getline(&zbuf, &zblen, f.cfile)
|
||||
if zx == -1 {
|
||||
C.free(zbuf)
|
||||
if C.errno == 0 {
|
||||
return error('end of file')
|
||||
}
|
||||
return error(posix_get_error_msg(C.errno))
|
||||
}
|
||||
return zbuf.vstring_with_len(zx)
|
||||
}
|
||||
}
|
||||
//
|
||||
// using C.fgets is less efficient than f.get_line_getline,
|
||||
// but is available everywhere, while C.getline does not work
|
||||
// on windows
|
||||
//
|
||||
buf := [4096]byte{}
|
||||
mut res := strings.new_builder(1024)
|
||||
mut x := 0
|
||||
for {
|
||||
unsafe {
|
||||
x = C.fgets(charptr(buf), 4096, f.cfile)
|
||||
}
|
||||
if x == 0 {
|
||||
if res.len > 0 {
|
||||
break
|
||||
}
|
||||
return error('end of file')
|
||||
}
|
||||
bufbp := byteptr(buf)
|
||||
mut blen := vstrlen(bufbp)
|
||||
res.write_bytes(bufbp, blen)
|
||||
unsafe {
|
||||
if blen == 0 || bufbp[blen-1] == `\n` || bufbp[blen-1] == `\r` {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return res.str()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user