From 29107a71be53b185f16191393e43ba2ad9c54b71 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sun, 25 Dec 2011 15:25:28 +0000 Subject: [PATCH] changed qse_tio_t to accept buffer specified externally. removed the internal buffer from qse_tio_t. added the WriteFile/WriteConsoleW hack into qse_sio_putwcs()/qse_sio_wcsn() as a partial solution to the WriteFile issue with UTF8 strings on the UTF8 console on win32 --- qse/include/qse/cmn/fio.h | 15 +-- qse/include/qse/cmn/pio.h | 2 +- qse/include/qse/cmn/sio.h | 30 +++-- qse/include/qse/cmn/tio.h | 87 +++++++------ qse/lib/cmn/fio.c | 21 +-- qse/lib/cmn/pio.c | 8 +- qse/lib/cmn/sio.c | 159 ++++++++++++++++++++--- qse/lib/cmn/tio-get.c | 42 +++--- qse/lib/cmn/tio-put.c | 32 ++--- qse/lib/cmn/tio.c | 238 +++++++++++++++++++++++++--------- qse/regress/awk/regress.out | 92 ++++++------- qse/regress/awk/regress.sh.in | 104 +++++++-------- qse/samples/cmn/sio01.c | 27 ++-- 13 files changed, 557 insertions(+), 300 deletions(-) diff --git a/qse/include/qse/cmn/fio.h b/qse/include/qse/cmn/fio.h index e1663280..6971a548 100644 --- a/qse/include/qse/cmn/fio.h +++ b/qse/include/qse/cmn/fio.h @@ -32,9 +32,10 @@ enum qse_fio_open_flag_t { - /** request qse_char_io based IO */ + /** request text-based based IO */ QSE_FIO_TEXT = (1 << 0), - QSE_FIO_IGNOREMBWCERR = (1 << 1), + QSE_FIO_IGNOREMBWCERR = (1 << 1), /* useful if QSE_FIO_TEXT is set */ + QSE_FIO_NOAUTOFLUSH = (1 << 2), /* useful if QSE_FIO_TEXT is set */ /** treat the file name pointer as a handle pointer */ QSE_FIO_HANDLE = (1 << 3), @@ -60,18 +61,14 @@ enum qse_fio_open_flag_t QSE_FIO_NOFOLLOW = (1 << 15), /* for WIN32 only. harmless(no effect) when used on other platforms */ - QSE_FIO_NOSHRD = (1 << 20), - QSE_FIO_NOSHWR = (1 << 21), - QSE_FIO_NOSHDL = (1 << 22), + QSE_FIO_NOSHREAD = (1 << 20), + QSE_FIO_NOSHWRITE = (1 << 21), + QSE_FIO_NOSHDELETE = (1 << 22), /* hints to OS. harmless(no effect) when used on unsupported platforms */ QSE_FIO_RANDOM = (1 << 23), /* hint that access be random */ QSE_FIO_SEQUENTIAL = (1 << 24) /* hint that access is sequential */ - /* NOTE: - * NEVER (1 << 31) since QSE_SIO_NOAUTOFLUSH is defined to - * that value in sio.h FIO doesn't have any bufferring. - */ }; enum qse_fio_std_t diff --git a/qse/include/qse/cmn/pio.h b/qse/include/qse/cmn/pio.h index aec36e17..62392927 100644 --- a/qse/include/qse/cmn/pio.h +++ b/qse/include/qse/cmn/pio.h @@ -119,7 +119,7 @@ enum qse_pio_errnum_t { QSE_PIO_ENOERR = 0, /**< no error */ QSE_PIO_ENOMEM, /**< out of memory */ - QSE_PIO_EINVAL, /**< out of memory */ + QSE_PIO_EINVAL, /**< invalid parameter */ QSE_PIO_ENOHND, /**< no handle available */ QSE_PIO_ECHILD, /**< the child is not valid */ QSE_PIO_EINTR, /**< interrupted */ diff --git a/qse/include/qse/cmn/sio.h b/qse/include/qse/cmn/sio.h index 5ffba447..2fc6fd2c 100644 --- a/qse/include/qse/cmn/sio.h +++ b/qse/include/qse/cmn/sio.h @@ -30,12 +30,13 @@ #include #include -enum qse_sio_oflag_t +enum qse_sio_flag_t { + QSE_SIO_IGNOREMBWCERR = QSE_FIO_IGNOREMBWCERR, + QSE_SIO_NOAUTOFLUSH = QSE_FIO_NOAUTOFLUSH, + QSE_SIO_HANDLE = QSE_FIO_HANDLE, QSE_SIO_TEMPORARY = QSE_FIO_TEMPORARY, - - QSE_SIO_IGNOREMBWCERR = QSE_FIO_IGNOREMBWCERR, QSE_SIO_NOCLOSE = QSE_FIO_NOCLOSE, QSE_SIO_READ = QSE_FIO_READ, @@ -48,16 +49,12 @@ enum qse_sio_oflag_t QSE_SIO_SYNC = QSE_FIO_SYNC, QSE_SIO_NOFOLLOW = QSE_FIO_NOFOLLOW, - QSE_SIO_NOSHRD = QSE_FIO_NOSHRD, - QSE_SIO_NOSHWR = QSE_FIO_NOSHWR, - QSE_SIO_NOSHDL = QSE_FIO_NOSHDL, + QSE_SIO_NOSHREAD = QSE_FIO_NOSHREAD, + QSE_SIO_NOSHWRITE = QSE_FIO_NOSHWRITE, + QSE_SIO_NOSHDELETE = QSE_FIO_NOSHDELETE, QSE_SIO_RANDOM = QSE_FIO_RANDOM, - QSE_SIO_SEQUENTIAL = QSE_FIO_SEQUENTIAL, - - /* Beware that this should not overlap with any QSE_FIO_XXXX. - * See NOTE in fio.h */ - QSE_SIO_NOAUTOFLUSH = (1 << 31) + QSE_SIO_SEQUENTIAL = QSE_FIO_SEQUENTIAL }; typedef qse_tio_errnum_t qse_sio_errnum_t; @@ -88,6 +85,13 @@ struct qse_sio_t QSE_DEFINE_COMMON_FIELDS (tio) qse_fio_t fio; qse_tio_t tio; + + qse_mchar_t inbuf[2048]; + qse_mchar_t outbuf[2048]; + +#if defined(_WIN32) + int status; +#endif }; #ifdef __cplusplus @@ -101,14 +105,14 @@ qse_sio_t* qse_sio_open ( qse_mmgr_t* mmgr, /**< memory manager */ qse_size_t xtnsize, /**< extension size in bytes */ const qse_char_t* file, /**< file name */ - int oflags /**< number OR'ed of #qse_sio_oflag_t */ + int flags /**< number OR'ed of #qse_sio_flag_t */ ); qse_sio_t* qse_sio_openstd ( qse_mmgr_t* mmgr, /**< memory manager */ qse_size_t xtnsize, /**< extension size in bytes */ qse_sio_std_t std, /**< standard I/O identifier */ - int oflags /**< number OR'ed of #qse_sio_oflag_t */ + int flags /**< number OR'ed of #qse_sio_flag_t */ ); /** diff --git a/qse/include/qse/cmn/tio.h b/qse/include/qse/cmn/tio.h index 89d2ba36..52fb4e3b 100644 --- a/qse/include/qse/cmn/tio.h +++ b/qse/include/qse/cmn/tio.h @@ -34,44 +34,44 @@ enum qse_tio_errnum_t { QSE_TIO_ENOERR = 0, QSE_TIO_ENOMEM, /* out of memory */ + QSE_TIO_EINVAL, /* invalid parameter */ QSE_TIO_ENOSPC, /* no more space */ QSE_TIO_EILSEQ, /* illegal sequence */ QSE_TIO_EICSEQ, /* incomplete sequence */ QSE_TIO_EILCHR, /* illegal character */ - QSE_TIO_ENOINF, /* no input function attached */ - QSE_TIO_EINPUT, /* input function returned an error */ - QSE_TIO_EINPOP, /* input function failed to open */ - QSE_TIO_EINPCL, /* input function failed to close */ + QSE_TIO_ENINPF, /* no input function attached */ QSE_TIO_ENOUTF, /* no output function attached */ - QSE_TIO_EOUTPT, /* output function returned an error */ - QSE_TIO_EOUTOP, /* output function failed to open */ - QSE_TIO_EOUTCL /* output function failed to close */ + QSE_TIO_EIOERR /* I/O error */ }; typedef enum qse_tio_errnum_t qse_tio_errnum_t; -enum -{ - /* the size of input buffer should be at least equal to or greater - * than the maximum sequence length of the qse_mchar_t string. - * (i.e. 6 for utf8) - */ - QSE_TIO_MAX_INBUF_LEN = 4096, - QSE_TIO_MAX_OUTBUF_LEN = 4096 -}; - enum qse_tio_cmd_t { - QSE_TIO_IO_OPEN, - QSE_TIO_IO_CLOSE, - QSE_TIO_IO_DATA + QSE_TIO_OPEN, + QSE_TIO_CLOSE, + QSE_TIO_DATA }; typedef enum qse_tio_cmd_t qse_tio_cmd_t; enum qse_tio_flag_t { + /**< ignore multibyte/wide-character conversion error by + * inserting a question mark for each error occurrence */ QSE_TIO_IGNOREMBWCERR = (1 << 0), - QSE_TIO_NOAUTOFLUSH = (1 << 1) + + /**< do not flush data in the buffer until the buffer gets full. */ + QSE_TIO_NOAUTOFLUSH = (1 << 1), + + /* for internal use only. */ + QSE_TIO_DYNINBUF = (1 << 30), + QSE_TIO_DYNOUTBUF = (1 << 31) +}; + +enum qse_tio_misc_t +{ + QSE_TIO_MININBUFCAPA = 32, + QSE_TIO_MINOUTBUFCAPA = 32 }; #define QSE_TIO_ERRNUM(tio) ((const qse_tio_errnum_t)(tio)->errnum) @@ -79,15 +79,28 @@ enum qse_tio_flag_t typedef struct qse_tio_t qse_tio_t; /** - * The qse_tio_io_t types define a text I/O handler. + * The qse_tio_io_fun_t types define a text I/O handler. */ -typedef qse_ssize_t (*qse_tio_io_t) ( +typedef qse_ssize_t (*qse_tio_io_fun_t) ( qse_tio_cmd_t cmd, void* arg, void* data, qse_size_t size ); +struct qse_tio_io_t +{ + qse_tio_io_fun_t fun; + void* arg; + struct + { + qse_size_t capa; + qse_mchar_t* ptr; + } buf; +}; + +typedef struct qse_tio_io_t qse_tio_io_t; + /** * The qse_tio_t type defines a generic type for text IO. If #qse_char_t is * #qse_mchar_t, it handles any byte streams. If qse_char_t is #qse_wchar_t, @@ -99,20 +112,14 @@ struct qse_tio_t qse_tio_errnum_t errnum; int flags; - /* io functions */ - qse_tio_io_t input_func; - qse_tio_io_t output_func; - void* input_arg; - void* output_arg; + qse_tio_io_t in; + qse_tio_io_t out; - /* for housekeeping */ + /* for house keeping from here */ int input_status; qse_size_t inbuf_cur; qse_size_t inbuf_len; qse_size_t outbuf_len; - - qse_mchar_t inbuf[QSE_TIO_MAX_INBUF_LEN]; - qse_mchar_t outbuf[QSE_TIO_MAX_OUTBUF_LEN]; }; #ifdef __cplusplus @@ -174,9 +181,11 @@ const qse_char_t* qse_tio_geterrmsg ( * @return 0 on success, -1 on failure */ int qse_tio_attachin ( - qse_tio_t* tio, - qse_tio_io_t input, - void* arg + qse_tio_t* tio, + qse_tio_io_fun_t input, + void* arg, + qse_mchar_t* bufptr, + qse_size_t bufcapa ); /** @@ -192,9 +201,11 @@ int qse_tio_detachin ( * @return 0 on success, -1 on failure */ int qse_tio_attachout ( - qse_tio_t* tio, - qse_tio_io_t output, - void* arg + qse_tio_t* tio, + qse_tio_io_fun_t output, + void* arg, + qse_mchar_t* bufptr, + qse_size_t bufcapa ); /** diff --git a/qse/lib/cmn/fio.c b/qse/lib/cmn/fio.c index 8b8a9a91..ee08e2ed 100644 --- a/qse/lib/cmn/fio.c +++ b/qse/lib/cmn/fio.c @@ -189,11 +189,11 @@ int qse_fio_init ( } else creation_disposition = OPEN_EXISTING; - if (flags & QSE_FIO_NOSHRD) + if (flags & QSE_FIO_NOSHREAD) share_mode &= ~FILE_SHARE_READ; - if (flags & QSE_FIO_NOSHWR) + if (flags & QSE_FIO_NOSHWRITE) share_mode &= ~FILE_SHARE_WRITE; - if (flags & QSE_FIO_NOSHDL) + if (flags & QSE_FIO_NOSHDELETE) share_mode &= ~FILE_SHARE_DELETE; if (!(mode & QSE_FIO_WUSR)) @@ -302,11 +302,11 @@ int qse_fio_init ( if (flags & QSE_FIO_SYNC) open_mode |= OPEN_FLAGS_WRITE_THROUGH; - if ((flags & QSE_FIO_NOSHRD) && (flags & QSE_FIO_NOSHWR)) + if ((flags & QSE_FIO_NOSHREAD) && (flags & QSE_FIO_NOSHWRITE)) open_mode |= OPEN_SHARE_DENYREADWRITE; - else if (flags & QSE_FIO_NOSHRD) + else if (flags & QSE_FIO_NOSHREAD) open_mode |= OPEN_SHARE_DENYREAD; - else if (flags & QSE_FIO_NOSHWR) + else if (flags & QSE_FIO_NOSHWRITE) open_mode |= OPEN_SHARE_DENYWRITE; else open_mode |= OPEN_SHARE_DENYNONE; @@ -511,12 +511,13 @@ int qse_fio_init ( int opt = 0; if (fio->flags & QSE_FIO_IGNOREMBWCERR) opt |= QSE_TIO_IGNOREMBWCERR; + if (fio->flags & QSE_FIO_NOAUTOFLUSH) opt |= QSE_TIO_NOAUTOFLUSH; tio = qse_tio_open (fio->mmgr, 0, opt); if (tio == QSE_NULL) QSE_THROW_ERR (tio); - if (qse_tio_attachin (tio, fio_input, fio) <= -1 || - qse_tio_attachout (tio, fio_output, fio) <= -1) + if (qse_tio_attachin (tio, fio_input, fio, QSE_NULL, 4096) <= -1 || + qse_tio_attachout (tio, fio_output, fio, QSE_NULL, 4096) <= -1) { qse_tio_close (tio); QSE_THROW_ERR (tio); @@ -991,7 +992,7 @@ static qse_ssize_t fio_input (qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_ { qse_fio_t* fio = (qse_fio_t*)arg; QSE_ASSERT (fio != QSE_NULL); - if (cmd == QSE_TIO_IO_DATA) return fio_read (fio, buf, size); + if (cmd == QSE_TIO_DATA) return fio_read (fio, buf, size); /* take no actions for OPEN and CLOSE as they are handled * by fio */ @@ -1002,7 +1003,7 @@ static qse_ssize_t fio_output (qse_tio_cmd_t cmd, void* arg, void* buf, qse_size { qse_fio_t* fio = (qse_fio_t*)arg; QSE_ASSERT (fio != QSE_NULL); - if (cmd == QSE_TIO_IO_DATA) return fio_write (fio, buf, size); + if (cmd == QSE_TIO_DATA) return fio_write (fio, buf, size); /* take no actions for OPEN and CLOSE as they are handled * by fio */ diff --git a/qse/lib/cmn/pio.c b/qse/lib/cmn/pio.c index 6abb48a2..7caab106 100644 --- a/qse/lib/cmn/pio.c +++ b/qse/lib/cmn/pio.c @@ -991,8 +991,8 @@ int qse_pio_init ( } r = (i == QSE_PIO_IN)? - qse_tio_attachout (tio[i], pio_output, &pio->pin[i]): - qse_tio_attachin (tio[i], pio_input, &pio->pin[i]); + qse_tio_attachout (tio[i], pio_output, &pio->pin[i], QSE_NULL, 4096): + qse_tio_attachin (tio[i], pio_input, &pio->pin[i], QSE_NULL, 4096); if (r <= -1) goto oops; @@ -1563,7 +1563,7 @@ static qse_ssize_t pio_input (qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_ { qse_pio_pin_t* pin = (qse_pio_pin_t*)arg; QSE_ASSERT (pin != QSE_NULL); - if (cmd == QSE_TIO_IO_DATA) + if (cmd == QSE_TIO_DATA) { QSE_ASSERT (pin->self != QSE_NULL); return pio_read (pin->self, buf, size, pin->handle); @@ -1578,7 +1578,7 @@ static qse_ssize_t pio_output (qse_tio_cmd_t cmd, void* arg, void* buf, qse_size { qse_pio_pin_t* pin = (qse_pio_pin_t*)arg; QSE_ASSERT (pin != QSE_NULL); - if (cmd == QSE_TIO_IO_DATA) + if (cmd == QSE_TIO_DATA) { QSE_ASSERT (pin->self != QSE_NULL); return pio_write (pin->self, buf, size, pin->handle); diff --git a/qse/lib/cmn/sio.c b/qse/lib/cmn/sio.c index 446fc900..dca56484 100644 --- a/qse/lib/cmn/sio.c +++ b/qse/lib/cmn/sio.c @@ -25,10 +25,7 @@ static qse_ssize_t __sio_input (qse_tio_cmd_t cmd, void* arg, void* buf, qse_siz static qse_ssize_t __sio_output (qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size); #if defined(_WIN32) -# include -#elif defined(__OS2__) -# define INCL_DOSFILEMGR -# include +# include /* for the UGLY hack */ #endif qse_sio_t* qse_sio_open ( @@ -61,10 +58,22 @@ qse_sio_t* qse_sio_open ( qse_sio_t* qse_sio_openstd ( qse_mmgr_t* mmgr, qse_size_t xtnsize, qse_sio_std_t std, int flags) { + qse_sio_t* sio; qse_fio_hnd_t hnd; + if (qse_getstdfiohandle (std, &hnd) <= -1) return QSE_NULL; - return qse_sio_open (mmgr, xtnsize, + sio = qse_sio_open (mmgr, xtnsize, (const qse_char_t*)&hnd, flags | QSE_SIO_HANDLE | QSE_SIO_NOCLOSE); + +#if defined(_WIN32) + if (sio) + { + QSE_ASSERT (std >= 0 && std < QSE_TYPE_MAX(int)); + sio->status = std + 1; + } +#endif + + return sio; } void qse_sio_close (qse_sio_t* sio) @@ -87,7 +96,12 @@ int qse_sio_init ( mode = QSE_FIO_RUSR | QSE_FIO_WUSR | QSE_FIO_RGRP | QSE_FIO_ROTH; - if (qse_fio_init (&sio->fio, mmgr, file, flags, mode) <= -1) return -1; + /* sio flags redefines most fio flags. fio can be opened in the + * text mode. that way, fio is also buffered. since sio performs + * its own buffering, i don't want a caller to specify text mode + * flags accidentally. i mask off those bits here to avoid mishap. */ + if (qse_fio_init (&sio->fio, mmgr, file, + (flags & ~(QSE_FIO_TEXT|QSE_FIO_NOAUTOFLUSH)), mode) <= -1) return -1; if (flags & QSE_SIO_IGNOREMBWCERR) topt |= QSE_TIO_IGNOREMBWCERR; if (flags & QSE_SIO_NOAUTOFLUSH) topt |= QSE_TIO_NOAUTOFLUSH; @@ -98,8 +112,8 @@ int qse_sio_init ( return -1; } - if (qse_tio_attachin(&sio->tio, __sio_input, sio) <= -1 || - qse_tio_attachout(&sio->tio, __sio_output, sio) <= -1) + if (qse_tio_attachin (&sio->tio, __sio_input, sio, sio->inbuf, QSE_COUNTOF(sio->inbuf)) <= -1 || + qse_tio_attachout (&sio->tio, __sio_output, sio, sio->outbuf, QSE_COUNTOF(sio->outbuf)) <= -1) { qse_tio_fini (&sio->tio); qse_fio_fini (&sio->fio); @@ -112,10 +126,22 @@ int qse_sio_init ( int qse_sio_initstd ( qse_sio_t* sio, qse_mmgr_t* mmgr, qse_sio_std_t std, int flags) { + int n; qse_fio_hnd_t hnd; + if (qse_getstdfiohandle (std, &hnd) <= -1) return -1; - return qse_sio_init (sio, mmgr, - (const qse_char_t*)&hnd, flags | QSE_SIO_HANDLE); + n = qse_sio_init (sio, mmgr, + (const qse_char_t*)&hnd, flags | QSE_SIO_HANDLE | QSE_SIO_NOCLOSE); + +#if defined(_WIN32) + if (n >= 0) + { + QSE_ASSERT (std >= 0 && std < QSE_TYPE_MAX(int)); + sio->status = std + 1; + } +#endif + + return n; } void qse_sio_fini (qse_sio_t* sio) @@ -163,7 +189,14 @@ qse_ssize_t qse_sio_getmbs ( qse_ssize_t n; if (size <= 0) return 0; + +#if defined(_WIN32) + /* Using ReadConsoleA() didn't help at all. + * so I don't implement any hack here */ +#endif + n = qse_tio_readmbs (&sio->tio, buf, size - 1); + if (n <= -1) return -1; buf[n] = QSE_MT('\0'); return n; @@ -172,6 +205,11 @@ qse_ssize_t qse_sio_getmbs ( qse_ssize_t qse_sio_getmbsn ( qse_sio_t* sio, qse_mchar_t* buf, qse_size_t size) { +#if defined(_WIN32) + /* Using ReadConsoleA() didn't help at all. + * so I don't implement any hack here */ +#endif + return qse_tio_readmbs (&sio->tio, buf, size); } @@ -181,7 +219,14 @@ qse_ssize_t qse_sio_getwcs ( qse_ssize_t n; if (size <= 0) return 0; + +#if defined(_WIN32) + /* Using ReadConsoleA() didn't help at all. + * so I don't implement any hack here */ +#endif + n = qse_tio_readwcs (&sio->tio, buf, size - 1); + if (n <= -1) return -1; buf[n] = QSE_WT('\0'); return n; @@ -190,6 +235,10 @@ qse_ssize_t qse_sio_getwcs ( qse_ssize_t qse_sio_getwcsn ( qse_sio_t* sio, qse_wchar_t* buf, qse_size_t size) { +#if defined(_WIN32) + /* Using ReadConsoleW() didn't help at all. + * so I don't implement any hack here */ +#endif return qse_tio_readwcs (&sio->tio, buf, size); } @@ -205,23 +254,99 @@ qse_ssize_t qse_sio_putwc (qse_sio_t* sio, qse_wchar_t c) qse_ssize_t qse_sio_putmbs (qse_sio_t* sio, const qse_mchar_t* str) { - return qse_tio_writembs (&sio->tio, str, (qse_size_t)-1); -} +#if defined(_WIN32) + /* Using WriteConsoleA() didn't help at all. + * so I don't implement any hack here */ +#endif -qse_ssize_t qse_sio_putwcs (qse_sio_t* sio, const qse_wchar_t* str) -{ - return qse_tio_writewcs (&sio->tio, str, (qse_size_t)-1); + return qse_tio_writembs (&sio->tio, str, (qse_size_t)-1); } qse_ssize_t qse_sio_putmbsn ( qse_sio_t* sio, const qse_mchar_t* str, qse_size_t size) { +#if defined(_WIN32) + /* Using WriteConsoleA() didn't help at all. + * so I don't implement any hack here */ +#endif + return qse_tio_writembs (&sio->tio, str, size); } +qse_ssize_t qse_sio_putwcs (qse_sio_t* sio, const qse_wchar_t* str) +{ +#if defined(_WIN32) + /* DAMN UGLY: See comment in qse_sio_putwcsn() */ + if (sio->status) + { + DWORD mode; + + if (GetConsoleMode (sio->fio.handle, &mode) == FALSE) + { + return qse_tio_writewcs (&sio->tio, str, (qse_size_t)-1); + } + else + { + DWORD count, left; + const qse_wchar_t* cur; + if (qse_sio_flush (sio) <= -1) return -1; /* can't do buffering */ + for (cur = str, left = qse_wcslen(str); left > 0; cur += count, left -= count) + { + if (WriteConsoleW ( + sio->fio.handle, cur, left, + &count, QSE_NULL) == FALSE) return -1; + if (count == 0) break; + } + return cur - str; + } + } +#endif + + return qse_tio_writewcs (&sio->tio, str, (qse_size_t)-1); +} + qse_ssize_t qse_sio_putwcsn ( qse_sio_t* sio, const qse_wchar_t* str, qse_size_t size) { +#if defined(_WIN32) + /* DAMN UGLY: + * WriteFile returns wrong number of bytes written if it is + * requested to write a utf8 string on utf8 console (codepage 65001). + * it seems to return a number of characters written instead. so + * i have to use an alternate API for console output for + * wide-character strings. Conversion to either an OEM codepage or + * the utf codepage is handled by the API. This hack at least + * lets you do proper utf8 output on utf8 console using wide-character. + * + * Note that the multibyte functions qse_sio_putmbs() and + * qse_sio_putmbsn() doesn't handle this. So you may still suffer. + */ + if (sio->status) + { + DWORD mode; + + if (GetConsoleMode (sio->fio.handle, &mode) == FALSE) + { + return qse_tio_writewcs (&sio->tio, str, size); + } + else + { + DWORD count, left; + const qse_wchar_t* cur; + + if (qse_sio_flush (sio) <= -1) return -1; /* can't do buffering */ + for (cur = str, left = size; left > 0; cur += count, left -= count) + { + if (WriteConsoleW ( + sio->fio.handle, cur, left, + &count, QSE_NULL) == FALSE) return -1; + if (count == 0) break; + } + return cur - str; + } + } +#endif + return qse_tio_writewcs (&sio->tio, str, size); } @@ -271,7 +396,7 @@ static qse_ssize_t __sio_input ( QSE_ASSERT (sio != QSE_NULL); - if (cmd == QSE_TIO_IO_DATA) + if (cmd == QSE_TIO_DATA) { return qse_fio_read (&sio->fio, buf, size); } @@ -286,7 +411,7 @@ static qse_ssize_t __sio_output ( QSE_ASSERT (sio != QSE_NULL); - if (cmd == QSE_TIO_IO_DATA) + if (cmd == QSE_TIO_DATA) { return qse_fio_write (&sio->fio, buf, size); } diff --git a/qse/lib/cmn/tio-get.c b/qse/lib/cmn/tio-get.c index 1599f00f..c2f5de30 100644 --- a/qse/lib/cmn/tio-get.c +++ b/qse/lib/cmn/tio-get.c @@ -30,10 +30,10 @@ qse_ssize_t qse_tio_readmbs (qse_tio_t* tio, qse_mchar_t* buf, qse_size_t size) qse_size_t nread; qse_ssize_t n; - /*QSE_ASSERT (tio->input_func != QSE_NULL);*/ - if (tio->input_func == QSE_NULL) + /*QSE_ASSERT (tio->in.fun != QSE_NULL);*/ + if (tio->in.fun == QSE_NULL) { - tio->errnum = QSE_TIO_ENOINF; + tio->errnum = QSE_TIO_ENINPF; return -1; } @@ -49,13 +49,14 @@ qse_ssize_t qse_tio_readmbs (qse_tio_t* tio, qse_mchar_t* buf, qse_size_t size) { if (tio->inbuf_cur >= tio->inbuf_len) { - n = tio->input_func ( - QSE_TIO_IO_DATA, tio->input_arg, - tio->inbuf, QSE_COUNTOF(tio->inbuf)); + n = tio->in.fun ( + QSE_TIO_DATA, tio->in.arg, + tio->in.buf.ptr, + tio->in.buf.capa); if (n == 0) break; if (n <= -1) { - tio->errnum = QSE_TIO_EINPUT; + tio->errnum = QSE_TIO_EIOERR; return -1; } @@ -65,7 +66,7 @@ qse_ssize_t qse_tio_readmbs (qse_tio_t* tio, qse_mchar_t* buf, qse_size_t size) do { - buf[nread] = tio->inbuf[tio->inbuf_cur++]; + buf[nread] = tio->in.buf.ptr[tio->inbuf_cur++]; /* TODO: support a different line terminator */ if (buf[nread++] == QSE_MT('\n')) goto done; } @@ -92,9 +93,10 @@ static QSE_INLINE qse_ssize_t tio_read_widechars ( if (tio->input_status & STATUS_EOF) n = 0; else { - n = tio->input_func ( - QSE_TIO_IO_DATA, tio->input_arg, - &tio->inbuf[tio->inbuf_len], QSE_COUNTOF(tio->inbuf) - tio->inbuf_len); + n = tio->in.fun ( + QSE_TIO_DATA, tio->in.arg, + &tio->in.buf.ptr[tio->inbuf_len], + tio->in.buf.capa - tio->inbuf_len); } if (n == 0) { @@ -120,7 +122,7 @@ static QSE_INLINE qse_ssize_t tio_read_widechars ( } if (n <= -1) { - tio->errnum = QSE_TIO_EINPUT; + tio->errnum = QSE_TIO_EIOERR; return -1; } @@ -130,7 +132,9 @@ static QSE_INLINE qse_ssize_t tio_read_widechars ( mlen = tio->inbuf_len - tio->inbuf_cur; wlen = bufsize; - x = qse_mbsntowcsnupto (&tio->inbuf[tio->inbuf_cur], &mlen, buf, &wlen, QSE_WT('\n')); + x = qse_mbsntowcsnupto ( + &tio->in.buf.ptr[tio->inbuf_cur], + &mlen, buf, &wlen, QSE_WT('\n')); tio->inbuf_cur += mlen; if (x == -3) @@ -142,9 +146,9 @@ static QSE_INLINE qse_ssize_t tio_read_widechars ( * shift bytes in the buffer to the head. */ QSE_ASSERT (mlen <= 0); tio->inbuf_len = tio->inbuf_len - tio->inbuf_cur; - QSE_MEMCPY (&tio->inbuf[0], - &tio->inbuf[tio->inbuf_cur], - tio->inbuf_len * QSE_SIZEOF(tio->inbuf[0])); + QSE_MEMCPY (&tio->in.buf.ptr[0], + &tio->in.buf.ptr[tio->inbuf_cur], + tio->inbuf_len * QSE_SIZEOF(tio->in.buf.ptr[0])); tio->inbuf_cur = 0; goto getc_conv; /* and read more */ } @@ -192,10 +196,10 @@ qse_ssize_t qse_tio_readwcs (qse_tio_t* tio, qse_wchar_t* buf, qse_size_t size) qse_size_t nread = 0; qse_ssize_t n; - /*QSE_ASSERT (tio->input_func != QSE_NULL);*/ - if (tio->input_func == QSE_NULL) + /*QSE_ASSERT (tio->in.fun != QSE_NULL);*/ + if (tio->in.fun == QSE_NULL) { - tio->errnum = QSE_TIO_ENOINF; + tio->errnum = QSE_TIO_ENINPF; return -1; } diff --git a/qse/lib/cmn/tio-put.c b/qse/lib/cmn/tio-put.c index d5dd70f1..05af627d 100644 --- a/qse/lib/cmn/tio-put.c +++ b/qse/lib/cmn/tio-put.c @@ -24,7 +24,7 @@ qse_ssize_t qse_tio_writembs ( qse_tio_t* tio, const qse_mchar_t* mptr, qse_size_t mlen) { - if (tio->outbuf_len >= QSE_COUNTOF(tio->outbuf)) + if (tio->outbuf_len >= tio->out.buf.capa) { /* maybe, previous flush operation has failed a few * times previously. so the buffer is full. @@ -41,8 +41,8 @@ qse_ssize_t qse_tio_writembs ( { while (mptr[pos]) { - tio->outbuf[tio->outbuf_len++] = mptr[pos++]; - if (tio->outbuf_len >= QSE_COUNTOF(tio->outbuf) && + tio->out.buf.ptr[tio->outbuf_len++] = mptr[pos++]; + if (tio->outbuf_len >= tio->out.buf.capa && qse_tio_flush (tio) <= -1) return -1; if (pos >= QSE_TYPE_MAX(qse_ssize_t)) break; } @@ -52,8 +52,8 @@ qse_ssize_t qse_tio_writembs ( int nl = 0; while (mptr[pos]) { - tio->outbuf[tio->outbuf_len++] = mptr[pos]; - if (tio->outbuf_len >= QSE_COUNTOF(tio->outbuf)) + tio->out.buf.ptr[tio->outbuf_len++] = mptr[pos]; + if (tio->outbuf_len >= tio->out.buf.capa) { if (qse_tio_flush (tio) <= -1) return -1; nl = 0; @@ -79,10 +79,10 @@ qse_ssize_t qse_tio_writembs ( xptr = mptr; /* handle the parts that can't fit into the internal buffer */ - while (mlen >= (capa = QSE_COUNTOF(tio->outbuf) - tio->outbuf_len)) + while (mlen >= (capa = tio->out.buf.capa - tio->outbuf_len)) { for (xend = xptr + capa; xptr < xend; xptr++) - tio->outbuf[tio->outbuf_len++] = *xptr; + tio->out.buf.ptr[tio->outbuf_len++] = *xptr; if (qse_tio_flush (tio) <= -1) return -1; mlen -= capa; } @@ -91,7 +91,7 @@ qse_ssize_t qse_tio_writembs ( { /* handle the last part that can fit into the internal buffer */ for (xend = xptr + mlen; xptr < xend; xptr++) - tio->outbuf[tio->outbuf_len++] = *xptr; + tio->out.buf.ptr[tio->outbuf_len++] = *xptr; } else { @@ -99,14 +99,14 @@ qse_ssize_t qse_tio_writembs ( for (xend = xptr + mlen; xptr < xend; xptr++) { /* TODO: support different line terminating characeter */ - tio->outbuf[tio->outbuf_len++] = *xptr; + tio->out.buf.ptr[tio->outbuf_len++] = *xptr; if (*xptr == QSE_MT('\n')) { nl = 1; break; } } - while (xptr < xend) tio->outbuf[tio->outbuf_len++] = *xptr++; + while (xptr < xend) tio->out.buf.ptr[tio->outbuf_len++] = *xptr++; } /* if the last part contains a new line, flush the internal @@ -124,7 +124,7 @@ qse_ssize_t qse_tio_writewcs ( qse_size_t capa, wcnt, mcnt, xwlen; int n, nl = 0; - if (tio->outbuf_len >= QSE_COUNTOF(tio->outbuf)) + if (tio->outbuf_len >= tio->out.buf.capa) { /* maybe, previous flush operation has failed a few * times previously. so the buffer is full. @@ -139,11 +139,11 @@ qse_ssize_t qse_tio_writewcs ( xwlen = wlen; while (xwlen > 0) { - capa = QSE_COUNTOF(tio->outbuf) - tio->outbuf_len; + capa = tio->out.buf.capa - tio->outbuf_len; wcnt = xwlen; mcnt = capa; n = qse_wcsntombsn ( - wptr, &wcnt, &tio->outbuf[tio->outbuf_len], &mcnt); + wptr, &wcnt, &tio->out.buf.ptr[tio->outbuf_len], &mcnt); tio->outbuf_len += mcnt; if (n == -2) @@ -157,7 +157,7 @@ qse_ssize_t qse_tio_writewcs ( } else { - if (tio->outbuf_len >= QSE_COUNTOF(tio->outbuf)) + if (tio->outbuf_len >= tio->out.buf.capa) { /* flush the full buffer regardless of conversion * result. */ @@ -172,8 +172,8 @@ qse_ssize_t qse_tio_writewcs ( { /* insert a question mark for an illegal * character. */ - QSE_ASSERT (tio->outbuf_len < QSE_COUNTOF(tio->outbuf)); - tio->outbuf[tio->outbuf_len++] = QSE_MT('?'); + QSE_ASSERT (tio->outbuf_len < tio->out.buf.capa); + tio->out.buf.ptr[tio->outbuf_len++] = QSE_MT('?'); wcnt++; /* skip this illegal character */ /* don't need to increment mcnt since * it's not used below */ diff --git a/qse/lib/cmn/tio.c b/qse/lib/cmn/tio.c index 8a265c2a..b15fd676 100644 --- a/qse/lib/cmn/tio.c +++ b/qse/lib/cmn/tio.c @@ -23,6 +23,9 @@ QSE_IMPLEMENT_COMMON_FUNCTIONS (tio) +static int detach_in (qse_tio_t* tio, int fini); +static int detach_out (qse_tio_t* tio, int fini); + qse_tio_t* qse_tio_open (qse_mmgr_t* mmgr, qse_size_t xtnsize, int flags) { qse_tio_t* tio; @@ -63,7 +66,8 @@ int qse_tio_init (qse_tio_t* tio, qse_mmgr_t* mmgr, int flags) QSE_MEMSET (tio, 0, QSE_SIZEOF(*tio)); tio->mmgr = mmgr; - tio->flags = flags; + /* mask off internal bits when storing the flags for safety */ + tio->flags = flags & ~(QSE_TIO_DYNINBUF | QSE_TIO_DYNOUTBUF); /* tio->input_func = QSE_NULL; @@ -83,10 +87,13 @@ int qse_tio_init (qse_tio_t* tio, qse_mmgr_t* mmgr, int flags) int qse_tio_fini (qse_tio_t* tio) { + int ret = 0; + qse_tio_flush (tio); /* don't care about the result */ - if (qse_tio_detachin(tio) == -1) return -1; - if (qse_tio_detachout(tio) == -1) return -1; - return 0; + if (detach_in (tio, 1) <= -1) ret = -1; + if (detach_out (tio, 1) <= -1) ret = -1; + + return ret; } qse_tio_errnum_t qse_tio_geterrnum (qse_tio_t* tio) @@ -100,18 +107,14 @@ const qse_char_t* qse_tio_geterrmsg (qse_tio_t* tio) { QSE_T("no error"), QSE_T("out of memory"), + QSE_T("invalid parameter"), QSE_T("no more space"), QSE_T("illegal multibyte sequence"), QSE_T("incomplete multibyte sequence"), QSE_T("illegal wide character"), QSE_T("no input function attached"), - QSE_T("input function returned an error"), - QSE_T("input function failed to open"), - QSE_T("input function failed to closed"), QSE_T("no output function attached"), - QSE_T("output function returned an error"), - QSE_T("output function failed to open"), - QSE_T("output function failed to closed"), + QSE_T("I/O error"), QSE_T("unknown error") }; @@ -120,112 +123,219 @@ const qse_char_t* qse_tio_geterrmsg (qse_tio_t* tio) QSE_COUNTOF(__errmsg) - 1: tio->errnum]; } -int qse_tio_attachin (qse_tio_t* tio, qse_tio_io_t input, void* arg) +int qse_tio_attachin ( + qse_tio_t* tio, qse_tio_io_fun_t input, void* arg, + qse_mchar_t* bufptr, qse_size_t bufcapa) { - if (qse_tio_detachin(tio) == -1) return -1; + qse_mchar_t* xbufptr; - QSE_ASSERT (tio->input_func == QSE_NULL); - - if (input(QSE_TIO_IO_OPEN, arg, QSE_NULL, 0) == -1) + if (input == QSE_NULL || bufcapa < QSE_TIO_MININBUFCAPA) { - tio->errnum = QSE_TIO_EINPOP; + tio->errnum = QSE_TIO_EINVAL; return -1; } - tio->input_func = input; - tio->input_arg = arg; + if (qse_tio_detachin(tio) <= -1) return -1; + + QSE_ASSERT (tio->in.fun == QSE_NULL); + + xbufptr = bufptr; + if (xbufptr == QSE_NULL) + { + xbufptr = QSE_MMGR_ALLOC ( + tio->mmgr, QSE_SIZEOF(qse_mchar_t) * bufcapa); + if (xbufptr == QSE_NULL) + { + tio->errnum = QSE_TIO_ENOMEM; + return -1; + } + } + + if (input (QSE_TIO_OPEN, arg, QSE_NULL, 0) <= -1) + { + if (xbufptr != bufptr) QSE_MMGR_FREE (tio->mmgr, xbufptr); + tio->errnum = QSE_TIO_EIOERR; + return -1; + } + + /* if i defined tio->io[2] instead of tio->in and tio-out, + * i would be able to shorten code amount. but fields to initialize + * are not symmetric between input and output. + * so it's just a bit clumsy that i repeat almost the same code + * in qse_tio_attachout(). + */ + + tio->in.fun = input; + tio->in.arg = arg; + tio->in.buf.ptr = xbufptr; + tio->in.buf.capa = bufcapa; tio->input_status = 0; tio->inbuf_cur = 0; tio->inbuf_len = 0; + if (xbufptr != bufptr) tio->flags |= QSE_TIO_DYNINBUF; return 0; } +static int detach_in (qse_tio_t* tio, int fini) +{ + int ret = 0; + + if (tio->in.fun) + { + if (tio->in.fun ( + QSE_TIO_CLOSE, tio->in.arg, QSE_NULL, 0) <= -1) + { + tio->errnum = QSE_TIO_EIOERR; + + /* returning with an error here allows you to retry detaching */ + if (!fini) return -1; + + /* otherwise, you can't retry since the input handler information + * is reset below */ + ret = -1; + } + + if (tio->flags & QSE_TIO_DYNINBUF) + { + QSE_MMGR_FREE (tio->mmgr, tio->in.buf.ptr); + tio->flags &= ~QSE_TIO_DYNINBUF; + } + + tio->in.fun = QSE_NULL; + tio->in.arg = QSE_NULL; + tio->in.buf.ptr = QSE_NULL; + tio->in.buf.capa = 0; + } + + return ret; +} + int qse_tio_detachin (qse_tio_t* tio) { - if (tio->input_func != QSE_NULL) - { - if (tio->input_func ( - QSE_TIO_IO_CLOSE, tio->input_arg, QSE_NULL, 0) == -1) - { - tio->errnum = QSE_TIO_EINPCL; - return -1; - } - - tio->input_func = QSE_NULL; - tio->input_arg = QSE_NULL; - } - - return 0; + return detach_in (tio, 0); } -int qse_tio_attachout (qse_tio_t* tio, qse_tio_io_t output, void* arg) +int qse_tio_attachout ( + qse_tio_t* tio, qse_tio_io_fun_t output, void* arg, + qse_mchar_t* bufptr, qse_size_t bufcapa) { - if (qse_tio_detachout(tio) == -1) return -1; + qse_mchar_t* xbufptr; - QSE_ASSERT (tio->output_func == QSE_NULL); - - if (output(QSE_TIO_IO_OPEN, arg, QSE_NULL, 0) == -1) + if (output == QSE_NULL || bufcapa < QSE_TIO_MINOUTBUFCAPA) { - tio->errnum = QSE_TIO_EOUTOP; + tio->errnum = QSE_TIO_EINVAL; return -1; } - tio->output_func = output; - tio->output_arg = arg; + if (qse_tio_detachout(tio) == -1) return -1; + + QSE_ASSERT (tio->out.fun == QSE_NULL); + + xbufptr = bufptr; + if (xbufptr == QSE_NULL) + { + xbufptr = QSE_MMGR_ALLOC ( + tio->mmgr, QSE_SIZEOF(qse_mchar_t) * bufcapa); + if (xbufptr == QSE_NULL) + { + tio->errnum = QSE_TIO_ENOMEM; + return -1; + } + } + + if (output (QSE_TIO_OPEN, arg, QSE_NULL, 0) == -1) + { + if (xbufptr != bufptr) QSE_MMGR_FREE (tio->mmgr, xbufptr); + tio->errnum = QSE_TIO_EIOERR; + return -1; + } + + tio->out.fun = output; + tio->out.arg = arg; + tio->out.buf.ptr = xbufptr; + tio->out.buf.capa = bufcapa; + tio->outbuf_len = 0; + if (xbufptr != bufptr) tio->flags |= QSE_TIO_DYNOUTBUF; return 0; } +static int detach_out (qse_tio_t* tio, int fini) +{ + int ret = 0; + + if (tio->out.fun) + { + qse_tio_flush (tio); /* don't care about the result */ + + if (tio->out.fun ( + QSE_TIO_CLOSE, tio->out.arg, QSE_NULL, 0) <= -1) + { + tio->errnum = QSE_TIO_EIOERR; + /* returning with an error here allows you to retry detaching */ + if (!fini) return -1; + + /* otherwise, you can't retry since the input handler information + * is reset below */ + ret = -1; + } + + if (tio->flags & QSE_TIO_DYNOUTBUF) + { + QSE_MMGR_FREE (tio->mmgr, tio->out.buf.ptr); + tio->flags &= ~QSE_TIO_DYNOUTBUF; + } + + tio->out.fun = QSE_NULL; + tio->out.arg = QSE_NULL; + tio->out.buf.ptr = QSE_NULL; + tio->out.buf.capa = 0; + } + + return ret; +} + int qse_tio_detachout (qse_tio_t* tio) { - if (tio->output_func != QSE_NULL) - { - qse_tio_flush (tio); /* don't care about the result */ - - if (tio->output_func ( - QSE_TIO_IO_CLOSE, tio->output_arg, QSE_NULL, 0) == -1) - { - tio->errnum = QSE_TIO_EOUTCL; - return -1; - } - - tio->output_func = QSE_NULL; - tio->output_arg = QSE_NULL; - } - - return 0; + return detach_out (tio, 0); } qse_ssize_t qse_tio_flush (qse_tio_t* tio) { qse_size_t left, count; + qse_ssize_t n; + qse_mchar_t* cur; - if (tio->output_func == QSE_NULL) + if (tio->out.fun == QSE_NULL) { tio->errnum = QSE_TIO_ENOUTF; return (qse_ssize_t)-1; } left = tio->outbuf_len; + cur = tio->out.buf.ptr; while (left > 0) { - qse_ssize_t n; - - n = tio->output_func ( - QSE_TIO_IO_DATA, tio->output_arg, tio->outbuf, left); + n = tio->out.fun ( + QSE_TIO_DATA, tio->out.arg, cur, left); if (n <= -1) { + QSE_MEMCPY (tio->out.buf.ptr, cur, left); tio->outbuf_len = left; - tio->errnum = QSE_TIO_EOUTPT; + tio->errnum = QSE_TIO_EIOERR; return -1; } - if (n == 0) break; + if (n == 0) + { + QSE_MEMCPY (tio->out.buf.ptr, cur, left); + break; + } left -= n; - QSE_MEMCPY (tio->outbuf, &tio->inbuf[n], left); + cur += n; } count = tio->outbuf_len - left; diff --git a/qse/regress/awk/regress.out b/qse/regress/awk/regress.out index 5528e94d..9b89dc96 100644 --- a/qse/regress/awk/regress.out +++ b/qse/regress/awk/regress.out @@ -413,7 +413,7 @@ Mark 5.00 20 Mary 5.5 22 Susie 4.25 18 -------------------------------------------------------------------------------- -[CMD] qseawk --strictnaming=off --newline=on -o- -f lang-001.awk &1 +[CMD] qseawk --strictnaming=off --newline=on -d- -f lang-001.awk &1 -------------------------------------------------------------------------------- function f (__p0) { @@ -426,7 +426,7 @@ BEGIN { hello -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-002.awk &1 +[CMD] qseawk --newline=on -d- -f lang-002.awk &1 -------------------------------------------------------------------------------- function f (__p0) { @@ -939,7 +939,7 @@ my hello my hello ERROR: CODE 15 LINE 6 COLUMN 1 - block nested too deeply -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-003.awk &1 +[CMD] qseawk --newline=on -d- -f lang-003.awk &1 -------------------------------------------------------------------------------- function fn (__p0) { @@ -954,11 +954,11 @@ BEGIN { 50 -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-004.awk &1 +[CMD] qseawk --newline=on -d- -f lang-004.awk &1 -------------------------------------------------------------------------------- ERROR: CODE 42 LINE 3 COLUMN 9 - function 'a' redefined -------------------------------------------------------------------------------- -[CMD] qseawk --implicit=off --explicit=on --newline=on -o- -f lang-005.awk &1 +[CMD] qseawk --implicit=off --explicit=on --newline=on -d- -f lang-005.awk &1 -------------------------------------------------------------------------------- function a (__p0) { @@ -982,11 +982,11 @@ BEGIN { 50 100 -------------------------------------------------------------------------------- -[CMD] qseawk --implicit=off --explicit=on --newline=on -o- -f lang-006.awk &1 +[CMD] qseawk --implicit=off --explicit=on --newline=on -d- -f lang-006.awk &1 -------------------------------------------------------------------------------- ERROR: CODE 43 LINE 5 COLUMN 10 - global variable 'a' redefined -------------------------------------------------------------------------------- -[CMD] qseawk --implicit=on --explicit=on --newline=on -o- -f lang-007.awk &1 +[CMD] qseawk --implicit=on --explicit=on --newline=on -d- -f lang-007.awk &1 -------------------------------------------------------------------------------- global __g17; @@ -1005,7 +1005,7 @@ BEGIN { 20 30 -------------------------------------------------------------------------------- -[CMD] qseawk --implicit=off --explicit=on --newline=on -o- -f lang-008.awk &1 +[CMD] qseawk --implicit=off --explicit=on --newline=on -d- -f lang-008.awk &1 -------------------------------------------------------------------------------- global x; @@ -1027,7 +1027,7 @@ BEGIN { 2 1 -------------------------------------------------------------------------------- -[CMD] qseawk --implicit=off --explicit=on --newline=on --strictnaming=off -o- -f lang-009.awk lang-009.awk &1 +[CMD] qseawk --implicit=off --explicit=on --newline=on --strictnaming=off -d- -f lang-009.awk lang-009.awk &1 -------------------------------------------------------------------------------- function a (__p0) { @@ -1044,7 +1044,7 @@ END { } 1000 -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-010.awk this is just a test &1 +[CMD] qseawk --newline=on -d- -f lang-010.awk this is just a test &1 -------------------------------------------------------------------------------- BEGIN { print "ARGC=",ARGC; @@ -1101,7 +1101,7 @@ ARGC [+10124.1123000000] is positive [A ] [-000000000000000000000000000000000000000000000001] abc10 000000000000000000000000000040 g good K -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-011.awk &1 +[CMD] qseawk --newline=on -d- -f lang-011.awk &1 -------------------------------------------------------------------------------- BEGIN { a[1,2,3] = 20; @@ -1144,7 +1144,7 @@ BEGIN { (1,2,3) in a ==> 20 (4,5) not in a -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-012.awk &1 +[CMD] qseawk --newline=on -d- -f lang-012.awk &1 -------------------------------------------------------------------------------- BEGIN { OFS = " "; @@ -1345,7 +1345,7 @@ a < " " : 1 -0.123 122.877 -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-013.awk &1 +[CMD] qseawk --newline=on -d- -f lang-013.awk &1 -------------------------------------------------------------------------------- BEGIN { CONVFMT = "%s"; @@ -1354,7 +1354,7 @@ BEGIN { ERROR: CODE 103 LINE 3 COLUMN 2 - recursion detected in format conversion -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-014.awk &1 +[CMD] qseawk --newline=on -d- -f lang-014.awk &1 -------------------------------------------------------------------------------- BEGIN { a = (10 + 20); @@ -1365,11 +1365,11 @@ BEGIN { 30 30 30 -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-015.awk &1 +[CMD] qseawk --newline=on -d- -f lang-015.awk &1 -------------------------------------------------------------------------------- ERROR: CODE 15 LINE 3 COLUMN 50 - block nested too deeply -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-016.awk &1 +[CMD] qseawk --newline=on -d- -f lang-016.awk &1 -------------------------------------------------------------------------------- BEGIN { printf "[[[[[%s]]]]\n",sprintf("abc %s abc",sprintf("def %s %s",sprintf("%s %s %s","xyz",1.2342,"xyz"),sprintf("ttt %s tttt",123.12))); @@ -1379,7 +1379,7 @@ BEGIN { [[[[[abc def xyz 1.2342 xyz ttt 123.12 tttt abc]]]] [[[[ttt 123.12 tttt]]]] -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-017.awk &1 +[CMD] qseawk --newline=on -d- -f lang-017.awk &1 -------------------------------------------------------------------------------- function gety () { @@ -1430,7 +1430,7 @@ END { END OF PROGRAM END OF PROGRAM 2 -------------------------------------------------------------------------------- -[CMD] qseawk --call main --newline=on -o- -f lang-017.awk &1 +[CMD] qseawk --call main --newline=on -d- -f lang-017.awk &1 -------------------------------------------------------------------------------- function gety () { @@ -1479,31 +1479,31 @@ END { 0 2 -------------------------------------------------------------------------------- -[CMD] qseawk --explicit=on --newline=on -o- -f lang-018.awk &1 +[CMD] qseawk --explicit=on --newline=on -d- -f lang-018.awk &1 -------------------------------------------------------------------------------- ERROR: CODE 47 LINE 1 COLUMN 8 - duplicate global variable 'ARGV' -------------------------------------------------------------------------------- -[CMD] qseawk --explicit=on --newline=on -o- -f lang-019.awk &1 +[CMD] qseawk --explicit=on --newline=on -d- -f lang-019.awk &1 -------------------------------------------------------------------------------- ERROR: CODE 49 LINE 1 COLUMN 15 - '+' not a valid parameter name -------------------------------------------------------------------------------- -[CMD] qseawk --explicit=on --newline=on -o- -f lang-020.awk &1 +[CMD] qseawk --explicit=on --newline=on -d- -f lang-020.awk &1 -------------------------------------------------------------------------------- ERROR: CODE 50 LINE 1 COLUMN 8 - '+' not a valid variable name -------------------------------------------------------------------------------- -[CMD] qseawk --explicit=on --newline=on -o- -f lang-021.awk &1 +[CMD] qseawk --explicit=on --newline=on -d- -f lang-021.awk &1 -------------------------------------------------------------------------------- ERROR: CODE 50 LINE 3 COLUMN 8 - '+' not a valid variable name -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-022.awk &1 +[CMD] qseawk --newline=on -d- -f lang-022.awk &1 -------------------------------------------------------------------------------- ERROR: CODE 23 LINE 2 COLUMN 9 - left parenthesis expected in place of '=' -------------------------------------------------------------------------------- -[CMD] qseawk --explicit=on --newline=on -o- -f lang-023.awk &1 +[CMD] qseawk --explicit=on --newline=on -d- -f lang-023.awk &1 -------------------------------------------------------------------------------- ERROR: CODE 28 LINE 5 COLUMN 20 - colon expected in place of ';' -------------------------------------------------------------------------------- -[CMD] qseawk --explicit=on --newline=on -o- -f lang-024.awk &1 +[CMD] qseawk --explicit=on --newline=on -d- -f lang-024.awk &1 -------------------------------------------------------------------------------- BEGIN { local __l0; @@ -1513,7 +1513,7 @@ BEGIN { 1 -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-025.awk &1 +[CMD] qseawk --newline=on -d- -f lang-025.awk &1 -------------------------------------------------------------------------------- BEGIN { iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiix = 20; @@ -1522,7 +1522,7 @@ BEGIN { ERROR: CODE 78 LINE 3 COLUMN 9 - variable 'iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiix' not deletable -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-026.awk &1 +[CMD] qseawk --newline=on -d- -f lang-026.awk &1 -------------------------------------------------------------------------------- BEGIN { abc[20] = "abc"; @@ -1534,19 +1534,19 @@ BEGIN { abc ERROR: CODE 86 LINE 4 COLUMN 2 - map 'abc' not assignable with a scalar -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-027.awk &1 +[CMD] qseawk --newline=on -d- -f lang-027.awk &1 -------------------------------------------------------------------------------- ERROR: CODE 17 LINE 2 COLUMN 1 - invalid character '' -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-028.awk &1 +[CMD] qseawk --newline=on -d- -f lang-028.awk &1 -------------------------------------------------------------------------------- ERROR: CODE 41 LINE 2 COLUMN 10 - intrinsic function 'substr' redefined -------------------------------------------------------------------------------- -[CMD] qseawk --explicit=on --newline=on -o- -f lang-029.awk &1 +[CMD] qseawk --explicit=on --newline=on -d- -f lang-029.awk &1 -------------------------------------------------------------------------------- ERROR: CODE 42 LINE 9 COLUMN 9 - function 'abc' redefined -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-030.awk &1 +[CMD] qseawk --newline=on -d- -f lang-030.awk &1 -------------------------------------------------------------------------------- BEGIN { print (1 + 0); @@ -1598,7 +1598,7 @@ BEGIN { 0 0 -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-031.awk &1 +[CMD] qseawk --newline=on -d- -f lang-031.awk &1 -------------------------------------------------------------------------------- BEGIN { print match("hhhheeeo",/e+/); @@ -1632,7 +1632,7 @@ BEGIN { 0 -1 -------------------------- -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-032.awk &1 +[CMD] qseawk --newline=on -d- -f lang-032.awk &1 -------------------------------------------------------------------------------- BEGIN { a = 91; @@ -1654,7 +1654,7 @@ BEGIN { --------------------- 9210 -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-033.awk &1 +[CMD] qseawk --newline=on -d- -f lang-033.awk &1 -------------------------------------------------------------------------------- BEGIN { while ((("cat lang-033.awk" | getline x) > 0)) @@ -1666,7 +1666,7 @@ BEGIN { print x } -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on --rwpipe=on -o- -f lang-034.awk &1 +[CMD] qseawk --newline=on --rwpipe=on -d- -f lang-034.awk &1 -------------------------------------------------------------------------------- BEGIN { print "15" || "sort"; @@ -1687,7 +1687,7 @@ xx: 13 xx: 14 xx: 15 -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -vdatafile=lang-035.dat1 -vgroupname=lang-035 -f lang-035.awk lang-035.dat2 &1 +[CMD] qseawk --newline=on -d- -vdatafile=lang-035.dat1 -vgroupname=lang-035 -f lang-035.awk lang-035.dat2 &1 -------------------------------------------------------------------------------- BEGIN { max_cid_vars = 100; @@ -1931,7 +1931,7 @@ lease 10.218.255.151 { uid "\001\000\033[\234\220\000"; } -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-036.awk lang-036.dat &1 +[CMD] qseawk --newline=on -d- -f lang-036.awk lang-036.dat &1 -------------------------------------------------------------------------------- { if (($0 ~ /^-+$/)) @@ -1963,7 +1963,7 @@ pq...r AAA2 kbs ddd dif cccc -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-037.awk lang-037.dat &1 +[CMD] qseawk --newline=on -d- -f lang-037.awk lang-037.dat &1 -------------------------------------------------------------------------------- BEGIN { RS = "\n-+\n"; @@ -1991,7 +1991,7 @@ pq...r AAA2 kbs ddd dif cccc -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-038.awk &1 +[CMD] qseawk --newline=on -d- -f lang-038.awk &1 -------------------------------------------------------------------------------- BEGIN { xstr = "abcdefabcdefabcdef"; @@ -2020,7 +2020,7 @@ BEGIN { 7 abc 13 abc -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-039.awk &1 +[CMD] qseawk --newline=on -d- -f lang-039.awk &1 -------------------------------------------------------------------------------- BEGIN { print (length() 11); @@ -2030,7 +2030,7 @@ BEGIN { 011 2 -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-040.awk &1 +[CMD] qseawk --newline=on -d- -f lang-040.awk &1 -------------------------------------------------------------------------------- BEGIN { for (x in y) @@ -2038,7 +2038,7 @@ BEGIN { } -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-041.awk &1 +[CMD] qseawk --newline=on -d- -f lang-041.awk &1 -------------------------------------------------------------------------------- BEGIN { abc = 20; @@ -2047,7 +2047,7 @@ BEGIN { 2010 -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-042.awk &1 +[CMD] qseawk --newline=on -d- -f lang-042.awk &1 -------------------------------------------------------------------------------- BEGIN { print //; @@ -2087,7 +2087,7 @@ IGNORECASE= 1 1 1 -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-043.awk lang-043.dat &1 +[CMD] qseawk --newline=on -d- -f lang-043.awk lang-043.dat &1 -------------------------------------------------------------------------------- BEGIN { RS = "[ \n\v\f\r ]*[\r\n]+[ \n\v\f\r ]*"; @@ -2101,7 +2101,7 @@ abcd dcba j -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-044.awk lang-044.dat &1 +[CMD] qseawk --newline=on -d- -f lang-044.awk lang-044.dat &1 -------------------------------------------------------------------------------- BEGIN { RS = ""; @@ -2119,7 +2119,7 @@ this is the second second line] [ ttttt killer] -------------------------------------------------------------------------------- -[CMD] qseawk --newline=on -o- -f lang-045.awk &1 +[CMD] qseawk --newline=on -d- -f lang-045.awk &1 -------------------------------------------------------------------------------- BEGIN { for (i = (-(10.0)); (i < 10.0); (i)++) diff --git a/qse/regress/awk/regress.sh.in b/qse/regress/awk/regress.sh.in index e9482b81..9d07749a 100755 --- a/qse/regress/awk/regress.sh.in +++ b/qse/regress/awk/regress.sh.in @@ -126,52 +126,52 @@ PROGS=" unr-001.awk!unr.dat!! - lang-001.awk!!!--strictnaming=off --newline=on -o- - lang-002.awk!!!--newline=on -o- - lang-003.awk!!!--newline=on -o- - lang-004.awk!!!--newline=on -o- - lang-005.awk!!!--implicit=off --explicit=on --newline=on -o- - lang-006.awk!!!--implicit=off --explicit=on --newline=on -o- - lang-007.awk!!!--implicit=on --explicit=on --newline=on -o- - lang-008.awk!!!--implicit=off --explicit=on --newline=on -o- - lang-009.awk!lang-009.awk!!--implicit=off --explicit=on --newline=on --strictnaming=off -o- - lang-010.awk!this is just a test!!--newline=on -o- - lang-011.awk!!!--newline=on -o- - lang-012.awk!!!--newline=on -o- - lang-013.awk!!!--newline=on -o- - lang-014.awk!!!--newline=on -o- - lang-015.awk!!!--newline=on -o- - lang-016.awk!!!--newline=on -o- - lang-017.awk!!!--newline=on -o- - lang-017.awk!!!--call main --newline=on -o- - lang-018.awk!!!--explicit=on --newline=on -o- - lang-019.awk!!!--explicit=on --newline=on -o- - lang-020.awk!!!--explicit=on --newline=on -o- - lang-021.awk!!!--explicit=on --newline=on -o- - lang-022.awk!!!--newline=on -o- - lang-023.awk!!!--explicit=on --newline=on -o- - lang-024.awk!!!--explicit=on --newline=on -o- - lang-025.awk!!!--newline=on -o- - lang-026.awk!!!--newline=on -o- - lang-027.awk!!!--newline=on -o- - lang-028.awk!!!--newline=on -o- - lang-029.awk!!!--explicit=on --newline=on -o- - lang-030.awk!!!--newline=on -o- - lang-031.awk!!!--newline=on -o- - lang-032.awk!!!--newline=on -o- - lang-033.awk!!!--newline=on -o- - lang-034.awk!!!--newline=on --rwpipe=on -o- - lang-035.awk!lang-035.dat2!!--newline=on -o- -vdatafile=lang-035.dat1 -vgroupname=lang-035 - lang-036.awk!lang-036.dat!!--newline=on -o- - lang-037.awk!lang-037.dat!!--newline=on -o- - lang-038.awk!!!--newline=on -o- - lang-039.awk!!!--newline=on -o- - lang-040.awk!!!--newline=on -o- - lang-041.awk!!!--newline=on -o- - lang-042.awk!!!--newline=on -o- - lang-043.awk!lang-043.dat!!--newline=on -o- - lang-044.awk!lang-044.dat!!--newline=on -o- - lang-045.awk!!!--newline=on -o- + lang-001.awk!!!--strictnaming=off --newline=on -d- + lang-002.awk!!!--newline=on -d- + lang-003.awk!!!--newline=on -d- + lang-004.awk!!!--newline=on -d- + lang-005.awk!!!--implicit=off --explicit=on --newline=on -d- + lang-006.awk!!!--implicit=off --explicit=on --newline=on -d- + lang-007.awk!!!--implicit=on --explicit=on --newline=on -d- + lang-008.awk!!!--implicit=off --explicit=on --newline=on -d- + lang-009.awk!lang-009.awk!!--implicit=off --explicit=on --newline=on --strictnaming=off -d- + lang-010.awk!this is just a test!!--newline=on -d- + lang-011.awk!!!--newline=on -d- + lang-012.awk!!!--newline=on -d- + lang-013.awk!!!--newline=on -d- + lang-014.awk!!!--newline=on -d- + lang-015.awk!!!--newline=on -d- + lang-016.awk!!!--newline=on -d- + lang-017.awk!!!--newline=on -d- + lang-017.awk!!!--call main --newline=on -d- + lang-018.awk!!!--explicit=on --newline=on -d- + lang-019.awk!!!--explicit=on --newline=on -d- + lang-020.awk!!!--explicit=on --newline=on -d- + lang-021.awk!!!--explicit=on --newline=on -d- + lang-022.awk!!!--newline=on -d- + lang-023.awk!!!--explicit=on --newline=on -d- + lang-024.awk!!!--explicit=on --newline=on -d- + lang-025.awk!!!--newline=on -d- + lang-026.awk!!!--newline=on -d- + lang-027.awk!!!--newline=on -d- + lang-028.awk!!!--newline=on -d- + lang-029.awk!!!--explicit=on --newline=on -d- + lang-030.awk!!!--newline=on -d- + lang-031.awk!!!--newline=on -d- + lang-032.awk!!!--newline=on -d- + lang-033.awk!!!--newline=on -d- + lang-034.awk!!!--newline=on --rwpipe=on -d- + lang-035.awk!lang-035.dat2!!--newline=on -d- -vdatafile=lang-035.dat1 -vgroupname=lang-035 + lang-036.awk!lang-036.dat!!--newline=on -d- + lang-037.awk!lang-037.dat!!--newline=on -d- + lang-038.awk!!!--newline=on -d- + lang-039.awk!!!--newline=on -d- + lang-040.awk!!!--newline=on -d- + lang-041.awk!!!--newline=on -d- + lang-042.awk!!!--newline=on -d- + lang-043.awk!lang-043.dat!!--newline=on -d- + lang-044.awk!lang-044.dat!!--newline=on -d- + lang-045.awk!!!--newline=on -d- columnate.awk!passwd.dat!!--newline=on -F: levenshtein-utests.awk!!!--newline=on --include=on @@ -183,15 +183,15 @@ PROGS=" wordfreq.awk!wordfreq.awk!! hanoi.awk!!! indent.awk!indent.dat!! - lisp/awklisp!lisp/startup lisp/fib.lsp!!-o- - lisp/awklisp!lisp/startup lisp/numbers lisp/numbers.dat!!-o- - lisp/awklisp!lisp/startup lisp/scmhelp.lsp lisp/tail.lsp!!-o- - lisp/awklisp!lisp/startup lisp/scmhelp.lsp lisp/scheme.lsp!!-o- + lisp/awklisp!lisp/startup lisp/fib.lsp!!-d- + lisp/awklisp!lisp/startup lisp/numbers lisp/numbers.dat!!-d- + lisp/awklisp!lisp/startup lisp/scmhelp.lsp lisp/tail.lsp!!-d- + lisp/awklisp!lisp/startup lisp/scmhelp.lsp lisp/scheme.lsp!!-d- " # # I can't include this as eliza.lsp gives different output on each run. -# lisp/awklisp!lisp/startup lisp/lists lisp/eliza.lsp lisp/eliza.dat!!-o- +# lisp/awklisp!lisp/startup lisp/lists lisp/eliza.lsp lisp/eliza.dat!!-d- # [ -x "${QSEAWK}" ] || @@ -239,7 +239,7 @@ run_scripts() [ -f "${datafile_path}" ] || datafile_path="$datafile" echo_title "${valgrind} ${QSEAWK_BASENAME} ${extraopts} ${awkopts} -f ${orgscript} ${datafile} <${readinfile} 2>&1" - ${valgrind} ${QSEAWK} ${extraopts} -o "${script}.dp" ${awkopts} -f ${script_path} ${datafile_path} <${readinfile_path} 2>&1 + ${valgrind} ${QSEAWK} ${extraopts} -d "${script}.dp" ${awkopts} -f ${script_path} ${datafile_path} <${readinfile_path} 2>&1 done < "${TMPFILE}" diff --git a/qse/samples/cmn/sio01.c b/qse/samples/cmn/sio01.c index d2792aeb..cb862f1a 100644 --- a/qse/samples/cmn/sio01.c +++ b/qse/samples/cmn/sio01.c @@ -7,13 +7,14 @@ # include #endif +static qse_sio_t* g_out; #define R(f) \ do { \ - qse_printf (QSE_T("== ")); \ - qse_printf (QSE_T(#f)); \ - qse_printf (QSE_T(" ==\n")); \ - qse_fflush (QSE_STDOUT); \ + qse_sio_putstr (g_out,QSE_T("== ")); \ + qse_sio_putstr (g_out,QSE_T(#f)); \ + qse_sio_putstr (g_out,QSE_T(" ==\n")); \ + qse_sio_flush (g_out); \ if (f() == -1) return -1; \ } while (0) @@ -61,11 +62,11 @@ static int test1 (void) for (i = 0; i < QSE_COUNTOF(x); i++) { - qse_printf (QSE_T("written: [")); - qse_printf (x[i]); - qse_printf (QSE_T("]\n")); + qse_sio_putstr (g_out, QSE_T("Written [")); + qse_sio_putwcs (g_out, x[i]); + qse_sio_putstr (g_out, QSE_T("]\n")); - qse_sio_putstr (sio, x[i]); + qse_sio_putwcs (sio, x[i]); qse_sio_putc (sio, QSE_T('\n')); } @@ -141,23 +142,27 @@ static int test3 (void) int main () { +#if 0 #if defined(_WIN32) UINT old_cp = GetConsoleOutputCP(); SetConsoleOutputCP (CP_UTF8); +#endif #endif setlocale (LC_ALL, ""); - qse_printf (QSE_T("--------------------------------------------------------------------------------\n")); - qse_printf (QSE_T("Set the environment LANG to a Unicode locale such as UTF-8 if you see the illegal XXXXX errors. If you see such errors in Unicode locales, this program might be buggy. It is normal to see such messages in non-Unicode locales as it uses Unicode data\n")); - qse_printf (QSE_T("--------------------------------------------------------------------------------\n")); + g_out = qse_sio_openstd (QSE_NULL, 0, QSE_SIO_STDOUT, QSE_SIO_WRITE | QSE_SIO_IGNOREMBWCERR); R (test1); R (test2); R (test3); + qse_sio_close (g_out); + +#if 0 #if defined(_WIN32) SetConsoleOutputCP (old_cp); +#endif #endif return 0; }