From b682392d5fbd9041d5b3c47786ae247c2355e530 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Wed, 8 Jul 2009 07:05:10 +0000 Subject: [PATCH] - fixed a bug of not handling nextfile and nextofile when no files are specified in the standard console handler (awk/std.c) - enhanced the console handler for StdAwk --- qse/include/qse/awk/Awk.hpp | 14 +- qse/include/qse/awk/StdAwk.hpp | 21 +- qse/lib/awk/Awk.cpp | 81 ++--- qse/lib/awk/StdAwk.cpp | 556 ++++++++++++++++----------------- qse/lib/awk/run.c | 3 +- qse/lib/awk/std.c | 105 +++---- qse/samples/awk/awk05.cpp | 264 +--------------- 7 files changed, 394 insertions(+), 650 deletions(-) diff --git a/qse/include/qse/awk/Awk.hpp b/qse/include/qse/awk/Awk.hpp index 23771831..f16ef5c8 100644 --- a/qse/include/qse/awk/Awk.hpp +++ b/qse/include/qse/awk/Awk.hpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.hpp 223 2009-07-06 12:37:25Z hyunghwan.chung $ + * $Id: Awk.hpp 224 2009-07-07 13:05:10Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -206,6 +206,7 @@ public: operator Awk* () const; operator awk_t* () const; operator rio_arg_t* () const; + operator Run* () const; operator rtx_t* () const; protected: @@ -1061,12 +1062,19 @@ protected: bool runCallback; - struct + struct xstrs_t { + xstrs_t (): ptr (QSE_NULL), len (0), capa (0) {} + + int add (awk_t* awk, const char_t* arg, size_t len); + void clear (awk_t* awk); + qse_xstr_t* ptr; size_t len; size_t capa; - } runarg; + }; + + xstrs_t runarg; private: static const char_t* xerrstr (awk_t* a, errnum_t num) throw (); diff --git a/qse/include/qse/awk/StdAwk.hpp b/qse/include/qse/awk/StdAwk.hpp index 76b0f71a..f395d822 100644 --- a/qse/include/qse/awk/StdAwk.hpp +++ b/qse/include/qse/awk/StdAwk.hpp @@ -1,5 +1,5 @@ /* - * $Id: StdAwk.hpp 220 2009-07-01 13:14:39Z hyunghwan.chung $ + * $Id: StdAwk.hpp 224 2009-07-07 13:05:10Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -39,6 +39,11 @@ class StdAwk: public Awk { public: int open (); + void close (); + + virtual int addConsoleOutput (const char_t* arg, size_t len); + virtual int addConsoleOutput (const char_t* arg); + virtual void clearConsoleOutputs (); protected: @@ -82,7 +87,6 @@ protected: ssize_t writeFile (File& io, const char_t* buf, size_t len); int flushFile (File& io); -#if 0 // console io handlers int openConsole (Console& io); int closeConsole (Console& io); @@ -90,7 +94,6 @@ protected: ssize_t writeConsole (Console& io, const char_t* buf, size_t len); int flushConsole (Console& io); int nextConsole (Console& io); -#endif // primitive handlers void* allocMem (size_t n) throw (); @@ -103,7 +106,19 @@ protected: protected: unsigned int seed; + + /* standard input console - reuse runarg */ size_t runarg_index; + size_t runarg_count; + + /* standard output console */ + xstrs_t ofile; + size_t ofile_index; + size_t ofile_count; + +private: + int open_console_in (Console& io); + int open_console_out (Console& io); }; ///////////////////////////////// diff --git a/qse/lib/awk/Awk.cpp b/qse/lib/awk/Awk.cpp index f12ddff1..2e5f61e6 100644 --- a/qse/lib/awk/Awk.cpp +++ b/qse/lib/awk/Awk.cpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.cpp 223 2009-07-06 12:37:25Z hyunghwan.chung $ + * $Id: Awk.cpp 224 2009-07-07 13:05:10Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -88,7 +88,8 @@ Awk::RIOBase::operator Awk* () const Awk::RIOBase::operator Awk::awk_t* () const { - return qse_awk_rtx_getawk (this->run->rtx); + QSE_ASSERT (qse_awk_rtx_getawk(this->run->rtx) == this->run->awk->awk); + return this->run->awk->awk; } Awk::RIOBase::operator Awk::rio_arg_t* () const @@ -96,6 +97,11 @@ Awk::RIOBase::operator Awk::rio_arg_t* () const return this->riod; } +Awk::RIOBase::operator Awk::Run* () const +{ + return this->run; +} + Awk::RIOBase::operator Awk::rtx_t* () const { return this->run->rtx; @@ -146,7 +152,7 @@ Awk::Console::~Console () int Awk::Console::setFileName (const char_t* name) { - if (riod->mode == READ) + if (this->getMode() == READ) { return qse_awk_rtx_setfilename ( this->run->rtx, name, qse_strlen(name)); @@ -396,7 +402,6 @@ int Awk::Argument::init (const char_t* str, size_t len) return 0; } - Awk::long_t Awk::Argument::toInt () const { return this->inum; @@ -1077,10 +1082,6 @@ Awk::Awk () throw (): awk (QSE_NULL), functionMap (QSE_NULL), { this->errmsg[0] = QSE_T('\0'); - - this->runarg.ptr = QSE_NULL; - this->runarg.len = 0; - this->runarg.capa = 0; } Awk::operator Awk::awk_t* () const @@ -1463,43 +1464,52 @@ int Awk::dispatchFunction (Run* run, const char_t* name, size_t len) return 0; } -int Awk::addArgument (const char_t* arg, size_t len) +int Awk::xstrs_t::add (awk_t* awk, const char_t* arg, size_t len) { - QSE_ASSERT (awk != QSE_NULL); - - if (runarg.len >= runarg.capa) + if (this->len >= this->capa) { qse_xstr_t* ptr; - size_t capa = runarg.capa; + size_t capa = this->capa; capa += 64; ptr = (qse_xstr_t*) qse_awk_realloc ( - awk, runarg.ptr, QSE_SIZEOF(qse_xstr_t)*(capa+1)); - if (ptr == QSE_NULL) - { - setError (ERR_NOMEM); - return -1; - } + awk, this->ptr, QSE_SIZEOF(qse_xstr_t)*(capa+1)); + if (ptr == QSE_NULL) return -1; - runarg.ptr = ptr; - runarg.capa = capa; + this->ptr = ptr; + this->capa = capa; } - runarg.ptr[runarg.len].len = len; - runarg.ptr[runarg.len].ptr = qse_awk_strxdup (awk, arg, len); - if (runarg.ptr[runarg.len].ptr == QSE_NULL) - { - setError (ERR_NOMEM); - return -1; - } + this->ptr[this->len].len = len; + this->ptr[this->len].ptr = qse_awk_strxdup (awk, arg, len); + if (this->ptr[this->len].ptr == QSE_NULL) return -1; - runarg.len++; - runarg.ptr[runarg.len].len = 0; - runarg.ptr[runarg.len].ptr = QSE_NULL; + this->len++; + this->ptr[this->len].len = 0; + this->ptr[this->len].ptr = QSE_NULL; return 0; } +void Awk::xstrs_t::clear (awk_t* awk) +{ + if (this->ptr != QSE_NULL) + { + qse_awk_free (awk, this->ptr); + this->ptr = QSE_NULL; + this->len = 0; + this->capa = 0; + } +} + +int Awk::addArgument (const char_t* arg, size_t len) +{ + QSE_ASSERT (awk != QSE_NULL); + int n = runarg.add (awk, arg, len); + if (n <= -1) setError (ERR_NOMEM); + return n; +} + int Awk::addArgument (const char_t* arg) { return addArgument (arg, qse_strlen(arg)); @@ -1507,14 +1517,7 @@ int Awk::addArgument (const char_t* arg) void Awk::clearArguments () { - if (runarg.ptr != QSE_NULL) - { - QSE_ASSERT (awk != QSE_NULL); - qse_awk_free (awk, runarg.ptr); - runarg.ptr = QSE_NULL; - runarg.len = 0; - runarg.capa = 0; - } + runarg.clear (awk); } int Awk::addGlobal (const char_t* name) diff --git a/qse/lib/awk/StdAwk.cpp b/qse/lib/awk/StdAwk.cpp index 4d1618fe..3cf9f4eb 100644 --- a/qse/lib/awk/StdAwk.cpp +++ b/qse/lib/awk/StdAwk.cpp @@ -1,5 +1,5 @@ /* - * $Id: StdAwk.cpp 220 2009-07-01 13:14:39Z hyunghwan.chung $ + * $Id: StdAwk.cpp 224 2009-07-07 13:05:10Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -23,6 +23,7 @@ #include #include #include +#include "awk.h" #include #include @@ -74,6 +75,30 @@ int StdAwk::open () return 0; } +void StdAwk::close () +{ + clearConsoleOutputs (); + Awk::close (); +} + +int StdAwk::addConsoleOutput (const char_t* arg, size_t len) +{ + QSE_ASSERT (awk != QSE_NULL); + int n = ofile.add (awk, arg, len); + if (n <= -1) setError (ERR_NOMEM); + return n; +} + +int StdAwk::addConsoleOutput (const char_t* arg) +{ + return addConsoleOutput (arg, qse_strlen(arg)); +} + +void StdAwk::clearConsoleOutputs () +{ + ofile.clear (awk); +} + int StdAwk::sin (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len) { @@ -385,345 +410,314 @@ int StdAwk::flushFile (File& io) return qse_fio_flush ((qse_fio_t*)io.getHandle()); } -#if 0 // console io handlers -int StdAwk::openConsole (Console& io) +int StdAwk::open_console_in (Console& io) { - qse_sio_t* fp; - Console::Mode mode = io.getMode(); + qse_awk_rtx_t* rtx = (rtx_t*)io; - switch (mode) + if (runarg.ptr == QSE_NULL) { - case Console::READ: + QSE_ASSERT (runarg.len == 0 && runarg.capa == 0); + + if (runarg_count == 0) { - if (runarg.ptr == QSE_NULL) + io.setHandle (qse_sio_in); + runarg_count++; + return 1; + } + + return 0; + } + else + { + qse_sio_t* sio; + const qse_char_t* file; + qse_awk_val_t* argv; + qse_map_t* map; + qse_map_pair_t* pair; + qse_char_t ibuf[128]; + qse_size_t ibuflen; + qse_awk_val_t* v; + qse_awk_rtx_valtostr_out_t out; + + nextfile: + file = runarg.ptr[runarg_index].ptr; + + if (file == QSE_NULL) + { + /* no more input file */ + + if (runarg_count == 0) { - io.setHandle (qse_sio_in); - return 1; - } - else - { - qse_sio_t* sio; - const qse_char_t* file; - qse_awk_val_t* argv; - qse_map_t* map; - qse_map_pair_t* pair; - qse_char_t ibuf[128]; - qse_size_t ibuflen; - qse_awk_val_t* v; - qse_awk_rtx_valtostr_out_t out; - - nextfile: - file = runarg.ptr[runarg_index]; - - if (file == QSE_NULL) - { - /* no more input file */ - - if (runarg_count == 0) - { - /* all ARGVs are empty strings. - * so no console files were opened. - * open the standard input here. - * - * 'BEGIN { ARGV[1]=""; ARGV[2]=""; } - * { print $0; }' file1 file2 - */ - io.setHandle (qse_sio_in); - runarg_count++; - return 1; - } - - return 0; - } - - /* handle special case when ARGV[x] has been altered. - * so from here down, the file name gotten from - * rxtn->c.in.files is not important and is overridden - * from ARGV. - * 'BEGIN { ARGV[1]="file3"; } + /* all ARGVs are empty strings. + * so no console files were opened. + * open the standard input here. + * + * 'BEGIN { ARGV[1]=""; ARGV[2]=""; } * { print $0; }' file1 file2 */ - argv = qse_awk_rtx_getgbl (rtx, QSE_AWK_GBL_ARGV); - QSE_ASSERT (argv != QSE_NULL); - QSE_ASSERT (argv->type == QSE_AWK_VAL_MAP); - - map = ((qse_awk_val_map_t*)argv)->map; - QSE_ASSERT (map != QSE_NULL); - - ibuflen = qse_awk_longtostr ( - rtx->awk, rxtn->c.in.index + 1, 10, QSE_NULL, - ibuf, QSE_COUNTOF(ibuf)); - - pair = qse_map_search (map, ibuf, ibuflen); - QSE_ASSERT (pair != QSE_NULL); - - v = QSE_MAP_VPTR(pair); - QSE_ASSERT (v != QSE_NULL); - - out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP; - if (qse_awk_rtx_valtostr (rtx, v, &out) == QSE_NULL) return -1; - - if (out.u.cpldup.len == 0) - { - /* the name is empty */ - qse_awk_rtx_free (rtx, out.u.cpldup.ptr); - rxtn->c.in.index++; - goto nextfile; - } - - if (qse_strlen(out.u.cpldup.ptr) < out.u.cpldup.len) - { - /* the name contains one or more '\0' */ - qse_cstr_t errarg; - - errarg.ptr = out.u.cpldup.ptr; - /* use this length not to contains '\0' - * in an error message */ - errarg.len = qse_strlen(out.u.cpldup.ptr); - - qse_awk_rtx_seterror ( - rtx, QSE_AWK_EIONMNL, 0, &errarg); - - qse_awk_rtx_free (rtx, out.u.cpldup.ptr); - return -1; - } - - file = out.u.cpldup.ptr; - - if (file[0] == QSE_T('-') && file[1] == QSE_T('\0')) - { - /* special file name '-' */ - sio = qse_sio_in; - } - else - { - sio = qse_sio_open ( - rtx->awk->mmgr, 0, file, QSE_SIO_READ); - if (sio == QSE_NULL) - { - qse_cstr_t errarg; - - errarg.ptr = file; - errarg.len = qse_strlen(file); - - qse_awk_rtx_seterror ( - rtx, QSE_AWK_EOPEN, 0, &errarg); - - qse_awk_rtx_free (rtx, out.u.cpldup.ptr); - return -1; - } - } - - if (qse_awk_rtx_setfilename ( - rtx, file, qse_strlen(file)) == -1) - { - if (sio != qse_sio_in) qse_sio_close (sio); - qse_awk_rtx_free (rtx, out.u.cpldup.ptr); - return -1; - } - - qse_awk_rtx_free (rtx, out.u.cpldup.ptr); - riod->handle = sio; - - /* increment the counter of files successfully opened */ - rxtn->c.in.count++; - } - - rxtn->c.in.index++; + io.setHandle (qse_sio_in); + runarg_count++; + return 1; } - break; + return 0; } - case Console::WRITE: - break; - } + // TODO: need to check for '\0' contained??? + + /* handle special case when ARGV[x] has been altered. + * so from here down, the file name gotten from + * rxtn->c.in.files is not important and is overridden + * from ARGV. + * 'BEGIN { ARGV[1]="file3"; } + * { print $0; }' file1 file2 + */ + argv = qse_awk_rtx_getgbl (rtx, QSE_AWK_GBL_ARGV); + QSE_ASSERT (argv != QSE_NULL); + QSE_ASSERT (argv->type == QSE_AWK_VAL_MAP); + + map = ((qse_awk_val_map_t*)argv)->map; + QSE_ASSERT (map != QSE_NULL); -#if 0 - FILE* fp = QSE_NULL; - const char_t* fn = QSE_NULL; + ibuflen = qse_awk_longtostr ( + rtx->awk, runarg_index + 1, + 10, QSE_NULL, + ibuf, QSE_COUNTOF(ibuf) + ); - switch (mode) - { - case StdAwk::Console::READ: + pair = qse_map_search (map, ibuf, ibuflen); + QSE_ASSERT (pair != QSE_NULL); - if (numConInFiles == 0) fp = stdin; - else - { - fn = conInFile[0]; - fp = qse_fopen (fn, QSE_T("r")); - } - break; + v = (qse_awk_val_t*)QSE_MAP_VPTR(pair); + QSE_ASSERT (v != QSE_NULL); - case StdAwk::Console::WRITE: + out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP; + if (qse_awk_rtx_valtostr (rtx, v, &out) == QSE_NULL) return -1; - if (numConOutFiles == 0) fp = stdout; - else - { - fn = conOutFile[0]; - fp = qse_fopen (fn, QSE_T("w")); - } - break; - } - - if (fp == NULL) return -1; - - ConTrack* t = (ConTrack*) - qse_awk_alloc (awk, QSE_SIZEOF(ConTrack)); - if (t == QSE_NULL) - { - if (fp != stdin && fp != stdout) fclose (fp); - return -1; - } - - t->handle = fp; - t->nextConIdx = 1; - - if (fn != QSE_NULL) - { - if (io.setFileName(fn) == -1) + if (out.u.cpldup.len == 0) { - if (fp != stdin && fp != stdout) fclose (fp); - qse_awk_free (awk, t); + /* the name is empty */ + qse_awk_rtx_free (rtx, out.u.cpldup.ptr); + runarg_index++; + goto nextfile; + } + + if (qse_strlen(out.u.cpldup.ptr) < out.u.cpldup.len) + { + /* the name contains one or more '\0' */ + ((Run*)io)->setError (ERR_IONMNL, 0, out.u.cpldup.ptr); + qse_awk_rtx_free (rtx, out.u.cpldup.ptr); return -1; } + + file = out.u.cpldup.ptr; + + if (file[0] == QSE_T('-') && file[1] == QSE_T('\0')) + { + /* special file name '-' */ + sio = qse_sio_in; + } + else + { + sio = qse_sio_open ( + rtx->awk->mmgr, 0, file, QSE_SIO_READ); + if (sio == QSE_NULL) + { + ((Run*)io)->setError (ERR_OPEN, 0, file); + qse_awk_rtx_free (rtx, out.u.cpldup.ptr); + return -1; + } + } + + if (qse_awk_rtx_setfilename ( + rtx, file, qse_strlen(file)) == -1) + { + if (sio != qse_sio_in) qse_sio_close (sio); + qse_awk_rtx_free (rtx, out.u.cpldup.ptr); + return -1; + } + + qse_awk_rtx_free (rtx, out.u.cpldup.ptr); + io.setHandle (sio); + + /* increment the counter of files successfully opened */ + runarg_count++; + runarg_index++; + return 1; } - io.setHandle (t); - return 1; -#endif +} + +int StdAwk::open_console_out (Console& io) +{ + qse_awk_rtx_t* rtx = (rtx_t*)io; + + if (ofile.ptr == QSE_NULL) + { + QSE_ASSERT (ofile.len == 0 && ofile.capa == 0); + + if (ofile_count == 0) + { + io.setHandle (qse_sio_out); + ofile_count++; + return 1; + } + + return 0; + } + else + { + /* a temporary variable sio is used here not to change + * any fields of riod when the open operation fails */ + qse_sio_t* sio; + const qse_char_t* file; + + file = ofile.ptr[ofile_index].ptr; + + if (file == QSE_NULL) + { + /* no more input file */ + return 0; + } + + // TODO: need to check for '\0' contained??? + + if (file[0] == QSE_T('-') && file[1] == QSE_T('\0')) + { + /* special file name '-' */ + sio = qse_sio_out; + } + else + { + sio = qse_sio_open ( + rtx->awk->mmgr, 0, file, QSE_SIO_READ); + if (sio == QSE_NULL) + { + ((Run*)io)->setError (ERR_OPEN, 0, file); + return -1; + } + } + + if (qse_awk_rtx_setofilename ( + rtx, file, qse_strlen(file)) == -1) + { + qse_sio_close (sio); + return -1; + } + + io.setHandle (sio); + + ofile_index++; + ofile_count++; + return 1; + } +} + +int StdAwk::openConsole (Console& io) +{ + Console::Mode mode = io.getMode(); + + if (mode == Console::READ) + { + runarg_count = 0; + runarg_index = 0; + return open_console_in (io); + } + else + { + QSE_ASSERT (mode == Console::WRITE); + + ofile_count = 0; + ofile_index = 0; + return open_console_out (io); + } } int StdAwk::closeConsole (Console& io) { - ConTrack* t = (ConTrack*)io.getHandle(); - FILE* fp = t->handle; + qse_sio_t* sio; - if (fp == stdout || fp == stderr) fflush (fp); - if (fp != stdin && fp != stdout && fp != stderr) fclose (fp); + sio = (qse_sio_t*)io.getHandle(); + if (sio != qse_sio_in && + sio != qse_sio_out && + sio != qse_sio_err) + { + qse_sio_close (sio); + } - qse_awk_free (awk, t); return 0; } -ssize_t StdAwk::readConsole (Console& io, char_t* buf, size_t len) +ssize_t StdAwk::readConsole (Console& io, char_t* data, size_t size) { - ConTrack* t = (ConTrack*)io.getHandle(); - FILE* fp = t->handle; - ssize_t n = 0; + qse_ssize_t nn; - while (n < (ssize_t)len) + while ((nn = qse_sio_getsn((qse_sio_t*)io.getHandle(),data,size)) == 0) { - qse_cint_t c = qse_fgetc (fp); - if (c == QSE_CHAR_EOF) + int n; + qse_sio_t* sio = (qse_sio_t*)io.getHandle(); + + n = open_console_in (io); + if (n == -1) return -1; + + if (n == 0) { - if (qse_ferror(fp)) return -1; - if (t->nextConIdx >= numConInFiles) break; - - const char_t* fn = conInFile[t->nextConIdx]; - FILE* nfp = qse_fopen (fn, QSE_T("r")); - if (nfp == QSE_NULL) return -1; - - if (io.setFileName(fn) == -1 || io.setFNR(0) == -1) - { - fclose (nfp); - return -1; - } - - fclose (fp); - fp = nfp; - t->nextConIdx++; - t->handle = fp; - - if (n == 0) continue; - else break; + /* no more input console */ + return 0; } - buf[n++] = c; - if (c == QSE_T('\n')) break; + if (sio != QSE_NULL && + sio != qse_sio_in && + sio != qse_sio_out && + sio != qse_sio_err) + { + qse_sio_close (sio); + } } - return n; + return nn; } -ssize_t StdAwk::writeConsole (Console& io, const char_t* buf, size_t len) +ssize_t StdAwk::writeConsole (Console& io, const char_t* data, size_t size) { - ConTrack* t = (ConTrack*)io.getHandle(); - FILE* fp = t->handle; - size_t left = len; - - while (left > 0) - { - if (*buf == QSE_T('\0')) - { - if (qse_fputc(*buf,fp) == QSE_CHAR_EOF) return -1; - left -= 1; buf += 1; - } - else - { - int chunk = (left > QSE_TYPE_MAX(int))? QSE_TYPE_MAX(int): (int)left; - int n = qse_fprintf (fp, QSE_T("%.*s"), chunk, buf); - if (n < 0 || n > chunk) return -1; - left -= n; buf += n; - } - } - - return len; + return qse_sio_putsn ( + (qse_sio_t*)io.getHandle(), + data, + size + ); } int StdAwk::flushConsole (Console& io) { - ConTrack* t = (ConTrack*)io.getHandle(); - FILE* fp = t->handle; - return ::fflush (fp); + return qse_sio_flush ((qse_sio_t*)io.getHandle()); } int StdAwk::nextConsole (Console& io) { - StdAwk::Console::Mode mode = io.getMode(); + int n; + qse_sio_t* sio = (qse_sio_t*)io.getHandle(); - ConTrack* t = (ConTrack*)io.getHandle(); - FILE* ofp = t->handle; - FILE* nfp = QSE_NULL; - const char_t* fn = QSE_NULL; + n = (io.getMode() == Console::READ)? + open_console_in(io): open_console_out(io); + if (n == -1) return -1; - switch (mode) + if (n == 0) { - case StdAwk::Console::READ: - - if (t->nextConIdx >= numConInFiles) return 0; - fn = conInFile[t->nextConIdx]; - nfp = qse_fopen (fn, QSE_T("r")); - break; - - case StdAwk::Console::WRITE: - - if (t->nextConIdx >= numConOutFiles) return 0; - fn = conOutFile[t->nextConIdx]; - nfp = qse_fopen (fn, QSE_T("w")); - break; + /* if there is no more file, keep the previous handle */ + return 0; } - if (nfp == QSE_NULL) return -1; - - if (fn != QSE_NULL) + if (sio != QSE_NULL && + sio != qse_sio_in && + sio != qse_sio_out && + sio != qse_sio_err) { - if (io.setFileName (fn) == -1) - { - fclose (nfp); - return -1; - } + qse_sio_close (sio); } - fclose (ofp); - - t->nextConIdx++; - t->handle = nfp; - - return 1; + return n; } -#endif // memory allocation primitives void* StdAwk::allocMem (size_t n) throw () diff --git a/qse/lib/awk/run.c b/qse/lib/awk/run.c index 1650dae9..c5a0268b 100644 --- a/qse/lib/awk/run.c +++ b/qse/lib/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c 220 2009-07-01 13:14:39Z hyunghwan.chung $ + * $Id: run.c 224 2009-07-07 13:05:10Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -667,7 +667,6 @@ qse_awk_rtx_t* qse_awk_rtx_open ( return QSE_NULL; } - /* initialize the run object */ if (init_rtx (rtx, awk, rio) == -1) { diff --git a/qse/lib/awk/std.c b/qse/lib/awk/std.c index d61c3dfe..0de4539e 100644 --- a/qse/lib/awk/std.c +++ b/qse/lib/awk/std.c @@ -1,5 +1,5 @@ /* - * $Id: std.c 212 2009-06-25 07:39:27Z hyunghwan.chung $ + * $Id: std.c 224 2009-07-07 13:05:10Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -85,6 +85,7 @@ typedef struct rxtn_t { const qse_char_t*const* files; qse_size_t index; + qse_size_t count; } out; } c; /* console */ @@ -609,7 +610,15 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod) /* if no input files is specified, * open the standard input */ QSE_ASSERT (rxtn->c.in.index == 0); - riod->handle = qse_sio_in; + + if (rxtn->c.in.count == 0) + { + riod->handle = qse_sio_in; + rxtn->c.in.count++; + return 1; + } + + return 0; } else { @@ -740,17 +749,25 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod) /* increment the counter of files successfully opened */ rxtn->c.in.count++; + rxtn->c.in.index++; + return 1; } - rxtn->c.in.index++; - return 1; } else if (riod->mode == QSE_AWK_RIO_CONSOLE_WRITE) { if (rxtn->c.out.files == QSE_NULL) { QSE_ASSERT (rxtn->c.out.index == 0); - riod->handle = qse_sio_out; + + if (rxtn->c.out.count == 0) + { + riod->handle = qse_sio_out; + rxtn->c.out.count++; + return 1; + } + + return 0; } else { @@ -797,10 +814,12 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod) } riod->handle = sio; + + rxtn->c.out.index++; + rxtn->c.out.count++; + return 1; } - rxtn->c.out.index++; - return 1; } return -1; @@ -810,8 +829,6 @@ static qse_ssize_t awk_rio_console ( qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_rio_arg_t* riod, qse_char_t* data, qse_size_t size) { - rxtn_t* rxtn = (rxtn_t*) QSE_XTN (rtx); - if (cmd == QSE_AWK_RIO_OPEN) { return open_rio_console (rtx, riod); @@ -830,73 +847,32 @@ static qse_ssize_t awk_rio_console ( } else if (cmd == QSE_AWK_RIO_READ) { - qse_ssize_t n; + qse_ssize_t nn; - while ((n = qse_sio_getsn((qse_sio_t*)riod->handle,data,size)) == 0) + while ((nn = qse_sio_getsn((qse_sio_t*)riod->handle,data,size)) == 0) { - qse_sio_t* sio; - const qse_char_t* file; + int n; + qse_sio_t* sio = (qse_sio_t*)riod->handle; - /* it has reached the end of the current file. - * open the next file if available */ - if (rxtn->c.in.files == QSE_NULL || - rxtn->c.in.files[rxtn->c.in.index] == QSE_NULL) + n = open_rio_console (rtx, riod); + if (n == -1) return -1; + + if (n == 0) { /* no more input console */ return 0; } - file = rxtn->c.in.files[rxtn->c.in.index]; - - if (file[0] == QSE_T('-') && file[1] == QSE_T('\0')) + if (sio != QSE_NULL && + sio != qse_sio_in && + sio != qse_sio_out && + sio != qse_sio_err) { - sio = qse_sio_in; + qse_sio_close (sio); } - else - { - sio = qse_sio_open ( - rtx->awk->mmgr, 0, file, QSE_SIO_READ); - if (sio == QSE_NULL) - { - qse_cstr_t errarg; - - errarg.ptr = file; - errarg.len = qse_strlen(file); - - qse_awk_rtx_seterror ( - rtx, QSE_AWK_EOPEN, 0, &errarg); - return -1; - } - } - - if (qse_awk_rtx_setfilename ( - rtx, file, qse_strlen(file)) == -1) - { - if (sio != qse_sio_in) qse_sio_close (sio); - return -1; - } - - if (qse_awk_rtx_setgbl ( - rtx, QSE_AWK_GBL_FNR, qse_awk_val_zero) == -1) - { - /* need to reset FNR */ - if (sio != qse_sio_in) qse_sio_close (sio); - return -1; - } - - if (riod->handle != QSE_NULL && - riod->handle != qse_sio_in && - riod->handle != qse_sio_out && - riod->handle != qse_sio_err) - { - qse_sio_close ((qse_sio_t*)riod->handle); - } - - riod->handle = sio; - rxtn->c.in.index++; } - return n; + return nn; } else if (cmd == QSE_AWK_RIO_WRITE) { @@ -1019,6 +995,7 @@ qse_awk_rtx_t* qse_awk_rtx_openstd ( rxtn->c.in.count = 0; rxtn->c.out.files = ocf; rxtn->c.out.index = 0; + rxtn->c.out.count = 0; return rtx; } diff --git a/qse/samples/awk/awk05.cpp b/qse/samples/awk/awk05.cpp index 97bb3799..2abec132 100644 --- a/qse/samples/awk/awk05.cpp +++ b/qse/samples/awk/awk05.cpp @@ -48,8 +48,8 @@ static bool verbose = false; class TestAwk: public QSE::StdAwk { public: - TestAwk (): srcInName(QSE_NULL), srcOutName(QSE_NULL), - numConInFiles(0), numConOutFiles(0) + TestAwk (): srcInName(QSE_NULL), srcOutName(QSE_NULL) + { #ifdef _WIN32 heap = QSE_NULL; @@ -106,9 +106,6 @@ public: { StdAwk::close (); - numConInFiles = 0; - numConOutFiles = 0; - #ifdef _WIN32 if (heap != QSE_NULL) { @@ -193,28 +190,6 @@ public: return 0; } - int addConsoleInput (const char_t* file) - { - if (numConInFiles < QSE_COUNTOF(conInFile)) - { - conInFile[numConInFiles++] = file; - return 0; - } - - return -1; - } - - int addConsoleOutput (const char_t* file) - { - if (numConOutFiles < QSE_COUNTOF(conOutFile)) - { - conOutFile[numConOutFiles++] = file; - return 0; - } - - return -1; - } - int parse (const char_t* in, const char_t* out) { srcInName = in; @@ -331,193 +306,6 @@ protected: return len; } - // console io handlers - int openConsole (Console& io) - { - StdAwk::Console::Mode mode = io.getMode(); - - FILE* fp = QSE_NULL; - const char_t* fn = QSE_NULL; - - switch (mode) - { - case StdAwk::Console::READ: - - if (numConInFiles == 0) fp = stdin; - else - { - fn = conInFile[0]; - fp = qse_fopen (fn, QSE_T("r")); - } - break; - - case StdAwk::Console::WRITE: - - if (numConOutFiles == 0) fp = stdout; - else - { - fn = conOutFile[0]; - fp = qse_fopen (fn, QSE_T("w")); - } - break; - } - - if (fp == NULL) return -1; - - ConTrack* t = (ConTrack*) - qse_awk_alloc (awk, QSE_SIZEOF(ConTrack)); - if (t == QSE_NULL) - { - if (fp != stdin && fp != stdout) fclose (fp); - return -1; - } - - t->handle = fp; - t->nextConIdx = 1; - - if (fn != QSE_NULL) - { - if (io.setFileName(fn) <= -1) - { - if (fp != stdin && fp != stdout) fclose (fp); - qse_awk_free (awk, t); - return -1; - } - } - - io.setHandle (t); - return 1; - } - - int closeConsole (Console& io) - { - ConTrack* t = (ConTrack*)io.getHandle(); - FILE* fp = t->handle; - - if (fp == stdout || fp == stderr) fflush (fp); - if (fp != stdin && fp != stdout && fp != stderr) fclose (fp); - - qse_awk_free (awk, t); - return 0; - } - - ssize_t readConsole (Console& io, char_t* buf, size_t len) - { - ConTrack* t = (ConTrack*)io.getHandle(); - FILE* fp = t->handle; - ssize_t n = 0; - - while (n < (ssize_t)len) - { - qse_cint_t c = qse_fgetc (fp); - if (c == QSE_CHAR_EOF) - { - if (qse_ferror(fp)) return -1; - if (t->nextConIdx >= numConInFiles) break; - - const char_t* fn = conInFile[t->nextConIdx]; - FILE* nfp = qse_fopen (fn, QSE_T("r")); - if (nfp == QSE_NULL) return -1; - - if (io.setFileName(fn) <= -1 || io.setFNR(0) <= -1) - { - fclose (nfp); - return -1; - } - - fclose (fp); - fp = nfp; - t->nextConIdx++; - t->handle = fp; - - if (n == 0) continue; - else break; - } - - buf[n++] = c; - if (c == QSE_T('\n')) break; - } - - return n; - } - - ssize_t writeConsole (Console& io, const char_t* buf, size_t len) - { - ConTrack* t = (ConTrack*)io.getHandle(); - FILE* fp = t->handle; - size_t left = len; - - while (left > 0) - { - if (*buf == QSE_T('\0')) - { - if (qse_fputc(*buf,fp) == QSE_CHAR_EOF) return -1; - left -= 1; buf += 1; - } - else - { - int chunk = (left > QSE_TYPE_MAX(int))? QSE_TYPE_MAX(int): (int)left; - int n = qse_fprintf (fp, QSE_T("%.*s"), chunk, buf); - if (n < 0 || n > chunk) return -1; - left -= n; buf += n; - } - } - - return len; - } - - int flushConsole (Console& io) - { - ConTrack* t = (ConTrack*)io.getHandle(); - FILE* fp = t->handle; - return ::fflush (fp); - } - - int nextConsole (Console& io) - { - StdAwk::Console::Mode mode = io.getMode(); - - ConTrack* t = (ConTrack*)io.getHandle(); - FILE* ofp = t->handle; - FILE* nfp = QSE_NULL; - const char_t* fn = QSE_NULL; - - switch (mode) - { - case StdAwk::Console::READ: - - if (t->nextConIdx >= numConInFiles) return 0; - fn = conInFile[t->nextConIdx]; - nfp = qse_fopen (fn, QSE_T("r")); - break; - - case StdAwk::Console::WRITE: - - if (t->nextConIdx >= numConOutFiles) return 0; - fn = conOutFile[t->nextConIdx]; - nfp = qse_fopen (fn, QSE_T("w")); - break; - } - - if (nfp == QSE_NULL) return -1; - - if (fn != QSE_NULL) - { - if (io.setFileName (fn) <= -1) - { - fclose (nfp); - return -1; - } - } - - fclose (ofp); - - t->nextConIdx++; - t->handle = nfp; - - return 1; - } - void* allocMem (size_t n) throw () { #ifdef _WIN32 @@ -552,18 +340,6 @@ private: const char_t* srcInName; const char_t* srcOutName; - struct ConTrack - { - FILE* handle; - size_t nextConIdx; - }; - - size_t numConInFiles; - const char_t* conInFile[128]; - - size_t numConOutFiles; - const char_t* conOutFile[128]; - int idLastSleep; #ifdef _WIN32 @@ -672,14 +448,13 @@ static void print_usage (const qse_char_t* argv0) if (base == QSE_NULL) base = qse_strrchr(argv0, QSE_T('\\')); if (base == QSE_NULL) base = argv0; else base++; - qse_printf (QSE_T("Usage: %s [-si file]? [-so file]? [-ci file]* [-co file]* [-a arg]* [-w o:n]* \n"), base); + qse_printf (QSE_T("Usage: %s [-si file]? [-so file]? [-ci file]* [-co file]* [-w o:n]* \n"), base); qse_printf (QSE_T(" -si file Specify the input source file\n")); qse_printf (QSE_T(" The source code is read from stdin when it is not specified\n")); qse_printf (QSE_T(" -so file Specify the output source file\n")); qse_printf (QSE_T(" The deparsed code is not output when is it not specified\n")); qse_printf (QSE_T(" -ci file Specify the input console file\n")); qse_printf (QSE_T(" -co file Specify the output console file\n")); - qse_printf (QSE_T(" -a str Specify an argument\n")); qse_printf (QSE_T(" -w o:n Specify an old and new word pair\n")); qse_printf (QSE_T(" o - an original word\n")); qse_printf (QSE_T(" n - the new word to replace the original\n")); @@ -700,8 +475,6 @@ static int awk_main (int argc, qse_char_t* argv[]) int mode = 0; const qse_char_t* srcin = QSE_T(""); const qse_char_t* srcout = NULL; - const qse_char_t* args[256]; - qse_size_t nargs = 0; qse_size_t nsrcins = 0; qse_size_t nsrcouts = 0; @@ -719,8 +492,7 @@ static int awk_main (int argc, qse_char_t* argv[]) else if (qse_strcmp(argv[i], QSE_T("-so")) == 0) mode = 2; else if (qse_strcmp(argv[i], QSE_T("-ci")) == 0) mode = 3; else if (qse_strcmp(argv[i], QSE_T("-co")) == 0) mode = 4; - else if (qse_strcmp(argv[i], QSE_T("-a")) == 0) mode = 5; - else if (qse_strcmp(argv[i], QSE_T("-w")) == 0) mode = 6; + else if (qse_strcmp(argv[i], QSE_T("-w")) == 0) mode = 5; else if (qse_strcmp(argv[i], QSE_T("-v")) == 0) { verbose = true; @@ -796,7 +568,7 @@ static int awk_main (int argc, qse_char_t* argv[]) } else if (mode == 3) // console input { - if (awk.addConsoleInput (argv[i]) <= -1) + if (awk.addArgument (argv[i]) <= -1) { print_error (QSE_T("too many console inputs")); return -1; @@ -814,18 +586,7 @@ static int awk_main (int argc, qse_char_t* argv[]) mode = 0; } - else if (mode == 5) // argument mode - { - if (nargs >= QSE_COUNTOF(args)) - { - print_usage (argv[0]); - return -1; - } - - args[nargs++] = argv[i]; - mode = 0; - } - else if (mode == 6) // word replacement + else if (mode == 5) // word replacement { const qse_char_t* p; qse_size_t l; @@ -866,19 +627,6 @@ static int awk_main (int argc, qse_char_t* argv[]) awk.enableRunCallback (); app_awk = &awk; - for (qse_size_t i = 0; i < nargs; i++) - { - if (awk.addArgument (args[i]) <= -1) - { - qse_fprintf (stderr, - QSE_T("ERROR: %s\n"), - awk.getErrorMessage() - ); - awk.close (); - return -1; - } - } - if (awk.loop () <= -1) { qse_fprintf (stderr, QSE_T("cannot run: LINE[%d] %s\n"),