os: basic proof of concept stdout capture; autofree: small fixes
parent
8157f3c6ab
commit
1b1d17cfb5
|
@ -159,6 +159,54 @@ pub fn exec(cmd string) ?Result {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Command {
|
||||||
|
mut:
|
||||||
|
f voidptr
|
||||||
|
pub mut:
|
||||||
|
eof bool
|
||||||
|
pub:
|
||||||
|
path string
|
||||||
|
redirect_stdout bool
|
||||||
|
}
|
||||||
|
|
||||||
|
//pub fn command(cmd Command) Command {
|
||||||
|
//}
|
||||||
|
|
||||||
|
pub fn (mut c Command) start()? {
|
||||||
|
pcmd := '$c.path 2>&1'
|
||||||
|
c.f = vpopen(pcmd)
|
||||||
|
if isnil(c.f) {
|
||||||
|
return error('exec("$c.path") failed')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (mut c Command) read_line() string {
|
||||||
|
buf := [4096]byte{}
|
||||||
|
mut res := strings.new_builder(1024)
|
||||||
|
unsafe {
|
||||||
|
for C.fgets(charptr(buf), 4096, c.f) != 0 {
|
||||||
|
bufbp := byteptr(buf)
|
||||||
|
len := vstrlen(bufbp)
|
||||||
|
for i in 0..len {
|
||||||
|
if int(bufbp[i]) == `\n` {
|
||||||
|
res.write_bytes(bufbp, i)
|
||||||
|
return res.str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.write_bytes(bufbp, len)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.eof = true
|
||||||
|
return res.str()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (c &Command) close()? {
|
||||||
|
exit_code := vpclose(c.f)
|
||||||
|
if exit_code == 127 {
|
||||||
|
return error_with_code('error', 127)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn symlink(origin string, target string) ?bool {
|
pub fn symlink(origin string, target string) ?bool {
|
||||||
res := C.symlink(charptr(origin.str), charptr(target.str))
|
res := C.symlink(charptr(origin.str), charptr(target.str))
|
||||||
if res == 0 {
|
if res == 0 {
|
||||||
|
|
|
@ -503,3 +503,18 @@ fn test_write_file_array_structs() {
|
||||||
assert rarr.len == maxn
|
assert rarr.len == maxn
|
||||||
// eprintln( rarr.str().replace('\n', ' ').replace('},', '},\n'))
|
// eprintln( rarr.str().replace('\n', ' ').replace('},', '},\n'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_stdout_capture() {
|
||||||
|
/*
|
||||||
|
mut cmd := os.Command{
|
||||||
|
path:'cat'
|
||||||
|
redirect_stdout: true
|
||||||
|
}
|
||||||
|
cmd.start()
|
||||||
|
for !cmd.eof {
|
||||||
|
line := cmd.read_line()
|
||||||
|
println('line="$line"')
|
||||||
|
}
|
||||||
|
cmd.close()
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
|
@ -118,7 +118,8 @@ mut:
|
||||||
called_fn_name string
|
called_fn_name string
|
||||||
cur_mod string
|
cur_mod string
|
||||||
is_js_call bool // for handling a special type arg #1 `json.decode(User, ...)`
|
is_js_call bool // for handling a special type arg #1 `json.decode(User, ...)`
|
||||||
nr_vars_to_free int
|
// nr_vars_to_free int
|
||||||
|
doing_autofree_tmp bool
|
||||||
inside_lambda bool
|
inside_lambda bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1043,9 +1044,12 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||||
// If we have temporary string exprs to free after this statement, do it. e.g.:
|
// If we have temporary string exprs to free after this statement, do it. e.g.:
|
||||||
// `foo('a' + 'b')` => `tmp := 'a' + 'b'; foo(tmp); string_free(&tmp);`
|
// `foo('a' + 'b')` => `tmp := 'a' + 'b'; foo(tmp); string_free(&tmp);`
|
||||||
if g.pref.autofree {
|
if g.pref.autofree {
|
||||||
|
// if node is ast.ExprStmt {&& node.expr is ast.CallExpr {
|
||||||
|
if node !is ast.FnDecl {
|
||||||
p := node.position()
|
p := node.position()
|
||||||
g.autofree_call_postgen(p.pos)
|
g.autofree_call_postgen(p.pos)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) write_defer_stmts() {
|
fn (mut g Gen) write_defer_stmts() {
|
||||||
|
@ -1975,13 +1979,13 @@ fn (mut g Gen) autofree_var_call(free_fn_name string, v ast.Var) {
|
||||||
// tmp expr vars do not need to be freed again here
|
// tmp expr vars do not need to be freed again here
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// if v.is_autofree_tmp {
|
if v.is_autofree_tmp && !g.doing_autofree_tmp {
|
||||||
// return
|
return
|
||||||
// }
|
}
|
||||||
if v.typ.is_ptr() {
|
if v.typ.is_ptr() {
|
||||||
g.writeln('\t${free_fn_name}(${c_name(v.name)}); // autofreed ptr var')
|
g.writeln('\t${free_fn_name}(${c_name(v.name)}); // autofreed ptr var')
|
||||||
} else {
|
} else {
|
||||||
g.writeln('\t${free_fn_name}(&${c_name(v.name)}); // autofreed var')
|
g.writeln('\t${free_fn_name}(&${c_name(v.name)}); // autofreed var $g.doing_autofree_tmp')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -709,7 +709,7 @@ fn (mut g Gen) autofree_call_pregen(node ast.CallExpr) {
|
||||||
g.strs_to_free0 << s
|
g.strs_to_free0 << s
|
||||||
// Now free the tmp arg vars right after the function call
|
// Now free the tmp arg vars right after the function call
|
||||||
// g.strs_to_free << t
|
// g.strs_to_free << t
|
||||||
g.nr_vars_to_free++
|
// g.nr_vars_to_free++
|
||||||
// g.strs_to_free << 'string_free(&$t);'
|
// g.strs_to_free << 'string_free(&$t);'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -720,10 +720,12 @@ fn (mut g Gen) autofree_call_postgen(node_pos int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
// g.writeln('\n/* strs_to_free3: $g.nr_vars_to_free */')
|
/*
|
||||||
|
g.writeln('\n/* strs_to_free3: $g.nr_vars_to_free */')
|
||||||
if g.nr_vars_to_free <= 0 {
|
if g.nr_vars_to_free <= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
for s in g.strs_to_free {
|
for s in g.strs_to_free {
|
||||||
g.writeln('string_free(&$s);')
|
g.writeln('string_free(&$s);')
|
||||||
|
@ -734,6 +736,11 @@ fn (mut g Gen) autofree_call_postgen(node_pos int) {
|
||||||
g.strs_to_free = []
|
g.strs_to_free = []
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
if g.inside_vweb_tmpl {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
g.doing_autofree_tmp = true
|
||||||
|
g.write('/* postgen */')
|
||||||
scope := g.file.scope.innermost(node_pos)
|
scope := g.file.scope.innermost(node_pos)
|
||||||
for _, obj in scope.objects {
|
for _, obj in scope.objects {
|
||||||
match mut obj {
|
match mut obj {
|
||||||
|
@ -757,11 +764,13 @@ fn (mut g Gen) autofree_call_postgen(node_pos int) {
|
||||||
}
|
}
|
||||||
obj.is_used = true
|
obj.is_used = true
|
||||||
g.autofree_variable(v)
|
g.autofree_variable(v)
|
||||||
g.nr_vars_to_free--
|
// g.nr_vars_to_free--
|
||||||
}
|
}
|
||||||
else {}
|
else {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
g.write('/* postgen end */')
|
||||||
|
g.doing_autofree_tmp = false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) call_args(node ast.CallExpr) {
|
fn (mut g Gen) call_args(node ast.CallExpr) {
|
||||||
|
|
Loading…
Reference in New Issue