From 81b3d369e8a8bbb3131808bd7962ef9fc0657152 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Fri, 28 Aug 2009 06:52:20 +0000 Subject: [PATCH] implemented partial closing for rwpipe --- qse/doc/page/awk.doc | 2 +- qse/include/qse/awk/awk.h | 27 +++++++------ qse/lib/awk/StdAwk.cpp | 23 ++++++++++- qse/lib/awk/fnc.c | 4 +- qse/lib/awk/rio.c | 83 +++++++++++++++++++++++++++------------ qse/lib/awk/std.c | 22 ++++++++++- 6 files changed, 116 insertions(+), 45 deletions(-) diff --git a/qse/doc/page/awk.doc b/qse/doc/page/awk.doc index aec4261e..b5ff923a 100644 --- a/qse/doc/page/awk.doc +++ b/qse/doc/page/awk.doc @@ -60,7 +60,7 @@ BEGIN { print "11" || "sort"; #close the input as sort emits when the input is closed close ("sort", "r"); - while (("sort" || getline x) > 0) print x; + while (("sort" || getline x) > 0) print "xx:", x; } @endcode diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index 6020154c..c5bead83 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h 270 2009-08-26 12:59:08Z hyunghwan.chung $ + * $Id: awk.h 271 2009-08-27 12:52:20Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -351,11 +351,13 @@ enum qse_awk_rio_mode_t }; typedef enum qse_awk_rio_mode_t qse_awk_rio_mode_t; -enum qse_awk_rio_close_opt_t +enum qse_awk_rio_rwcopt_t { - QSE_AWK_RIO_CLOSE_R = (1 << 0), - QSE_AWK_RIO_CLOSE_W = (1 << 1) + QSE_AWK_RIO_CLOSE_A = 0, + QSE_AWK_RIO_CLOSE_R = 1, + QSE_AWK_RIO_CLOSE_W = 2 }; +typedef enum qse_awk_rio_rwcopt_t qse_awk_rio_rwcopt_t; /** * The qse_awk_rio_arg_t defines the data structure passed to a runtime @@ -367,27 +369,28 @@ enum qse_awk_rio_close_opt_t typedef struct qse_awk_rio_arg_t qse_awk_rio_arg_t; struct qse_awk_rio_arg_t { - qse_awk_rio_mode_t mode; /**< [IN] I/O mode */ - qse_char_t* name; /**< [IN] name of I/O object */ - int copt; /**< [IN] closing option */ - void* handle; /**< [OUT] I/O handle set by a handler */ + qse_awk_rio_mode_t mode; /**< [IN] I/O mode */ + qse_char_t* name; /**< [IN] name of I/O object */ + qse_awk_rio_rwcopt_t rwcopt; /**< [IN] closing option for rwpipe */ + void* handle; /**< [OUT] I/O handle set by a handler */ /*-- from here down, internal use only --*/ int type; + int rwcstate; /** closing state for rwpipe */ struct { qse_char_t buf[2048]; qse_size_t pos; qse_size_t len; - qse_bool_t eof; - qse_bool_t eos; + int eof; + int eos; } in; struct { - qse_bool_t eof; - qse_bool_t eos; + int eof; + int eos; } out; struct qse_awk_rio_arg_t* next; diff --git a/qse/lib/awk/StdAwk.cpp b/qse/lib/awk/StdAwk.cpp index 71a24911..ceaa9f31 100644 --- a/qse/lib/awk/StdAwk.cpp +++ b/qse/lib/awk/StdAwk.cpp @@ -1,5 +1,5 @@ /* - * $Id: StdAwk.cpp 258 2009-08-19 14:04:15Z hyunghwan.chung $ + * $Id: StdAwk.cpp 271 2009-08-27 12:52:20Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -315,7 +315,26 @@ int StdAwk::openPipe (Pipe& io) int StdAwk::closePipe (Pipe& io) { - qse_pio_close ((qse_pio_t*)io.getHandle()); + qse_pio_t* pio = (qse_pio_t*)io.getHandle(); + if (io.getMode() == Awk::Pipe::RW) + { +#if 0 +TODO: support partial close.... + rwcopt = io.getCloseRW(); + if (rwcopt == Awk::Pipe::CLOSE_R) + { + qse_pio_end (pio, QSE_PIO_IN); + return 0; + } + else if (rwcopt == Awk::Pipe::CLOSE_W) + { + qse_pio_end (pio, QSE_PIO_OUT); + return 0; + } +#endif + } + + qse_pio_close (pio); return 0; } diff --git a/qse/lib/awk/fnc.c b/qse/lib/awk/fnc.c index 441aafe7..e6497916 100644 --- a/qse/lib/awk/fnc.c +++ b/qse/lib/awk/fnc.c @@ -1,5 +1,5 @@ /* - * $Id: fnc.c 270 2009-08-26 12:59:08Z hyunghwan.chung $ + * $Id: fnc.c 271 2009-08-27 12:52:20Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -310,7 +310,7 @@ static int fnc_close (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm) n = qse_awk_rtx_closeio (rtx, name, opt); /* failure to close is not a critical error. instead, that is - * flagged by the return value of close(). + * flagged by the return value of close(). if (n == -1 && rtx->errinf.num != QSE_AWK_EIONMNF) { if (a0->type != QSE_AWK_VAL_STR) diff --git a/qse/lib/awk/rio.c b/qse/lib/awk/rio.c index 58099c0d..9c421c63 100644 --- a/qse/lib/awk/rio.c +++ b/qse/lib/awk/rio.c @@ -1,5 +1,5 @@ /* - * $Id: rio.c 270 2009-08-26 12:59:08Z hyunghwan.chung $ + * $Id: rio.c 271 2009-08-27 12:52:20Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -148,14 +148,16 @@ int qse_awk_rtx_readio ( p->type = (io_type | io_mask); p->mode = io_mode; + p->rwcopt = QSE_AWK_RIO_CLOSE_A; p->handle = QSE_NULL; p->next = QSE_NULL; + p->rwcstate = 0; p->in.buf[0] = QSE_T('\0'); p->in.pos = 0; p->in.len = 0; - p->in.eof = QSE_FALSE; - p->in.eos = QSE_FALSE; + p->in.eof = 0; + p->in.eos = 0; qse_awk_rtx_seterrnum (run, QSE_AWK_ENOERR, QSE_NULL); @@ -187,12 +189,12 @@ int qse_awk_rtx_readio ( * entire pattern-block matching and exeuction. */ if (x == 0) { - p->in.eos = QSE_TRUE; + p->in.eos = 1; return 0; } } - if (p->in.eos) + if (p->in.eos) { /* no more streams. */ return 0; @@ -259,7 +261,7 @@ int qse_awk_rtx_readio ( if (n == 0) { - p->in.eof = QSE_TRUE; + p->in.eof = 1; if (QSE_STR_LEN(buf) == 0) ret = 0; else if (rs_len >= 2) @@ -507,11 +509,13 @@ int qse_awk_rtx_writeio_str ( p->type = (io_type | io_mask); p->mode = io_mode; + p->rwcopt = QSE_AWK_RIO_CLOSE_A; p->handle = QSE_NULL; p->next = QSE_NULL; + p->rwcstate = 0; - p->out.eof = QSE_FALSE; - p->out.eos = QSE_FALSE; + p->out.eof = 0; + p->out.eos = 0; qse_awk_rtx_seterrnum (run, QSE_AWK_ENOERR, QSE_NULL); n = handler (run, QSE_AWK_RIO_OPEN, p, QSE_NULL, 0); @@ -537,7 +541,7 @@ int qse_awk_rtx_writeio_str ( * entire pattern-block matching and exeuction. */ if (n == 0) { - p->out.eos = QSE_TRUE; + p->out.eos = 1; return 0; } } @@ -569,7 +573,7 @@ int qse_awk_rtx_writeio_str ( if (n == 0) { - p->out.eof = QSE_TRUE; + p->out.eof = 1; return 0; } @@ -587,7 +591,7 @@ int qse_awk_rtx_flushio ( qse_awk_rio_fun_t handler; int io_type, /*io_mode,*/ io_mask; qse_ssize_t n; - qse_bool_t ok = QSE_FALSE; + int ok = 0; QSE_ASSERT (out_type >= 0 && out_type <= QSE_COUNTOF(out_type_map)); QSE_ASSERT (out_type >= 0 && out_type <= QSE_COUNTOF(out_mode_map)); @@ -622,7 +626,7 @@ int qse_awk_rtx_flushio ( return -1; } - ok = QSE_TRUE; + ok = 1; } p = p->next; @@ -696,14 +700,14 @@ int qse_awk_rtx_nextio_read ( /* the next stream cannot be opened. * set the eos flags so that the next call to nextio_read * will return 0 without executing the handler */ - p->in.eos = QSE_TRUE; + p->in.eos = 1; return 0; } else { /* as the next stream has been opened successfully, * the eof flag should be cleared if set */ - p->in.eof = QSE_FALSE; + p->in.eof = 0; /* also the previous input buffer must be reset */ p->in.pos = 0; @@ -774,14 +778,14 @@ int qse_awk_rtx_nextio_write ( /* the next stream cannot be opened. * set the eos flags so that the next call to nextio_write * will return 0 without executing the handler */ - p->out.eos = QSE_TRUE; + p->out.eos = 1; return 0; } else { /* as the next stream has been opened successfully, * the eof flag should be cleared if set */ - p->out.eof = QSE_FALSE; + p->out.eof = 0; return 1; } } @@ -916,19 +920,37 @@ int qse_awk_rtx_closeio ( if (qse_strcmp (p->name, name) == 0) { qse_awk_rio_fun_t handler; - int copt = QSE_AWK_RIO_CLOSE_R | QSE_AWK_RIO_CLOSE_W; + qse_awk_rio_rwcopt_t rwcopt = QSE_AWK_RIO_CLOSE_A; if (opt != QSE_NULL) { if (opt[0] == QSE_T('r')) { - if (p->type & MASK_RDWR) copt = QSE_AWK_RIO_CLOSE_R; + if (p->type & MASK_RDWR) + { + if (p->rwcstate != QSE_AWK_RIO_CLOSE_W) + { + /* if the write end is not + * closed, let io handler close + * the read end only. */ + rwcopt = QSE_AWK_RIO_CLOSE_R; + } + } else if (!(p->type & MASK_READ)) goto skip; } else { QSE_ASSERT (opt[0] == QSE_T('w')); - if (p->type & MASK_RDWR) copt = QSE_AWK_RIO_CLOSE_W; + if (p->type & MASK_RDWR) + { + if (p->rwcstate != QSE_AWK_RIO_CLOSE_R) + { + /* if the read end is not + * closed, let io handler close + * the write end only. */ + rwcopt = QSE_AWK_RIO_CLOSE_W; + } + } else if (!(p->type & MASK_WRITE)) goto skip; } } @@ -937,7 +959,7 @@ int qse_awk_rtx_closeio ( if (handler != QSE_NULL) { qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOERR, QSE_NULL); - p->copt = copt; + p->rwcopt = rwcopt; if (handler (rtx, QSE_AWK_RIO_CLOSE, p, QSE_NULL, 0) <= -1) { /* this is not a run-time error.*/ @@ -946,12 +968,20 @@ int qse_awk_rtx_closeio ( return -1; } } -/* TODO: -if (p->type & MASK_RDWR) -{ - if partially closed don't destroy it yet... -} -*/ + + if (p->type & MASK_RDWR) + { + p->rwcopt = rwcopt; + if (p->rwcstate == 0 && rwcopt != 0) + { + /* if either end has not been closed. + * return success without destroying + * the internal node. rwcstate keeps + * what has been successfully closed */ + p->rwcstate = rwcopt; + return 0; + } + } if (px != QSE_NULL) px->next = p->next; else rtx->rio.chain = p->next; @@ -986,6 +1016,7 @@ void qse_awk_rtx_cleario (qse_awk_rtx_t* run) if (handler != QSE_NULL) { qse_awk_rtx_seterrnum (run, QSE_AWK_ENOERR, QSE_NULL); + run->rio.chain->rwcopt = 0; n = handler (run, QSE_AWK_RIO_CLOSE, run->rio.chain, QSE_NULL, 0); if (n <= -1) { diff --git a/qse/lib/awk/std.c b/qse/lib/awk/std.c index 92f77578..aa734cab 100644 --- a/qse/lib/awk/std.c +++ b/qse/lib/awk/std.c @@ -1,5 +1,5 @@ /* - * $Id: std.c 258 2009-08-19 14:04:15Z hyunghwan.chung $ + * $Id: std.c 271 2009-08-27 12:52:20Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -619,7 +619,25 @@ static qse_ssize_t awk_rio_pipe ( case QSE_AWK_RIO_CLOSE: { - qse_pio_close ((qse_pio_t*)riod->handle); + qse_pio_t* pio = (qse_pio_t*)riod->handle; + if (riod->mode == QSE_AWK_RIO_PIPE_RW) + { + /* specialy treatment is needef for rwpipe. + * inspect rwcopt to see if partial closing is + * requested. */ + if (riod->rwcopt == QSE_AWK_RIO_CLOSE_R) + { + qse_pio_end (pio, QSE_PIO_IN); + return 0; + } + else if (riod->rwcopt == QSE_AWK_RIO_CLOSE_W) + { + qse_pio_end (pio, QSE_PIO_OUT); + return 0; + } + } + + qse_pio_close (pio); riod->handle = QSE_NULL; return 0; }