os: basic proof of concept stdout capture; autofree: small fixes

pull/6751/head
Alexander Medvednikov 2020-11-05 08:44:34 +01:00
parent 8157f3c6ab
commit 1b1d17cfb5
4 changed files with 86 additions and 10 deletions

View File

@ -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 {
res := C.symlink(charptr(origin.str), charptr(target.str))
if res == 0 {

View File

@ -503,3 +503,18 @@ fn test_write_file_array_structs() {
assert rarr.len == maxn
// 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()
*/
}

View File

@ -118,7 +118,8 @@ mut:
called_fn_name string
cur_mod string
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
}
@ -1043,8 +1044,11 @@ fn (mut g Gen) stmt(node ast.Stmt) {
// 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);`
if g.pref.autofree {
p := node.position()
g.autofree_call_postgen(p.pos)
// if node is ast.ExprStmt {&& node.expr is ast.CallExpr {
if node !is ast.FnDecl {
p := node.position()
g.autofree_call_postgen(p.pos)
}
}
}
@ -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
return
}
// if v.is_autofree_tmp {
// return
// }
if v.is_autofree_tmp && !g.doing_autofree_tmp {
return
}
if v.typ.is_ptr() {
g.writeln('\t${free_fn_name}(${c_name(v.name)}); // autofreed ptr var')
} 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')
}
}

View File

@ -709,7 +709,7 @@ fn (mut g Gen) autofree_call_pregen(node ast.CallExpr) {
g.strs_to_free0 << s
// Now free the tmp arg vars right after the function call
// g.strs_to_free << t
g.nr_vars_to_free++
// g.nr_vars_to_free++
// g.strs_to_free << 'string_free(&$t);'
}
}
@ -720,10 +720,12 @@ fn (mut g Gen) autofree_call_postgen(node_pos int) {
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 {
return
}
*/
/*
for s in g.strs_to_free {
g.writeln('string_free(&$s);')
@ -734,6 +736,11 @@ fn (mut g Gen) autofree_call_postgen(node_pos int) {
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)
for _, obj in scope.objects {
match mut obj {
@ -757,11 +764,13 @@ fn (mut g Gen) autofree_call_postgen(node_pos int) {
}
obj.is_used = true
g.autofree_variable(v)
g.nr_vars_to_free--
// g.nr_vars_to_free--
}
else {}
}
}
g.write('/* postgen end */')
g.doing_autofree_tmp = false
}
fn (mut g Gen) call_args(node ast.CallExpr) {