diff --git a/ase/awk/awk.h b/ase/awk/awk.h index 793a654b..365c4c59 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h,v 1.72 2006-06-25 15:26:57 bacon Exp $ + * $Id: awk.h,v 1.73 2006-06-26 15:09:28 bacon Exp $ */ #ifndef _XP_AWK_AWK_H_ @@ -122,7 +122,7 @@ enum XP_AWK_ENOSUCHFUNC, /* no such function */ XP_AWK_ENOTASSIGNABLE, /* value not assignable */ XP_AWK_ENOTINDEXABLE, /* not indexable value */ - XP_AWK_EWRONGINDEX, /* wrong index */ + XP_AWK_EVALTYPE, /* wrong value type */ XP_AWK_EPIPE, /* pipe operation error */ XP_AWK_EIOIMPL, /* wrong implementation of user io handler */ XP_AWK_EINTERNAL /* internal error */ diff --git a/ase/awk/err.c b/ase/awk/err.c index 4e43da9b..882df682 100644 --- a/ase/awk/err.c +++ b/ase/awk/err.c @@ -1,5 +1,5 @@ /* - * $Id: err.c,v 1.22 2006-06-21 15:37:51 bacon Exp $ + * $Id: err.c,v 1.23 2006-06-26 15:09:28 bacon Exp $ */ #include @@ -65,7 +65,7 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk) XP_T("no such function"), XP_T("value not assignable"), XP_T("value not indexable"), - XP_T("wrong index value"), + XP_T("wrong value type"), XP_T("pipe operation error"), XP_T("wrong implementation of user-defined io handler"), diff --git a/ase/awk/extio.c b/ase/awk/extio.c index 7e221376..bbc52f0b 100644 --- a/ase/awk/extio.c +++ b/ase/awk/extio.c @@ -1,5 +1,5 @@ /* - * $Id: extio.c,v 1.10 2006-06-25 15:26:57 bacon Exp $ + * $Id: extio.c,v 1.11 2006-06-26 15:09:28 bacon Exp $ */ #include @@ -26,8 +26,7 @@ int xp_awk_readextio ( while (p != XP_NULL) { - if (p->type == type && - xp_strcmp(p->name,name) == 0) break; + if (p->type == type && xp_strcmp(p->name,name) == 0) break; p = p->next; } @@ -106,6 +105,7 @@ int xp_awk_writeextio ( { xp_awk_extio_t* p = run->extio; xp_awk_io_t handler = run->awk->extio[type]; + xp_str_t buf; int ioopt; if (handler == XP_NULL) @@ -115,18 +115,34 @@ int xp_awk_writeextio ( return -1; } + /* TODO: optimize the buffer management. each xp_awk_run_t have a buffer for this operation??? */ + if (xp_str_open (&buf, 256) == XP_NULL) + { + *errnum = XP_AWK_ENOMEM; + return -1; + } + + /* convert the value to string representation first */ + if (xp_awk_valtostr(v, errnum, &buf) == XP_NULL) + { + xp_str_close (&buf); + return -1; + } + + /* look for the corresponding extio for name */ while (p != XP_NULL) { - if (p->type == type && - xp_strcmp(p->name,name) == 0) break; + if (p->type == type && xp_strcmp(p->name,name) == 0) break; p = p->next; } + /* if there is not corresponding extio for name, create one */ if (p == XP_NULL) { p = (xp_awk_extio_t*) xp_malloc (xp_sizeof(xp_awk_extio_t)); if (p == XP_NULL) { + xp_str_close (&buf); *errnum = XP_AWK_ENOMEM; return -1; } @@ -135,6 +151,7 @@ int xp_awk_writeextio ( if (p->name == XP_NULL) { xp_free (p); + xp_str_close (&buf); *errnum = XP_AWK_ENOMEM; return -1; } @@ -144,17 +161,18 @@ int xp_awk_writeextio ( p->next = XP_NULL; if (type == XP_AWK_EXTIO_PIPE) - ioopt = XP_AWK_IO_PIPE_READ; + ioopt = XP_AWK_IO_PIPE_WRITE; else if (type == XP_AWK_EXTIO_FILE) - ioopt = XP_AWK_IO_FILE_READ; + ioopt = XP_AWK_IO_FILE_WRITE; else if (type == XP_AWK_EXTIO_CONSOLE) - ioopt = XP_AWK_IO_CONSOLE_READ; + ioopt = XP_AWK_IO_CONSOLE_WRITE; 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); + xp_str_close (&buf); /* TODO: set ERRNO */ *errnum = XP_AWK_ENOERR; @@ -165,8 +183,9 @@ int xp_awk_writeextio ( { xp_free (p->name); xp_free (p); + xp_str_close (&buf); - /* wrong implementation of user io handler. + /* wrong implementation of the user io handler. * the correct io handler should set p->handle to * non XP_NULL when it returns 0. */ *errnum = XP_AWK_EIOIMPL; @@ -178,21 +197,14 @@ int xp_awk_writeextio ( run->extio = p; } + if (handler (XP_AWK_IO_WRITE, 0, + p, XP_STR_BUF(&buf), XP_STR_LEN(&buf)) == 0) { - 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 */ + xp_str_close (&buf); return 0; } -xp_printf(XP_TEXT("%s"), buf); -#endif - } - + xp_str_close (&buf); return 1; } diff --git a/ase/awk/run.c b/ase/awk/run.c index 59852dca..c41d3acc 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c,v 1.107 2006-06-25 15:26:57 bacon Exp $ + * $Id: run.c,v 1.108 2006-06-26 15:09:28 bacon Exp $ */ #include @@ -1080,125 +1080,121 @@ 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_awk_nde_print_t* p = (xp_awk_nde_print_t*)nde; + xp_char_t* out = XP_NULL; + const xp_char_t* dst; xp_awk_val_t* v; + xp_awk_nde_t* np; + int extio_type, errnum, n; - if (p->out_type == XP_AWK_PRINT_PIPE) + static int __print_extio_map[] = { - xp_awk_val_t* out; - xp_char_t* dst; - int errnum, n; + /* the order should match the order of the + * XP_AWK_PRINT_XXX values in tree.h */ + XP_AWK_EXTIO_PIPE, + XP_AWK_EXTIO_COPROC, + XP_AWK_EXTIO_FILE, + XP_AWK_EXTIO_FILE, + XP_AWK_EXTIO_CONSOLE + }; - out = __eval_expression (run, p->out); + xp_assert ( + (p->out_type == XP_AWK_PRINT_PIPE && p->out != XP_NULL) || + (p->out_type == XP_AWK_PRINT_COPROC && p->out != XP_NULL) || + (p->out_type == XP_AWK_PRINT_FILE && p->out != XP_NULL) || + (p->out_type == XP_AWK_PRINT_FILE_APPEND && p->out != XP_NULL) || + (p->out_type == XP_AWK_PRINT_CONSOLE && p->out == XP_NULL)); + + xp_assert (p->out_type >= 0 && p->out_type < xp_countof(__print_extio_map)); + extio_type = __print_extio_map[p->out_type]; + + if (p->out != XP_NULL) + { + v = __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_refupval (v); + out = xp_awk_valtostr (v, &errnum, XP_NULL); + if (out == XP_NULL) { - xp_awk_refdownval (run, out); + xp_awk_refdownval (run, v); PANIC_I (run, errnum); } - xp_awk_refdownval (run, out); + xp_awk_refdownval (run, v); + } - if (p->args == XP_NULL) + dst = (out == XP_NULL)? XP_T(""): out; + + if (p->args == XP_NULL) + { + /* TODO: get $0 ans use it for v */ + v = xp_awk_makestrval0 (XP_T("\n")); + if (v == 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); - } + if (out != XP_NULL) xp_free (out); + PANIC_I (run, XP_AWK_ENOMEM); + } + xp_awk_refupval (v); + n = xp_awk_writeextio (run, extio_type, dst, v, &errnum); + if (n < 0 && errnum != XP_AWK_ENOERR) + { + if (out != XP_NULL) xp_free (out); xp_awk_refdownval (run, v); + PANIC_I (run, errnum); } - 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_CONSOLE) - { - xp_awk_nde_t* np; - int n, errnum; - - xp_assert (p->out == XP_NULL); - - for (np = p->args; np != XP_NULL; np = np->next) - { - v = __eval_expression (run, np); - if (v == XP_NULL) return -1; - xp_awk_refupval (v); - - /* console has the fixed name */ - n = xp_awk_writeextio ( - run, XP_AWK_EXTIO_CONSOLE, XP_T("console"), v, &errnum); - if (n < 0 && errnum != XP_AWK_ENOERR) - { - xp_awk_refdownval (run, v); - PANIC_I (run, errnum); - } - - xp_awk_refdownval (run, v); - } - - return 0; - } - 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; + xp_awk_refdownval (run, v); + /* TODO: how to handle n == -1 && errnum == XP_AWK_ENOERR. that is the user handler returned an error... */ } else { - xp_assert (!"should never happen - wrong out_type for print"); - PANIC_I (run, XP_AWK_EINTERNAL); + for (np = p->args; np != XP_NULL; np = np->next) + { + v = __eval_expression (run, np); + if (v == XP_NULL) + { + if (out != XP_NULL) xp_free (out); + return -1; + } + xp_awk_refupval (v); + + n = xp_awk_writeextio ( + run, extio_type, dst, v, &errnum); + if (n < 0 && errnum != XP_AWK_ENOERR) + { + if (out != XP_NULL) xp_free (out); + xp_awk_refdownval (run, v); + PANIC_I (run, errnum); + } + xp_awk_refdownval (run, v); + + /* TODO: how to handle n == -1 && errnum == XP_AWK_ENOERR. that is the user handler returned an error... */ + } + + /* TODO: predefine the new line string + * for performance improvement*/ + v = xp_awk_makestrval (XP_T("\n"), 1); + if (v == XP_NULL) + { + if (out != XP_NULL) xp_free (out); + PANIC_I (run, XP_AWK_ENOMEM); + } + xp_awk_refupval (v); + + n = xp_awk_writeextio ( + run, extio_type, dst, v, &errnum); + if (n < 0 && errnum != XP_AWK_ENOERR) + { + if (out != XP_NULL) xp_free (out); + xp_awk_refdownval (run, v); + PANIC_I (run, errnum); + } + xp_awk_refdownval (run, v); + + /* TODO: how to handle n == -1 && errnum == XP_AWK_ENOERR. that is the user handler returned an error... */ } + + if (out != XP_NULL) xp_free (out); + return 0; } static xp_awk_val_t* __eval_expression (xp_awk_run_t* run, xp_awk_nde_t* nde) diff --git a/ase/awk/tree.h b/ase/awk/tree.h index a560d8c3..9a3920a4 100644 --- a/ase/awk/tree.h +++ b/ase/awk/tree.h @@ -1,5 +1,5 @@ /* - * $Id: tree.h,v 1.49 2006-06-25 15:26:57 bacon Exp $ + * $Id: tree.h,v 1.50 2006-06-26 15:09:28 bacon Exp $ */ #ifndef _XP_AWK_TREE_H_ @@ -67,6 +67,8 @@ enum enum { + /* the order of these values match __print_extio_map in run.c */ + XP_AWK_PRINT_PIPE, XP_AWK_PRINT_COPROC, XP_AWK_PRINT_FILE, diff --git a/ase/awk/val.c b/ase/awk/val.c index e760d63a..8412c848 100644 --- a/ase/awk/val.c +++ b/ase/awk/val.c @@ -1,5 +1,5 @@ /* - * $Id: val.c,v 1.31 2006-06-21 11:44:55 bacon Exp $ + * $Id: val.c,v 1.32 2006-06-26 15:09:28 bacon Exp $ */ #include @@ -78,6 +78,11 @@ xp_awk_val_t* xp_awk_makerealval (xp_awk_run_t* run, xp_real_t v) return (xp_awk_val_t*)val; } +xp_awk_val_t* xp_awk_makestrval0 (const xp_char_t* str) +{ + return xp_awk_makestrval (str, xp_strlen(str)); +} + xp_awk_val_t* xp_awk_makestrval (const xp_char_t* str, xp_size_t len) { xp_awk_val_str_t* val; @@ -432,7 +437,7 @@ xp_char_t* xp_awk_valtostr (xp_awk_val_t* v, int* errnum, xp_str_t* buf) /* TODO: process more value types */ - *errnum = XP_AWK_EWRONGINDEX; + *errnum = XP_AWK_EVALTYPE; return XP_NULL; } diff --git a/ase/awk/val.h b/ase/awk/val.h index f50aae22..c4418f14 100644 --- a/ase/awk/val.h +++ b/ase/awk/val.h @@ -1,5 +1,5 @@ /* - * $Id: val.h,v 1.24 2006-06-21 11:44:55 bacon Exp $ + * $Id: val.h,v 1.25 2006-06-26 15:09:28 bacon Exp $ */ #ifndef _XP_AWK_VAL_H_ @@ -96,6 +96,7 @@ extern xp_awk_val_t* xp_awk_val_nil; xp_awk_val_t* xp_awk_makeintval (xp_awk_run_t* run, xp_long_t v); xp_awk_val_t* xp_awk_makerealval (xp_awk_run_t* run, xp_real_t v); +xp_awk_val_t* xp_awk_makestrval0 (const xp_char_t* str); xp_awk_val_t* xp_awk_makestrval (const xp_char_t* str, xp_size_t len); xp_awk_val_t* xp_awk_makestrval2 ( const xp_char_t* str1, xp_size_t len1, diff --git a/ase/test/awk/awk.c b/ase/test/awk/awk.c index a2d4c8db..93f79e7c 100644 --- a/ase/test/awk/awk.c +++ b/ase/test/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c,v 1.42 2006-06-25 15:26:57 bacon Exp $ + * $Id: awk.c,v 1.43 2006-06-26 15:09:28 bacon Exp $ */ #include @@ -271,6 +271,7 @@ static xp_ssize_t process_extio_console ( case XP_AWK_IO_CLOSE: { /* TODO: CloseConsole in GUI APPLICATION */ + return 0; } case XP_AWK_IO_READ: @@ -282,8 +283,8 @@ static xp_ssize_t process_extio_console ( case XP_AWK_IO_WRITE: { - if (_fputts (data, /*size,*/ (FILE*)epa->handle) == XP_NULL) - return 0; + /* TODO: how to return error or 0 */ + _fputts (data, /*size,*/ (FILE*)epa->handle); return size; }