diff --git a/ase/awk/extio.c b/ase/awk/extio.c index 48704a1e..20ce0893 100644 --- a/ase/awk/extio.c +++ b/ase/awk/extio.c @@ -1,5 +1,5 @@ /* - * $Id: extio.c,v 1.8 2006-06-22 04:25:44 bacon Exp $ + * $Id: extio.c,v 1.9 2006-06-22 14:15:01 bacon Exp $ */ #include @@ -100,6 +100,100 @@ xp_printf(XP_TEXT("%s"), buf); return 1; } +int xp_awk_writeextio ( + xp_awk_run_t* run, int type, + const xp_char_t* name, xp_awk_val_t* v, int* errnum) +{ + xp_awk_extio_t* p = run->extio; + xp_awk_io_t handler = run->awk->extio[type]; + int ioopt; + + if (handler == XP_NULL) + { + /* no io handler provided */ + *errnum = XP_AWK_EIOIMPL; /* TODO: change the error code */ + return -1; + } + + while (p != XP_NULL) + { + if (p->type == type && + xp_strcmp(p->name,name) == 0) break; + p = p->next; + } + + if (p == XP_NULL) + { + p = (xp_awk_extio_t*) xp_malloc (xp_sizeof(xp_awk_extio_t)); + if (p == XP_NULL) + { + *errnum = XP_AWK_ENOMEM; + return -1; + } + + p->name = xp_strdup (name); + if (p->name == XP_NULL) + { + xp_free (p); + *errnum = XP_AWK_ENOMEM; + return -1; + } + + p->type = type; + p->handle = XP_NULL; + p->next = XP_NULL; + + if (type == XP_AWK_EXTIO_PIPE) + ioopt = XP_AWK_IO_PIPE_READ; + else if (type == XP_AWK_EXTIO_FILE) + ioopt = XP_AWK_IO_FILE_READ; + else ioopt = 0; /* TODO: how to handle this??? */ + + if (handler (XP_AWK_IO_OPEN, ioopt, p, XP_NULL, 0) == -1) + { + xp_free (p->name); + xp_free (p); + + /* TODO: set ERRNO */ + *errnum = XP_AWK_ENOERR; + return -1; + } + + if (p->handle == XP_NULL) + { + xp_free (p->name); + xp_free (p); + + /* wrong implementation of user io handler. + * the correct io handler should set p->handle to + * non XP_NULL when it returns 0. */ + *errnum = XP_AWK_EIOIMPL; + return -1; + } + + /* chain it */ + p->next = run->extio; + run->extio = p; + } + + { + xp_awk_printval (v); +#if 0 +xp_char_t buf[1024] = XP_T("temp...");; + + if (handler (XP_AWK_IO_WRITE, 0, p, buf, xp_countof(buf)) == 0) + { + /* no more data. end of data stream */ + return 0; + } + +xp_printf(XP_TEXT("%s"), buf); +#endif + } + + return 1; +} + int xp_awk_closeextio (xp_awk_run_t* run, const xp_char_t* name, int* errnum) { xp_awk_extio_t* p = run->extio, * px = XP_NULL; diff --git a/ase/awk/extio.h b/ase/awk/extio.h index f96efad1..2cf08ae2 100644 --- a/ase/awk/extio.h +++ b/ase/awk/extio.h @@ -12,6 +12,11 @@ extern "C" int xp_awk_readextio ( xp_awk_run_t* run, int type, const xp_char_t* name, int* errnum); + +int xp_awk_writeextio ( + xp_awk_run_t* run, int type, + const xp_char_t* name, xp_awk_val_t* v, int* errnum); + int xp_awk_closeextio ( xp_awk_run_t* run, const xp_char_t* name, int* errnum); diff --git a/ase/awk/parse.c b/ase/awk/parse.c index 7bd73082..bb85bf84 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c,v 1.120 2006-06-22 04:25:44 bacon Exp $ + * $Id: parse.c,v 1.121 2006-06-22 14:15:01 bacon Exp $ */ #include @@ -2786,9 +2786,12 @@ static xp_awk_nde_t* __parse_print (xp_awk_t* awk) xp_awk_nde_t* out = XP_NULL; int out_type = -1; - /* TODO: expression list............ */ + /* TODO: handle expression list, not just a single expression */ + /* TODO: handle ambiguiouty print "1111" > "2222". is > redirection? */ + if (!MATCH(awk,TOKEN_SEMICOLON) && !MATCH(awk,TOKEN_GT) && + !MATCH(awk,TOKEN_RSHIFT) && !MATCH(awk,TOKEN_BOR) && !MATCH(awk,TOKEN_BORAND)) { @@ -2800,6 +2803,10 @@ static xp_awk_nde_t* __parse_print (xp_awk_t* awk) { out_type = XP_AWK_PRINT_FILE; } + else if (MATCH(awk,TOKEN_RSHIFT)) + { + out_type = XP_AWK_PRINT_FILE_APPEND; + } else if (MATCH(awk,TOKEN_BOR)) { out_type = XP_AWK_PRINT_PIPE; diff --git a/ase/awk/run.c b/ase/awk/run.c index 060bd444..c60c7972 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c,v 1.105 2006-06-22 04:25:44 bacon Exp $ + * $Id: run.c,v 1.106 2006-06-22 14:15:01 bacon Exp $ */ #include @@ -1079,8 +1079,99 @@ static int __run_nextfile_statement (xp_awk_run_t* run, xp_awk_nde_nextfile_t* n static int __run_print_statement (xp_awk_run_t* run, xp_awk_nde_print_t* nde) { -xp_printf (XP_T("**** print NOT IMPLEMENTED...\n")); - return -1; + xp_awk_nde_print_t* p = (xp_awk_nde_print_t*)nde; + xp_awk_val_t* v; + + if (p->out_type == XP_AWK_PRINT_PIPE) + { + xp_awk_val_t* out; + xp_char_t* dst; + int errnum, n; + + out = __eval_expression (run, p->out); + if (out == XP_NULL) return -1; + + xp_awk_refupval (out); + dst = xp_awk_valtostr (out, &errnum, XP_NULL); + if (dst == XP_NULL) + { + xp_awk_refdownval (run, out); + PANIC_I (run, errnum); + } + xp_awk_refdownval (run, out); + + if (p->args == XP_NULL) + { + /* TODO: get $0 ans use it for v */ + v = xp_awk_makestrval (XP_T("$0\n"), 1); + if (v == XP_NULL) + { + xp_free (dst); + PANIC_I (run, XP_AWK_ENOMEM); + } + + xp_awk_refupval (v); + n = xp_awk_writeextio ( + run, XP_AWK_EXTIO_PIPE, dst, v, &errnum); + if (n < 0 && errnum != XP_AWK_ENOERR) + { + xp_free (dst); + xp_awk_refdownval (run, v); + PANIC_I (run, errnum); + } + + xp_awk_refdownval (run, v); + } + else + { + xp_awk_nde_t* np = p->args; + while (np != XP_NULL) + { + v = __eval_expression (run, np); + if (v == XP_NULL) + { + xp_free (dst); + return -1; + } + xp_awk_refupval (v); + + n = xp_awk_writeextio ( + run, XP_AWK_EXTIO_PIPE, dst, v, &errnum); + if (n < 0 && errnum != XP_AWK_ENOERR) + { + xp_free (dst); + xp_awk_refdownval (run, v); + PANIC_I (run, errnum); + } + + xp_awk_refdownval (run, v); + np = np->next; + } + } + + xp_free (dst); + return 0; + } + else if (p->out_type == XP_AWK_PRINT_COPROC) + { + xp_printf (XP_T("eval_getline coprocess not properly implemented....\n")); + return -1; + } + else if (p->out_type == XP_AWK_PRINT_FILE) + { + xp_printf (XP_T("eval_print PRINT_FILE not properly implemented....\n")); + return -1; + } + else if (p->out_type == XP_AWK_PRINT_FILE_APPEND) + { + xp_printf (XP_T("eval_print PRINT_FILE_APPEND not properly implemented....\n")); + return -1; + } + else + { + xp_assert (!"should never happen - wrong out_type for getline"); + PANIC_I (run, XP_AWK_EINTERNAL); + } } static xp_awk_val_t* __eval_expression (xp_awk_run_t* run, xp_awk_nde_t* nde) @@ -2965,6 +3056,9 @@ static xp_awk_val_t* __eval_getline (xp_awk_run_t* run, xp_awk_nde_t* nde) n = xp_awk_readextio (run, XP_AWK_EXTIO_PIPE, str, &errnum); xp_free (str); + /* TODO: set the value to var if it is not null */ + /* TODO: set $0 if var is null */ + if (n < 0 && errnum != XP_AWK_ENOERR) PANIC (run, errnum); return xp_awk_makeintval (run, n); } @@ -2994,6 +3088,9 @@ static xp_awk_val_t* __eval_getline (xp_awk_run_t* run, xp_awk_nde_t* nde) n = xp_awk_readextio (run, XP_AWK_EXTIO_FILE, str, &errnum); xp_free (str); + /* TODO: set the value to var if it is not null */ + /* TODO: set $0 if var is null */ + if (n < 0 && errnum != XP_AWK_ENOERR) PANIC (run, errnum); return xp_awk_makeintval (run, n); } diff --git a/ase/awk/tree.c b/ase/awk/tree.c index 0131eb15..e4fb6107 100644 --- a/ase/awk/tree.c +++ b/ase/awk/tree.c @@ -1,5 +1,5 @@ /* - * $Id: tree.c,v 1.55 2006-06-19 15:43:27 bacon Exp $ + * $Id: tree.c,v 1.56 2006-06-22 14:15:02 bacon Exp $ */ #include @@ -79,7 +79,8 @@ static const xp_char_t* __print_outop_str[] = { XP_T("|"), XP_T("|&"), - XP_T(">") + XP_T(">"), + XP_T(">>") }; static void __print_tabs (int depth); diff --git a/ase/awk/tree.h b/ase/awk/tree.h index e9b0337d..10a698d2 100644 --- a/ase/awk/tree.h +++ b/ase/awk/tree.h @@ -1,5 +1,5 @@ /* - * $Id: tree.h,v 1.47 2006-06-20 15:27:50 bacon Exp $ + * $Id: tree.h,v 1.48 2006-06-22 14:15:02 bacon Exp $ */ #ifndef _XP_AWK_TREE_H_ @@ -69,7 +69,8 @@ enum { XP_AWK_PRINT_PIPE, XP_AWK_PRINT_COPROC, - XP_AWK_PRINT_FILE + XP_AWK_PRINT_FILE, + XP_AWK_PRINT_FILE_APPEND }; typedef struct xp_awk_afn_t xp_awk_afn_t; @@ -228,7 +229,7 @@ struct xp_awk_nde_getline_t { XP_AWK_NDE_HDR; xp_awk_nde_t* var; - int in_type; /* XP_AWK_GETLINE_PIPE, XP_AWK_GETLINE_FILE */ + int in_type; /* XP_AWK_GETLINE_XXX */ xp_awk_nde_t* in; }; @@ -237,7 +238,7 @@ struct xp_awk_nde_print_t { XP_AWK_NDE_HDR; xp_awk_nde_t* args; - int out_type; /* XP_AWK_PRINT_PIPE, XP_AWK_PRINT_FILE */ + int out_type; /* XP_AWK_PRINT_XXX */ xp_awk_nde_t* out; }; diff --git a/ase/test/awk/t10.awk b/ase/test/awk/t10.awk index affc0081..f251f8ad 100644 --- a/ase/test/awk/t10.awk +++ b/ase/test/awk/t10.awk @@ -1,5 +1,9 @@ BEGIN { + print | "more"; + print >> "echo"; + print >> "echo"; + getline x < "abc"; /* open("abc", O_RDONLY|O_LARGEFILE) = 3 */ //print 10 >> "abc"; /* open("abc", O_WRONLY|O_APPEND|O_CREAT|O_LARGEFILE, 0666) = 4 */ getline x < "abc";