mirror of
https://github.com/vlang/v.git
synced 2025-08-04 02:07:28 -04:00
parent
1b136e213a
commit
f4b51d064e
12
examples/get_raw_line.v
Normal file
12
examples/get_raw_line.v
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
println('Press Ctrl+D(Linux) or Ctrl+Z(Windows) at line begin to exit')
|
||||||
|
mut i := 0
|
||||||
|
for {
|
||||||
|
i += 1
|
||||||
|
mut line := os.get_raw_line()
|
||||||
|
if line.len == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
println('${i}: ${line}')
|
||||||
|
}
|
@ -500,44 +500,74 @@ fn print_c_errno() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get_raw_line returns a one-line string from stdin along with '\n' if there is any.
|
// get_raw_line returns a one-line string from stdin along with '\n' if there is any.
|
||||||
|
@[manualfree]
|
||||||
pub fn get_raw_line() string {
|
pub fn get_raw_line() string {
|
||||||
$if windows {
|
$if windows {
|
||||||
unsafe {
|
is_console := is_atty(0) > 0
|
||||||
max_line_chars := 256
|
wide_char_size := if is_console { 2 } else { 1 }
|
||||||
mut old_size := max_line_chars * 2
|
|
||||||
mut buf := malloc_noscan(old_size)
|
|
||||||
h_input := C.GetStdHandle(C.STD_INPUT_HANDLE)
|
h_input := C.GetStdHandle(C.STD_INPUT_HANDLE)
|
||||||
mut bytes_read := u32(0)
|
if h_input == C.INVALID_HANDLE_VALUE {
|
||||||
if is_atty(0) > 0 {
|
return ''
|
||||||
x := C.ReadConsole(h_input, buf, max_line_chars * 2, voidptr(&bytes_read),
|
|
||||||
0)
|
|
||||||
if !x {
|
|
||||||
return tos(buf, 0)
|
|
||||||
}
|
|
||||||
return string_from_wide2(&u16(buf), int(bytes_read))
|
|
||||||
}
|
}
|
||||||
|
unsafe {
|
||||||
|
initial_size := 256 * wide_char_size
|
||||||
|
mut buf := malloc_noscan(initial_size)
|
||||||
|
defer { buf.free() }
|
||||||
|
mut capacity := initial_size
|
||||||
mut offset := 0
|
mut offset := 0
|
||||||
|
|
||||||
for {
|
for {
|
||||||
pos := buf + offset
|
required_space := offset + wide_char_size
|
||||||
res := C.ReadFile(h_input, pos, 1, voidptr(&bytes_read), 0)
|
if required_space > capacity {
|
||||||
if !res && offset == 0 {
|
new_capacity := capacity * 2
|
||||||
return tos(buf, 0)
|
new_buf := realloc_data(buf, capacity, new_capacity)
|
||||||
|
if new_buf == 0 {
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
buf = new_buf
|
||||||
|
capacity = new_capacity
|
||||||
|
}
|
||||||
|
|
||||||
|
pos := buf + offset
|
||||||
|
mut bytes_read := u32(0)
|
||||||
|
res := if is_console {
|
||||||
|
C.ReadConsole(h_input, pos, 1, voidptr(&bytes_read), 0)
|
||||||
|
} else {
|
||||||
|
C.ReadFile(h_input, pos, 1, voidptr(&bytes_read), 0)
|
||||||
|
}
|
||||||
|
|
||||||
if !res || bytes_read == 0 {
|
if !res || bytes_read == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if *pos == `\n` {
|
|
||||||
offset++
|
// check for `\n` and Ctrl+Z
|
||||||
|
if is_console {
|
||||||
|
read_char := *(&u16(pos))
|
||||||
|
if read_char == `\n` {
|
||||||
|
offset += wide_char_size
|
||||||
|
break
|
||||||
|
} else if read_char == 0x1A {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
offset++
|
} else {
|
||||||
if offset >= old_size {
|
read_byte := *pos
|
||||||
new_size := old_size + max_line_chars * 2
|
if read_byte == `\n` {
|
||||||
buf = realloc_data(buf, old_size, new_size)
|
offset += wide_char_size
|
||||||
old_size = new_size
|
break
|
||||||
|
} else if read_byte == 0x1A {
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return buf.vstring_with_len(offset)
|
|
||||||
|
offset += wide_char_size
|
||||||
|
}
|
||||||
|
|
||||||
|
return if is_console {
|
||||||
|
string_from_wide2(&u16(buf), offset / 2)
|
||||||
|
} else {
|
||||||
|
// let defer buf.free() to avoid memory leak
|
||||||
|
buf.vstring_with_len(offset).clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} $else {
|
} $else {
|
||||||
max := usize(0)
|
max := usize(0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user