diff --git a/ase/awk/awk.c b/ase/awk/awk.c index 1d66bda9..c757ce94 100644 --- a/ase/awk/awk.c +++ b/ase/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c,v 1.60 2006-07-26 05:19:44 bacon Exp $ + * $Id: awk.c,v 1.61 2006-07-28 10:34:21 bacon Exp $ */ #include @@ -170,7 +170,7 @@ int xp_awk_attsrc (xp_awk_t* awk, xp_awk_io_t handler, void* arg) if (xp_awk_detsrc(awk) == -1) return -1; xp_assert (awk->srcio == XP_NULL); - if (handler (XP_AWK_IO_OPEN, 0, arg, XP_NULL, 0) == -1) + if (handler (XP_AWK_IO_OPEN, arg, XP_NULL, 0) == -1) { awk->errnum = XP_AWK_ESRCINOPEN; return -1; @@ -193,8 +193,7 @@ int xp_awk_detsrc (xp_awk_t* awk) { xp_ssize_t n; - n = awk->srcio ( - XP_AWK_IO_CLOSE, 0, awk->srcio_arg, XP_NULL, 0); + n = awk->srcio (XP_AWK_IO_CLOSE, awk->srcio_arg, XP_NULL, 0); if (n == -1) { awk->errnum = XP_AWK_ESRCINCLOSE; diff --git a/ase/awk/awk.h b/ase/awk/awk.h index 04864f13..b74c2a86 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h,v 1.82 2006-07-27 16:50:28 bacon Exp $ + * $Id: awk.h,v 1.83 2006-07-28 10:34:21 bacon Exp $ */ #ifndef _XP_AWK_AWK_H_ @@ -14,13 +14,14 @@ typedef struct xp_awk_extio_t xp_awk_extio_t; typedef struct xp_awk_rex_t xp_awk_rex_t; typedef xp_ssize_t (*xp_awk_io_t) ( - int cmd, int opt, void* arg, xp_char_t* data, xp_size_t count); + int cmd, void* arg, xp_char_t* data, xp_size_t count); struct xp_awk_extio_t { - int type; - + int type; /* console, file, coproc, pipe */ + int mode; /* read, write, etc */ xp_char_t* name; + void* handle; /* input buffer */ diff --git a/ase/awk/extio.c b/ase/awk/extio.c index 482d7177..6eb710a8 100644 --- a/ase/awk/extio.c +++ b/ase/awk/extio.c @@ -1,5 +1,5 @@ /* - * $Id: extio.c,v 1.20 2006-07-27 16:50:28 bacon Exp $ + * $Id: extio.c,v 1.21 2006-07-28 10:34:21 bacon Exp $ */ #include @@ -19,6 +19,64 @@ enum __MASK_CLEAR = 0x00FF }; +static int __in_type_map[] = +{ + /* the order should match the order of the + * XP_AWK_IN_XXX values in tree.h */ + XP_AWK_EXTIO_PIPE, + XP_AWK_EXTIO_COPROC, + XP_AWK_EXTIO_FILE, + XP_AWK_EXTIO_CONSOLE +}; + +static int __in_mode_map[] = +{ + /* the order should match the order of the + * XP_AWK_IN_XXX values in tree.h */ + XP_AWK_IO_PIPE_READ, + 0, + XP_AWK_IO_FILE_READ, + XP_AWK_IO_CONSOLE_READ +}; + +static int __in_mask_map[] = +{ + __MASK_READ, + __MASK_RDWR, + __MASK_READ, + __MASK_READ +}; + +static int __out_type_map[] = +{ + /* the order should match the order of the + * XP_AWK_OUT_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 +}; + +static int __out_mode_map[] = +{ + /* the order should match the order of the + * XP_AWK_OUT_XXX values in tree.h */ + XP_AWK_IO_PIPE_WRITE, + 0, + XP_AWK_IO_FILE_WRITE, + XP_AWK_IO_FILE_APPEND, + XP_AWK_IO_CONSOLE_WRITE +}; + +static int __out_mask_map[] = +{ + __MASK_WRITE, + __MASK_RDWR, + __MASK_WRITE, + __MASK_WRITE, + __MASK_WRITE +}; int xp_awk_readextio ( xp_awk_run_t* run, int in_type, @@ -26,43 +84,15 @@ int xp_awk_readextio ( { xp_awk_extio_t* p = run->extio; xp_awk_io_t handler; - int extio_type, extio_opt, extio_mask; - - static int __in_type_map[] = - { - /* the order should match the order of the - * XP_AWK_IN_XXX values in tree.h */ - XP_AWK_EXTIO_PIPE, - XP_AWK_EXTIO_COPROC, - XP_AWK_EXTIO_FILE, - XP_AWK_EXTIO_CONSOLE - }; - - static int __in_opt_map[] = - { - /* the order should match the order of the - * XP_AWK_IN_XXX values in tree.h */ - XP_AWK_IO_PIPE_READ, - 0, - XP_AWK_IO_FILE_READ, - XP_AWK_IO_CONSOLE_READ - }; - - static int __in_mask_map[] = - { - __MASK_READ, - __MASK_RDWR, - __MASK_READ, - __MASK_READ - }; + int extio_type, extio_mode, extio_mask, n; xp_assert (in_type >= 0 && in_type <= xp_countof(__in_type_map)); - xp_assert (in_type >= 0 && in_type <= xp_countof(__in_opt_map)); + xp_assert (in_type >= 0 && in_type <= xp_countof(__in_mode_map)); xp_assert (in_type >= 0 && in_type <= xp_countof(__in_mask_map)); - /* translate the in_type into the relevant extio type and option */ + /* translate the in_type into the relevant extio type and mode */ extio_type = __in_type_map[in_type]; - extio_opt = __in_opt_map[in_type]; + extio_mode = __in_mode_map[in_type]; extio_mask = __in_mask_map[in_type]; handler = run->awk->extio[extio_type]; @@ -98,6 +128,7 @@ int xp_awk_readextio ( } p->type = (extio_type | extio_mask); + p->mode = extio_mode; p->handle = XP_NULL; p->in.buf[0] = XP_C('\0'); @@ -107,7 +138,8 @@ int xp_awk_readextio ( p->next = XP_NULL; - if (handler (XP_AWK_IO_OPEN, extio_opt, p, XP_NULL, 0) == -1) + n = handler (XP_AWK_IO_OPEN, p, XP_NULL, 0); + if (n == -1) { xp_free (p->name); xp_free (p); @@ -117,21 +149,16 @@ int xp_awk_readextio ( 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; + + /* n == 0 indicates that it has reached the end of input. + * the user io handler can return 0 for the open request + * if it doesn't have any files to open. One advantage + * of doing this would be that you can skip the entire + * pattern-block matching and exeuction. */ + if (n == 0) return 0; } /* read a line */ @@ -151,8 +178,8 @@ int xp_awk_readextio ( break; } - n = handler (XP_AWK_IO_READ, 0, - p, p->in.buf, xp_countof(p->in.buf)); + n = handler (XP_AWK_IO_READ, p, + p->in.buf, xp_countof(p->in.buf)); if (n == -1) { /* handler error. getline should return -1 */ @@ -192,46 +219,15 @@ int xp_awk_writeextio ( xp_awk_extio_t* p = run->extio; xp_awk_io_t handler; xp_str_t buf; - int extio_type, extio_opt, extio_mask; - - static int __out_type_map[] = - { - /* the order should match the order of the - * XP_AWK_OUT_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 - }; - - static int __out_opt_map[] = - { - /* the order should match the order of the - * XP_AWK_OUT_XXX values in tree.h */ - XP_AWK_IO_PIPE_WRITE, - 0, - XP_AWK_IO_FILE_WRITE, - XP_AWK_IO_FILE_APPEND, - XP_AWK_IO_CONSOLE_WRITE - }; - - static int __out_mask_map[] = - { - __MASK_WRITE, - __MASK_RDWR, - __MASK_WRITE, - __MASK_WRITE, - __MASK_WRITE - }; + int extio_type, extio_mode, extio_mask, n; xp_assert (out_type >= 0 && out_type <= xp_countof(__out_type_map)); - xp_assert (out_type >= 0 && out_type <= xp_countof(__out_opt_map)); + xp_assert (out_type >= 0 && out_type <= xp_countof(__out_mode_map)); xp_assert (out_type >= 0 && out_type <= xp_countof(__out_mask_map)); - /* translate the out_type into the relevant extio type and option */ + /* translate the out_type into the relevant extio type and mode */ extio_type = __out_type_map[out_type]; - extio_opt = __out_opt_map[out_type]; + extio_mode = __out_mode_map[out_type]; extio_mask = __out_mask_map[out_type]; handler = run->awk->extio[extio_type]; @@ -297,10 +293,12 @@ int xp_awk_writeextio ( } p->type = (extio_type | extio_mask); + p->mode = extio_mode; p->handle = XP_NULL; p->next = XP_NULL; - if (handler (XP_AWK_IO_OPEN, extio_opt, p, XP_NULL, 0) == -1) + n = handler (XP_AWK_IO_OPEN, p, XP_NULL, 0); + if (n == -1) { xp_free (p->name); xp_free (p); @@ -311,26 +309,28 @@ int xp_awk_writeextio ( return -1; } - if (p->handle == XP_NULL) - { - xp_free (p->name); - xp_free (p); - xp_str_close (&buf); - - /* 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; - return -1; - } - /* chain it */ p->next = run->extio; run->extio = p; + + /* read the comment in xp_awk_readextio */ + if (n == 0) return 0; } - if (handler (XP_AWK_IO_WRITE, 0, - p, XP_STR_BUF(&buf), XP_STR_LEN(&buf)) == 0) +/* TODO: */ +/* TODO: */ +/* TODO: if write handler returns less than the request, loop */ +/* TODO: */ +/* TODO: */ + n = handler (XP_AWK_IO_WRITE, p, + XP_STR_BUF(&buf), XP_STR_LEN(&buf)); + if (n == -1) + { + xp_str_close (&buf); + return -1; + } + + if (n == 0) { xp_str_close (&buf); return 0; @@ -340,6 +340,55 @@ int xp_awk_writeextio ( return 1; } +int xp_awk_nextextio_read ( + xp_awk_run_t* run, int in_type, const xp_char_t* name, int* errnum) +{ + xp_awk_extio_t* p = run->extio; + xp_awk_io_t handler; + int extio_type, extio_mode, extio_mask, n; + + xp_assert (in_type >= 0 && in_type <= xp_countof(__in_type_map)); + xp_assert (in_type >= 0 && in_type <= xp_countof(__in_mode_map)); + xp_assert (in_type >= 0 && in_type <= xp_countof(__in_mask_map)); + + /* translate the in_type into the relevant extio type and mode */ + extio_type = __in_type_map[in_type]; + extio_mode = __in_mode_map[in_type]; + extio_mask = __in_mask_map[in_type]; + + handler = run->awk->extio[extio_type]; + 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 == (extio_type | extio_mask) && + xp_strcmp(p->name,name) == 0) break; + p = p->next; + } + + if (p == XP_NULL) + { + /* something is totally wrong */ + *errnum = XP_AWK_EINTERNAL; + return -1; + } + + n = handler (XP_AWK_IO_NEXT, p, XP_NULL, 0); + if (n == -1) + { + /* TODO: is this errnum correct? */ + *errnum = XP_AWK_ENOERR; + return -1; + } + + return n; +} + 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; @@ -357,7 +406,7 @@ int xp_awk_closeextio (xp_awk_run_t* run, const xp_char_t* name, int* errnum) { /* TODO: io command should not be XP_AWK_IO_CLOSE * it should be more generic form than this... */ - if (handler (XP_AWK_IO_CLOSE, 0, p, XP_NULL, 0) == -1) + if (handler (XP_AWK_IO_CLOSE, p, XP_NULL, 0) == -1) { /* this is not a run-time error.*/ *errnum = XP_AWK_ENOERR; @@ -397,7 +446,7 @@ void xp_awk_clearextio (xp_awk_run_t* run) { /* TODO: io command should not be XP_AWK_INPUT_CLOSE * it should be more generic form than this... */ - n = handler (XP_AWK_IO_CLOSE, 0, run->extio, XP_NULL, 0); + n = handler (XP_AWK_IO_CLOSE, run->extio, XP_NULL, 0); if (n == -1) { /* TODO: diff --git a/ase/awk/extio.h b/ase/awk/extio.h index acd61f84..35134686 100644 --- a/ase/awk/extio.h +++ b/ase/awk/extio.h @@ -1,5 +1,5 @@ /* - * $Id: extio.h,v 1.5 2006-06-28 14:19:01 bacon Exp $ + * $Id: extio.h,v 1.6 2006-07-28 10:34:22 bacon Exp $ */ #ifndef _XP_AWK_EXTIO_H_ @@ -21,6 +21,14 @@ int xp_awk_writeextio ( xp_awk_run_t* run, int out_type, const xp_char_t* name, xp_awk_val_t* v, int* errnum); +int xp_awk_nextextio_read ( + xp_awk_run_t* run, int in_type, const xp_char_t* name, int* errnum); + +/* TODO: +int xp_awk_nextextio_write ( + xp_awk_run_t* run, int out_type, const xp_char_t* name, 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 03cdae41..5f9a3830 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c,v 1.142 2006-07-26 16:43:35 bacon Exp $ + * $Id: parse.c,v 1.143 2006-07-28 10:34:22 bacon Exp $ */ #include @@ -3740,8 +3740,9 @@ static int __get_char (xp_awk_t* awk) */ if (awk->lex.buf_pos >= awk->lex.buf_len) { - n = awk->srcio (XP_AWK_IO_READ, 0, - awk->srcio_arg, awk->lex.buf, xp_countof(awk->lex.buf)); + n = awk->srcio ( + XP_AWK_IO_READ, awk->srcio_arg, + awk->lex.buf, xp_countof(awk->lex.buf)); if (n == -1) { awk->errnum = XP_AWK_ESRCINDATA; diff --git a/ase/awk/run.c b/ase/awk/run.c index d4276319..8205b57a 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c,v 1.141 2006-07-27 16:50:28 bacon Exp $ + * $Id: run.c,v 1.142 2006-07-28 10:34:22 bacon Exp $ */ #include @@ -1161,17 +1161,34 @@ static int __run_next (xp_awk_run_t* run, xp_awk_nde_next_t* nde) static int __run_nextfile (xp_awk_run_t* run, xp_awk_nde_nextfile_t* nde) { -// xp_ssize_t n; +/* TODO: trigger an error if "nextfile" is called from BEGIN or END */ +/* TODO: some extentions such as nextfile "in/out"; + * what about awk -i in1,in2,in3 -o out1,out2,out3 ? + */ + int n, errnum; - /* TODO: implement this properly */ - /* TODO: how to pass opt properly for IO_NEXT??? -> READ? WRITE? */ -/* - n = run->txtio (XP_AWK_IO_NEXT, 0, run->txtio_arg, XP_NULL, 0); - if (n == -1) PANIC_I (run, XP_AWK_ETXTINNEXT); - return (n == -1)? -1: 0; -*/ -xp_printf (XP_T("nextfile not implemented....\n")); - return -1; + n = xp_awk_nextextio_read ( + run, XP_AWK_IN_CONSOLE, XP_T(""), &errnum); + if (n == -1) + { + if (errnum == XP_AWK_ENOERR) + PANIC_I (run, XP_AWK_ETXTINNEXT); + else + PANIC_I (run, errnum); + } + + if (n == 0) + { + /* no more input file */ + run->exit_level = EXIT_GLOBAL; + return 0; + } + +/* TODO: update FILENAME, ARGIND. reset FNR to 1. + * some significant changes will be required to do this */ +/* Consider using FILENAME_IN and FILENAME_OUT to accomplish nextfile in/out */ + run->exit_level = EXIT_NEXT; + return 0; } static int __run_delete (xp_awk_run_t* run, xp_awk_nde_delete_t* nde) @@ -3575,10 +3592,16 @@ static xp_awk_val_t* __eval_getline (xp_awk_run_t* run, xp_awk_nde_t* nde) n = xp_awk_readextio (run, p->in_type, dst, &buf, &errnum); if (in != XP_NULL) xp_free (in); - if (n < 0 && errnum != XP_AWK_ENOERR) + if (n < 0) { - xp_str_close (&buf); - PANIC (run, errnum); + if (errnum != XP_AWK_ENOERR) + { + xp_str_close (&buf); + PANIC (run, errnum); + } + + /* if errnum == XP_AWK_ENOERR, make getline return -1 */ + n = -1; } if (n > 0) diff --git a/ase/test/awk/awk.c b/ase/test/awk/awk.c index 579291ec..32df72b3 100644 --- a/ase/test/awk/awk.c +++ b/ase/test/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c,v 1.54 2006-07-27 16:50:29 bacon Exp $ + * $Id: awk.c,v 1.55 2006-07-28 10:34:22 bacon Exp $ */ #include @@ -13,6 +13,7 @@ #ifndef __STAND_ALONE #include #include + #include #include #include #else @@ -40,6 +41,10 @@ #include #define xp_assert assert + + #include + #define xp_malloc malloc + #define xp_free free #endif #if defined(_WIN32) && defined(__STAND_ALONE) && defined(_DEBUG) @@ -57,12 +62,6 @@ struct src_io FILE* input_handle; }; -struct data_io -{ - const char* input_file; - FILE* input_handle; -}; - static FILE* fopen_t (const xp_char_t* path, const xp_char_t* mode) { #ifdef _WIN32 @@ -131,7 +130,7 @@ static FILE* popen_t (const xp_char_t* cmd, const xp_char_t* mode) #endif static xp_ssize_t process_source ( - int cmd, int opt, void* arg, xp_char_t* data, xp_size_t size) + int cmd, void* arg, xp_char_t* data, xp_size_t size) { struct src_io* src_io = (struct src_io*)arg; xp_char_t c; @@ -143,7 +142,7 @@ static xp_ssize_t process_source ( if (src_io->input_file == XP_NULL) return 0; src_io->input_handle = fopen_t (src_io->input_file, XP_T("r")); if (src_io->input_handle == NULL) return -1; - return 0; + return 1; } case XP_AWK_IO_CLOSE: @@ -182,7 +181,7 @@ static xp_ssize_t process_source ( } static xp_ssize_t process_extio_pipe ( - int cmd, int opt, void* arg, xp_char_t* data, xp_size_t size) + int cmd, void* arg, xp_char_t* data, xp_size_t size) { xp_awk_extio_t* epa = (xp_awk_extio_t*)arg; @@ -193,16 +192,16 @@ static xp_ssize_t process_extio_pipe ( FILE* handle; const xp_char_t* mode; - if (opt == XP_AWK_IO_PIPE_READ) + if (epa->mode == XP_AWK_IO_PIPE_READ) mode = XP_T("r"); - else if (opt == XP_AWK_IO_PIPE_WRITE) + else if (epa->mode == XP_AWK_IO_PIPE_WRITE) mode = XP_T("w"); else return -1; /* TODO: any way to set the error number? */ xp_printf (XP_TEXT("opending %s of type %d (pipe)\n"), epa->name, epa->type); handle = popen_t (epa->name, mode); if (handle == NULL) return -1; epa->handle = (void*)handle; - return 0; + return 1; } case XP_AWK_IO_CLOSE: @@ -240,7 +239,7 @@ xp_printf (XP_TEXT("closing %s of type (pipe) %d\n"), epa->name, epa->type); } static xp_ssize_t process_extio_file ( - int cmd, int opt, void* arg, xp_char_t* data, xp_size_t size) + int cmd, void* arg, xp_char_t* data, xp_size_t size) { xp_awk_extio_t* epa = (xp_awk_extio_t*)arg; @@ -251,11 +250,11 @@ static xp_ssize_t process_extio_file ( FILE* handle; const xp_char_t* mode; - if (opt == XP_AWK_IO_FILE_READ) + if (epa->mode == XP_AWK_IO_FILE_READ) mode = XP_T("r"); - else if (opt == XP_AWK_IO_FILE_WRITE) + else if (epa->mode == XP_AWK_IO_FILE_WRITE) mode = XP_T("w"); - else if (opt == XP_AWK_IO_FILE_APPEND) + else if (epa->mode == XP_AWK_IO_FILE_APPEND) mode = XP_T("a"); else return -1; /* TODO: any way to set the error number? */ @@ -263,7 +262,7 @@ xp_printf (XP_TEXT("opending %s of type %d (file)\n"), epa->name, epa->type); handle = fopen_t (epa->name, mode); if (handle == NULL) return -1; epa->handle = (void*)handle; - return 0; + return 1; } case XP_AWK_IO_CLOSE: @@ -298,129 +297,188 @@ xp_printf (XP_TEXT("closing %s of type %d (file)\n"), epa->name, epa->type); return -1; } +static int open_extio_console (xp_awk_extio_t* epa); +static int close_extio_console (xp_awk_extio_t* epa); +static int next_extio_console (xp_awk_extio_t* epa); + +static const xp_char_t* infiles[] = +{ + XP_T(""), + XP_T("awk.in"), + XP_NULL +}; + +static xp_size_t infile_no = 0; static xp_ssize_t process_extio_console ( - int cmd, int opt, void* arg, xp_char_t* data, xp_size_t size) + int cmd, void* arg, xp_char_t* data, xp_size_t size) { xp_awk_extio_t* epa = (xp_awk_extio_t*)arg; - static const xp_char_t* infiles[] = + if (cmd == XP_AWK_IO_OPEN) { - XP_T(""), - //XP_T("awk.in"), - XP_NULL - }; - - static xp_size_t infile_no = 0; - - switch (cmd) + return open_extio_console (epa); + } + else if (cmd == XP_AWK_IO_CLOSE) { - case XP_AWK_IO_OPEN: + return close_extio_console (epa); + } + else if (cmd == XP_AWK_IO_READ) + { + while (fgets_t (data, size, epa->handle) == XP_NULL) { - /* TODO: OpenConsole in GUI APPLICATION */ - /* opt: XP_AWK_IO_CONSOLE_READ, - * XP_AWK_IO_CONSOLE_WRITE */ - - /* epa->name is always empty for console */ - xp_assert (epa->name[0] == XP_T('\0')); - -xp_printf (XP_TEXT("opening console of type %x\n"), epa->type); - - if (opt == XP_AWK_IO_CONSOLE_READ) + /* it has reached the end of the current file. + * open the next file if available */ + if (infiles[infile_no] == XP_NULL) { - if (infiles[infile_no] == XP_NULL) + /* no more input console */ + + /* is this correct??? */ + /* + if (epa->handle != XP_NULL && + epa->handle != stdin && + epa->handle != stdout && + epa->handle != stderr) fclose (epa->handle); + epa->handle = XP_NULL; + */ + + return 0; + } + + if (infiles[infile_no][0] == XP_T('\0')) + { + if (epa->handle != XP_NULL && + epa->handle != stdin && + epa->handle != stdout && + epa->handle != stderr) fclose (epa->handle); + epa->handle = stdin; + } + else + { + FILE* fp = fopen_t (infiles[infile_no], XP_T("r")); + if (fp == XP_NULL) { - /* no input file */ -xp_printf (XP_TEXT("failed to open console of type %x - no more input file\n"), epa->type); +xp_printf (XP_TEXT("failed to open the next console of type %x - fopen failure\n"), epa->type); return -1; } - else if (infiles[infile_no][0] == XP_T('\0')) - { -xp_printf (XP_T(" console(r) - \n")); - epa->handle = stdin; - } - else - { -xp_printf (XP_T(" console(r) - %s\n"), infiles[infile_no]); - epa->handle = fopen_t (infiles[infile_no], XP_T("r")); - if (epa->handle == XP_NULL) - { -xp_printf (XP_TEXT("failed to open console of type %x - fopen failure\n"), epa->type); - return -1; - } - } - infile_no++; - } - else if (opt == XP_AWK_IO_CONSOLE_WRITE) - { -xp_printf (XP_T(" console(w) - \n")); - epa->handle = stdout; - } - else return -1; + if (epa->handle != XP_NULL && + epa->handle != stdin && + epa->handle != stdout && + epa->handle != stderr) fclose (epa->handle); - return 0; - } - - case XP_AWK_IO_CLOSE: - { -xp_printf (XP_TEXT("closing [%s] of type %x (console)\n"), epa->name, epa->type); - /* TODO: CloseConsole in GUI APPLICATION */ - return 0; - } - - case XP_AWK_IO_READ: - { - while (fgets_t (data, size, (FILE*)epa->handle) == XP_NULL) - { - /* it has reached the end of the current file. - * open the next file if available */ - if (infiles[infile_no] == XP_NULL) - { - /* no more input console */ - return 0; - } - - if (epa->handle != stdin) fclose (epa->handle); - if (infiles[infile_no][0] == XP_T('\0')) - { - epa->handle = stdin; - } - else - { - epa->handle = fopen_t (infiles[infile_no], XP_T("r")); - if (epa->handle == XP_NULL) - { -xp_printf (XP_TEXT("failed to open the next console of type %x - fopen failure\n"), epa->type); - return -1; - } - } - - infile_no++; +xp_printf (XP_TEXT("open the next console [%s]\n"), infiles[infile_no]); + epa->handle = fp; } - return xp_strlen(data); - } - - case XP_AWK_IO_WRITE: - { - /* TODO: how to return error or 0 */ - fputs_t (data, /*size,*/ (FILE*)epa->handle); - /*fputs_t (data, stdout);*/ - /*MessageBox (NULL, data, data, MB_OK);*/ - return size; - } - - case XP_AWK_IO_NEXT: - { - return -1; + infile_no++; } + return xp_strlen(data); + } + else if (cmd == XP_AWK_IO_WRITE) + { + /* TODO: how to return error or 0 */ + fputs_t (data, /*size,*/ (FILE*)epa->handle); + /*MessageBox (NULL, data, data, MB_OK);*/ + return size; + } + else if (cmd == XP_AWK_IO_NEXT) + { + return next_extio_console (epa); } return -1; } +static int open_extio_console (xp_awk_extio_t* epa) +{ + /* TODO: OpenConsole in GUI APPLICATION */ + + /* epa->name is always empty for console */ + xp_assert (epa->name[0] == XP_T('\0')); + +xp_printf (XP_TEXT("opening console[%s] of type %x\n"), epa->name, epa->type); + + if (epa->mode == XP_AWK_IO_CONSOLE_READ) + { + if (infiles[infile_no] == XP_NULL) + { + /* no more input file */ +xp_printf (XP_TEXT("console - no more file\n"));; + return 0; + } + + if (infiles[infile_no][0] == XP_T('\0')) + { +xp_printf (XP_T(" console(r) - \n")); + epa->handle = stdin; + } + else + { + /* a temporary variable fp is used here not to change + * any fields of epa when the open operation fails */ + FILE* fp = fopen_t (infiles[infile_no], XP_T("r")); + if (fp == XP_NULL) + { +xp_printf (XP_TEXT("failed to open console of type %x - fopen failure\n"), epa->type); + return -1; + } + +xp_printf (XP_T(" console(r) - %s\n"), infiles[infile_no]); + epa->handle = fp; + } + + infile_no++; + return 1; + } + else if (epa->mode == XP_AWK_IO_CONSOLE_WRITE) + { +xp_printf (XP_T(" console(w) - \n")); + epa->handle = stdout; + return 1; + } + + return -1; +} + +static int close_extio_console (xp_awk_extio_t* epa) +{ +xp_printf (XP_TEXT("closing console of type %x\n"), epa->type); + + if (epa->handle != XP_NULL && + epa->handle != stdin && + epa->handle != stdout && + epa->handle != stderr) + { + fclose (epa->handle); + } + + /* TODO: CloseConsole in GUI APPLICATION */ + return 0; +} + +static int next_extio_console (xp_awk_extio_t* epa) +{ + int n; + FILE* fp = epa->handle; +xp_printf (XP_TEXT("switching console[%s] of type %x\n"), epa->name, epa->type); + + n = open_extio_console(epa); + if (n == -1) return -1; + + if (n == 0) + { + /* if there is no more file, keep the previous handle */ + return 0; + } + + if (fp != XP_NULL && fp != stdin && + fp != stdout && fp != stderr) fclose (fp); + + return n; +} + #if defined(__STAND_ALONE) && !defined(_WIN32) static int __main (int argc, char* argv[]) #else @@ -428,7 +486,6 @@ static int __main (int argc, xp_char_t* argv[]) #endif { xp_awk_t* awk; - struct data_io data_io = { "awk.in", NULL }; struct src_io src_io = { NULL, NULL }; if ((awk = xp_awk_open()) == XP_NULL)