os: fixes for os.input(), os.get_raw_stdin(), os.get_raw_line() in case of stdin EOF

pull/9004/head
Delyan Angelov 2021-02-27 12:50:15 +02:00
parent e6b4f9ff09
commit 20f9bdfa8e
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
4 changed files with 42 additions and 21 deletions

View File

@ -263,7 +263,7 @@ fn C._waccess() int
fn C._wremove() int
fn C.ReadConsole() voidptr
fn C.ReadConsole(in_input_handle voidptr, out_buffer voidptr, in_chars_to_read u32, out_read_chars &u32, in_input_control voidptr) bool
fn C.WriteConsole() voidptr

View File

@ -200,11 +200,23 @@ pub fn file_name(path string) string {
return path.all_after_last(path_separator)
}
// input returns a one-line string from stdin, after printing a prompt.
pub fn input(prompt string) string {
// input_opt returns a one-line string from stdin, after printing a prompt.
// In the event of error (end of input), it returns `none`.
pub fn input_opt(prompt string) ?string {
print(prompt)
flush()
return get_line()
res := get_raw_line()
if res.len > 0 {
return res.trim_right('\r\n')
}
return none
}
// input returns a one-line string from stdin, after printing a prompt.
// In the event of error (end of input), it returns '<EOF>'.
pub fn input(prompt string) string {
res := input_opt(prompt) or { return '<EOF>' }
return res
}
// get_line returns a one-line string from stdin
@ -212,9 +224,8 @@ pub fn get_line() string {
str := get_raw_line()
$if windows {
return str.trim_right('\r\n')
} $else {
return str.trim_right('\n')
}
return str.trim_right('\n')
}
// get_lines returns an array of strings read from from stdin.

View File

@ -476,14 +476,20 @@ pub fn get_raw_line() string {
h_input := C.GetStdHandle(C.STD_INPUT_HANDLE)
mut bytes_read := 0
if is_atty(0) > 0 {
C.ReadConsole(h_input, buf, max_line_chars * 2, C.LPDWORD(&bytes_read),
x := C.ReadConsole(h_input, buf, max_line_chars * 2, C.LPDWORD(&bytes_read),
0)
if !x {
return tos(buf, 0)
}
return string_from_wide2(&u16(buf), bytes_read)
}
mut offset := 0
for {
pos := buf + offset
res := C.ReadFile(h_input, pos, 1, C.LPDWORD(&bytes_read), 0)
if !res && offset == 0 {
return tos(buf, 0)
}
if !res || bytes_read == 0 {
break
}
@ -497,15 +503,9 @@ pub fn get_raw_line() string {
}
} $else {
max := size_t(0)
mut buf := charptr(0)
buf := charptr(0)
nr_chars := unsafe { C.getline(&buf, &max, C.stdin) }
// defer { unsafe{ free(buf) } }
if nr_chars == 0 || nr_chars == -1 {
return ''
}
return unsafe { tos3(buf) }
// res := tos_clone(buf)
// return res
return unsafe { tos(byteptr(buf), if nr_chars < 0 { 0 } else { nr_chars }) }
}
}
@ -527,7 +527,6 @@ pub fn get_raw_stdin() []byte {
}
buf = v_realloc(buf, offset + block_bytes + (block_bytes - bytes_read))
}
C.CloseHandle(h_input)
return array{
element_size: 1
data: voidptr(buf)
@ -536,7 +535,15 @@ pub fn get_raw_stdin() []byte {
}
}
} $else {
panic('get_raw_stdin not implemented on this platform...')
max := size_t(0)
buf := charptr(0)
nr_chars := unsafe { C.getline(&buf, &max, C.stdin) }
return array{
element_size: 1
data: voidptr(buf)
len: if nr_chars < 0 { 0 } else { nr_chars }
cap: int(max)
}
}
}

View File

@ -22,15 +22,18 @@ fn main() {
term.set_cursor_position(x: width / 2, y: height / 2) // now we point the cursor to the middle of the terminal
println(term.strikethrough(term.bright_green('hello world'))) // Print green text
term.set_cursor_position(x: 0, y: height) // Sets the position of the cursor to the bottom of the terminal
mut var := os.input('press q to quit: ')
// Keep prompting until the user presses the q key
for {
if var == 'q' {
if var := os.input_opt('press q to quit: ') {
if var != 'q' {
continue
}
break
} else {
var = os.input('press q to quit: ')
}
println('')
break
}
println('Goodbye.')
}
```