From 70090bc117972868c3e4b101d9246e17083a9b2b Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Fri, 6 Jan 2012 14:38:11 +0000 Subject: [PATCH] changed qse_awk_parsestd_t and related code. changed to use windows API for WIN32 in slmb.c --- qse/cmd/awk/awk.c | 26 +-- qse/cmd/sed/sed.c | 30 ++-- qse/doc/page/mem.doc | 2 - qse/include/qse/awk/std.h | 48 ++---- qse/include/qse/cmn/slmb.h | 8 +- qse/include/qse/cmn/utf8.h | 54 ++++-- qse/include/qse/sed/std.h | 33 ++-- qse/include/qse/types.h | 7 +- qse/lib/awk/StdAwk.cpp | 2 +- qse/lib/awk/std.c | 338 +++++++++++++++++-------------------- qse/lib/cmn/slmb.c | 172 +++++++++++++------ qse/lib/cmn/utf8.c | 149 ++++++---------- qse/lib/cut/std.c | 51 ++++-- qse/lib/sed/std.c | 168 ++++++++++++------ qse/samples/awk/awk01.c | 7 +- qse/samples/awk/awk02.c | 22 +-- qse/samples/awk/awk03.c | 7 +- qse/samples/awk/awk04.c | 7 +- qse/samples/awk/awk09.c | 7 +- qse/samples/awk/awk10.c | 7 +- qse/samples/cmn/slmb01.c | 37 +++- qse/samples/sed/sed01.c | 4 +- 22 files changed, 665 insertions(+), 521 deletions(-) diff --git a/qse/cmd/awk/awk.c b/qse/cmd/awk/awk.c index 30e06e16..86c2b201 100644 --- a/qse/cmd/awk/awk.c +++ b/qse/cmd/awk/awk.c @@ -30,7 +30,6 @@ #include #include - #include #include #include @@ -69,7 +68,6 @@ struct arg_t } isp; qse_size_t isfl; /* the number of input source files */ - qse_awk_parsestd_type_t ost; /* output source type */ qse_char_t* osf; /* output source file */ qse_char_t** icf; /* input console files */ @@ -678,7 +676,7 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg) } /* the source code is the string, not from the file */ - arg->ist = QSE_AWK_PARSESTD_CP; + arg->ist = QSE_AWK_PARSESTD_STR; arg->isp.str = argv[opt.ind++]; free (isf); @@ -714,7 +712,6 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg) icf[icfl] = QSE_NULL; } - arg->ost = QSE_AWK_PARSESTD_FILE; arg->osf = osf; arg->icf = icf; @@ -855,8 +852,8 @@ static int awk_main (int argc, qse_char_t* argv[]) int ret = -1; /* TODO: change it to support multiple source files */ - qse_awk_parsestd_in_t psin; - qse_awk_parsestd_out_t psout; + qse_awk_parsestd_t psin; + qse_awk_parsestd_t psout; qse_mmgr_t* mmgr = QSE_MMGR_GETDFL(); memset (&arg, 0, QSE_SIZEOF(arg)); @@ -869,13 +866,22 @@ static int awk_main (int argc, qse_char_t* argv[]) } psin.type = arg.ist; - if (arg.ist == QSE_AWK_PARSESTD_CP) psin.u.cp = arg.isp.str; - else psin.u.file = arg.isp.files[0]; + if (arg.ist == QSE_AWK_PARSESTD_STR) + { + psin.u.str.ptr = arg.isp.str; + psin.u.str.len = qse_strlen(arg.isp.str); + } + else + { + psin.u.file.path = arg.isp.files[0]; + psin.u.file.cmgr = QSE_NULL; + } if (arg.osf != QSE_NULL) { - psout.type = arg.ost; - psout.u.file = arg.osf; + psout.type = QSE_AWK_PARSESTD_FILE; + psout.u.file.path = arg.osf; + psout.u.file.cmgr = QSE_NULL; } #if defined(QSE_BUILD_DEBUG) diff --git a/qse/cmd/sed/sed.c b/qse/cmd/sed/sed.c index b7102f31..c1a008b3 100644 --- a/qse/cmd/sed/sed.c +++ b/qse/cmd/sed/sed.c @@ -184,17 +184,18 @@ static int add_script (const qse_char_t* str, int mem) if (mem) { - g_script.io[g_script.size].type = QSE_SED_IOSTD_MEM; + g_script.io[g_script.size].type = QSE_SED_IOSTD_STR; /* though its type is not qualified to be const, * u.mem.ptr is actually const when used for input */ - g_script.io[g_script.size].u.mem.ptr = (qse_char_t*)str; - g_script.io[g_script.size].u.mem.len = qse_strlen(str); + g_script.io[g_script.size].u.str.ptr = (qse_char_t*)str; + g_script.io[g_script.size].u.str.len = qse_strlen(str); } else { g_script.io[g_script.size].type = QSE_SED_IOSTD_FILE; - g_script.io[g_script.size].u.file = + g_script.io[g_script.size].u.file.path = (qse_strcmp (str, QSE_T("-")) == 0)? QSE_NULL: str; + g_script.io[g_script.size].u.file.cmgr = QSE_NULL; } g_script.size++; return 0; @@ -589,12 +590,12 @@ int sed_main (int argc, qse_char_t* argv[]) if (g_script.io[script_count].type == QSE_SED_IOSTD_FILE) { - target = g_script.io[script_count].u.file; + target = g_script.io[script_count].u.file.path; } else { /* i dont' use QSE_SED_IOSTD_SIO for input */ - QSE_ASSERT (g_script.io[script_count].type == QSE_SED_IOSTD_MEM); + QSE_ASSERT (g_script.io[script_count].type == QSE_SED_IOSTD_STR); qse_sprintf (exprbuf, QSE_COUNTOF(exprbuf), QSE_T("expression #%lu"), (unsigned long)script_count); target = exprbuf; @@ -663,15 +664,16 @@ int sed_main (int argc, qse_char_t* argv[]) qse_char_t* tmpl_tmpfile; in[0].type = QSE_SED_IOSTD_FILE; - in[0].u.file = + in[0].u.file.path = (qse_strcmp (argv[g_infile_pos], QSE_T("-")) == 0)? QSE_NULL: argv[g_infile_pos]; + in[0].u.file.cmgr = QSE_NULL; in[1].type = QSE_SED_IOSTD_NULL; tmpl_tmpfile = QSE_NULL; - if (g_inplace && in[0].u.file) + if (g_inplace && in[0].u.file.path) { - tmpl_tmpfile = qse_strdup2 (in[0].u.file, QSE_T(".XXXX"), qse_sed_getmmgr(sed)); + tmpl_tmpfile = qse_strdup2 (in[0].u.file.path, QSE_T(".XXXX"), qse_sed_getmmgr(sed)); if (tmpl_tmpfile == QSE_NULL) { qse_fprintf (QSE_STDERR, QSE_T("ERROR: out of memory\n")); @@ -721,10 +723,10 @@ TODO: qse_sio_close (output->u.sio); output = output_file; - if (qse_fs_move (fs, tmpl_tmpfile, in[0].u.file) <= -1) + if (qse_fs_move (fs, tmpl_tmpfile, in[0].u.file.path) <= -1) { qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot rename %s to %s. not deleting %s - %s\n"), - tmpl_tmpfile, in[0].u.file, tmpl_tmpfile, qse_fs_geterrmsg(fs)); + tmpl_tmpfile, in[0].u.file.path, tmpl_tmpfile, qse_fs_geterrmsg(fs)); QSE_MMGR_FREE (qse_sed_getmmgr(sed), tmpl_tmpfile); goto oops; } @@ -762,9 +764,10 @@ TODO: for (i = 0; i < num_ins; i++) { in[i].type = QSE_SED_IOSTD_FILE; - in[i].u.file = + in[i].u.file.path = (qse_strcmp (argv[g_infile_pos], QSE_T("-")) == 0)? QSE_NULL: argv[g_infile_pos]; + in[i].u.file.cmgr = QSE_NULL; g_infile_pos++; } @@ -774,9 +777,10 @@ TODO: if (g_output_file) { out.type = QSE_SED_IOSTD_FILE; - out.u.file = + out.u.file.path = (qse_strcmp (g_output_file, QSE_T("-")) == 0)? QSE_NULL: g_output_file; + out.u.file.cmgr = QSE_NULL; } g_sed = sed; diff --git a/qse/doc/page/mem.doc b/qse/doc/page/mem.doc index 1b4cc985..d641fa78 100644 --- a/qse/doc/page/mem.doc +++ b/qse/doc/page/mem.doc @@ -4,8 +4,6 @@ A memory manager is an instance of a structure type #qse_mmgr_t. Creating and/or initializing an object requires a memory manager to be passed in. -If you pass in #QSE_NULL for a memory manager, the object is created and/or -initialized with the default memory manager. The default memory manager is merely a wrapper to memory allocation functions provided by underlying operating systems: HeapAlloc/HeapReAlloc/HeapFree diff --git a/qse/include/qse/awk/std.h b/qse/include/qse/awk/std.h index b42110a3..ab970d95 100644 --- a/qse/include/qse/awk/std.h +++ b/qse/include/qse/awk/std.h @@ -22,6 +22,7 @@ #define _QSE_AWK_STD_H_ #include +#include /** @file * This file defines functions and data types that help you create @@ -38,49 +39,34 @@ * This programs shows how to specify multiple console output files. */ -/** - * The qse_awk_parsestd_type_t type defines a source script type - */ enum qse_awk_parsestd_type_t { - QSE_AWK_PARSESTD_FILE = 0, /**< file name */ - QSE_AWK_PARSESTD_CP = 1, /**< character pointer */ - QSE_AWK_PARSESTD_CPL = 2, /**< character pointer + length */ - QSE_AWK_PARSESTD_STDIO = 3 /**< standard input/output */ + QSE_AWK_PARSESTD_FILE = 1, + QSE_AWK_PARSESTD_STR = 2 }; + typedef enum qse_awk_parsestd_type_t qse_awk_parsestd_type_t; /** - * The qse_awk_parsestd_in_t type defines a source input. + * The qse_awk_parsestd_t type defines a source I/O. */ -struct qse_awk_parsestd_in_t +struct qse_awk_parsestd_t { qse_awk_parsestd_type_t type; union { - const qse_char_t* file; - const qse_char_t* cp; - qse_cstr_t cpl; + qse_sio_t* sio; + struct + { + const qse_char_t* path; + qse_cmgr_t* cmgr; + } file; + qse_xstr_t str; } u; }; -typedef struct qse_awk_parsestd_in_t qse_awk_parsestd_in_t; -/** - * The qse_awk_parsestd_out_t type defines a source output. - */ -struct qse_awk_parsestd_out_t -{ - qse_awk_parsestd_type_t type; - - union - { - const qse_char_t* file; - qse_char_t* cp; - qse_xstr_t cpl; - } u; -}; -typedef struct qse_awk_parsestd_out_t qse_awk_parsestd_out_t; +typedef struct qse_awk_parsestd_t qse_awk_parsestd_t; #ifdef __cplusplus extern "C" { @@ -136,9 +122,9 @@ void* qse_awk_getxtnstd ( * @endcode */ int qse_awk_parsestd ( - qse_awk_t* awk, - const qse_awk_parsestd_in_t* in, - qse_awk_parsestd_out_t* out + qse_awk_t* awk, + qse_awk_parsestd_t* in, + qse_awk_parsestd_t* out ); /** diff --git a/qse/include/qse/cmn/slmb.h b/qse/include/qse/cmn/slmb.h index e5fe60a7..aeecc92b 100644 --- a/qse/include/qse/cmn/slmb.h +++ b/qse/include/qse/cmn/slmb.h @@ -24,6 +24,12 @@ #include #include +/** @file + * This file provides functions, types, macros for + * multibyte/wide-character conversion based on system locale. + * + * + */ /** * The qse_mbstate_t type defines a structure large enough to hold @@ -114,7 +120,7 @@ qse_size_t qse_slmblen ( * The qse_slmblenmax() function returns the value of MB_CUR_MAX. * Note that QSE_MBLEN_MAX defines MB_LEN_MAX. */ -int qse_slmblenmax ( +qse_size_t qse_slmblenmax ( void ); diff --git a/qse/include/qse/cmn/utf8.h b/qse/include/qse/cmn/utf8.h index 951fea45..19bf55c7 100644 --- a/qse/include/qse/cmn/utf8.h +++ b/qse/include/qse/cmn/utf8.h @@ -24,6 +24,14 @@ #include #include +/** @file + * This file provides functions, types, macros for utf8 conversion. + */ + +/** + * The QSE_UTF8LEN_MAX macro defines the maximum number of bytes + * needed to form a single unicode character. + */ #if QSE_SIZEOF_WCHAR_T == 2 # define QSE_UTF8LEN_MAX 3 #elif QSE_SIZEOF_WCHAR_T == 4 @@ -36,24 +44,19 @@ extern "C" { #endif -/** - * The qse_uctoutf8len() function returns the number bytes in the utf8 sequence - * that would result from the original unicode character. - * @return - * - 0 is returned if @a uc is invalid. - * - A positive integer is returned in all other cases. - */ -qse_size_t qse_uctoutf8len ( - qse_wchar_t uc -); - /** * The qse_uctoutf8() function converts a unicode character to a utf8 sequence. * @return * - 0 is returned if @a uc is invalid. - * - An integer greater than @a size is returned if the utf8 sequence buffer is - * not large enough. + * - An integer greater than @a size is returned if the @a utf8 sequence buffer + * is not #QSE_NULL and not large enough. This integer is actually the number + * of bytes needed. + * - If @a utf8 is #QSE_NULL, the number of bytes that would have been stored + * into @a utf8 if it had not been #QSE_NULL is returned. * - An integer between 1 and size inclusive is returned in all other cases. + * @note + * This function doesn't check invalid unicode code points and performs + * conversion compuationally. */ qse_size_t qse_uctoutf8 ( qse_wchar_t uc, @@ -61,17 +64,40 @@ qse_size_t qse_uctoutf8 ( qse_size_t size ); +/** + * The qse_utf8touc() function converts a utf8 sequence to a unicode character. + * @return + * - 0 is returned if the @a utf8 sequence is invalid. + * - An integer greater than @a size is returned if the @a utf8 sequence is + * not complete. + * - An integer between 1 and size inclusive is returned in all other cases. + */ qse_size_t qse_utf8touc ( const qse_mchar_t* utf8, qse_size_t size, qse_wchar_t* uc ); +/** + * The qse_utf8lenmax() function scans at most @a size bytes from the @a utf8 + * sequence and returns the number of bytes needed to form a single unicode + * character. + * @return + * - 0 is returned if the @a utf8 sequence is invalid. + * - An integer greater than @a size is returned if the @a utf8 sequence is + * not complete. + * - An integer between 1 and size inclusive is returned in all other cases. + */ qse_size_t qse_utf8len ( const qse_mchar_t* utf8, - qse_size_t len + qse_size_t size ); +/** + * The qse_utf8lenmax() function returns the maximum number of bytes needed + * to form a single unicode character. Use #QSE_UTF8LEN_MAX if you need a + * compile-time constant. + */ qse_size_t qse_utf8lenmax ( void ); diff --git a/qse/include/qse/sed/std.h b/qse/include/qse/sed/std.h index 6a722c7e..d8cefce1 100644 --- a/qse/include/qse/sed/std.h +++ b/qse/include/qse/sed/std.h @@ -46,16 +46,20 @@ struct qse_sed_iostd_t enum { QSE_SED_IOSTD_NULL, /** invalid resource */ - QSE_SED_IOSTD_SIO, QSE_SED_IOSTD_FILE, - QSE_SED_IOSTD_MEM + QSE_SED_IOSTD_STR, + QSE_SED_IOSTD_SIO } type; union { + struct + { + const qse_char_t* path; + qse_cmgr_t* cmgr; + } file; + qse_xstr_t str; qse_sio_t* sio; - const qse_char_t* file; - qse_xstr_t mem; } u; }; @@ -113,22 +117,28 @@ int qse_sed_compstd ( /** * The qse_sed_compstdfile() function compiles a sed script from - * a single file @a infile. + * a single file @a infile. If @a infile is #QSE_NULL, it reads + * the script from the standard input. + * When #QSE_CHAR_IS_WCHAR is defined, it converts the multibyte + * sequences in the file @a infile to wide characters via the + * #qse_cmgr_t interface @a cmgr. If @a cmgr is #QSE_NULL, it uses + * the default interface. It calls cmgr->mbtowc() for conversion. * @return 0 on success, -1 on failure */ int qse_sed_compstdfile ( qse_sed_t* sed, - const qse_char_t* infile + const qse_char_t* infile, + qse_cmgr_t* cmgr ); /** - * The qse_sed_compstdmem() function compiles a sed script stored - * in a null-terminated string pointed to by @a str. + * The qse_sed_compstd() function compiles a sed script stored + * in a null-terminated string pointed to by @a script. * @return 0 on success, -1 on failure */ -int qse_sed_compstdmem ( +int qse_sed_compstdstr ( qse_sed_t* sed, - const qse_char_t* str + const qse_char_t* script ); /** @@ -164,7 +174,8 @@ int qse_sed_execstd ( int qse_sed_execstdfile ( qse_sed_t* sed, const qse_char_t* infile, - const qse_char_t* outfile + const qse_char_t* outfile, + qse_cmgr_t* cmgr ); #ifdef __cplusplus diff --git a/qse/include/qse/types.h b/qse/include/qse/types.h index 2809db31..ced01111 100644 --- a/qse/include/qse/types.h +++ b/qse/include/qse/types.h @@ -697,7 +697,7 @@ typedef void* (*qse_mmgr_realloc_t) (void* ctx, void* ptr, qse_size_t n); typedef void (*qse_mmgr_free_t) (void* ctx, void* ptr); /** - * The qse_mmgr_t type defines a set of functions for memory management. + * The qse_mmgr_t type defines the memory management interface. * As the type is merely a structure, it is just used as a single container * for memory management functions with a pointer to user-defined data. * The user-defined data pointer @a ctx is passed to each memory management @@ -730,7 +730,10 @@ typedef qse_size_t (*qse_cmgr_wctomb_t) ( /** * The qse_cmgr_t type defines the character-level interface to - * multibyte/wide-character string conversion. + * multibyte/wide-character conversion. This interface doesn't + * provide any facility to store conversion state in a context + * independent manner. This leads to the limitation that it can + * handle a stateless multibyte encoding only. */ struct qse_cmgr_t { diff --git a/qse/lib/awk/StdAwk.cpp b/qse/lib/awk/StdAwk.cpp index cafe142f..91f4585f 100644 --- a/qse/lib/awk/StdAwk.cpp +++ b/qse/lib/awk/StdAwk.cpp @@ -169,7 +169,7 @@ int StdAwk::openPipe (Pipe& io) { Awk::Pipe::Mode mode = io.getMode(); qse_pio_t* pio = QSE_NULL; - int flags = QSE_PIO_TEXT | QSE_PIO_SHELL; + int flags = QSE_PIO_TEXT | QSE_PIO_SHELL | QSE_PIO_IGNOREMBWCERR; switch (mode) { diff --git a/qse/lib/awk/std.c b/qse/lib/awk/std.c index f068e3f3..b3a1907b 100644 --- a/qse/lib/awk/std.c +++ b/qse/lib/awk/std.c @@ -58,36 +58,40 @@ typedef struct xtn_t { struct { - qse_awk_parsestd_type_t type; + qse_awk_parsestd_t* x; union { - const qse_char_t* file; - const qse_char_t* cp; + struct + { + qse_sio_t* sio; /* the handle to an open file */ + qse_cstr_t dir; + } file; struct { const qse_char_t* ptr; const qse_char_t* end; - } cpl; + } str; } u; - qse_cstr_t dir; - qse_sio_t* handle; /* the handle to an open file */ } in; struct { - qse_awk_parsestd_type_t type; + qse_awk_parsestd_t* x; union { - const qse_char_t* file; - qse_char_t* cp; + struct + { + qse_sio_t* sio; + } file; struct { - qse_xstr_t* osp; + qse_str_t* buf; +#if 0 qse_char_t* ptr; qse_char_t* end; - } cpl; +#endif + } str; } u; - qse_sio_t* handle; } out; } s; @@ -337,11 +341,17 @@ static qse_sio_t* open_sio_rtx (qse_awk_rtx_t* rtx, const qse_char_t* file, int return sio; } -static const qse_char_t* sio_std_names[] = +struct sio_std_name_t { - QSE_T("stdin"), - QSE_T("stdout"), - QSE_T("stderr"), + const qse_char_t* ptr; + qse_size_t len; +}; + +static struct sio_std_name_t sio_std_names[] = +{ + { QSE_T("stdin"), 5 }, + { QSE_T("stdout"), 6 }, + { QSE_T("stderr"), 6 } }; static qse_sio_t* open_sio_std (qse_awk_t* awk, qse_sio_std_t std, int flags) @@ -351,8 +361,8 @@ static qse_sio_t* open_sio_std (qse_awk_t* awk, qse_sio_std_t std, int flags) if (sio == QSE_NULL) { qse_cstr_t ea; - ea.ptr = sio_std_names[std]; - ea.len = qse_strlen (sio_std_names[std]); + ea.ptr = sio_std_names[std].ptr; + ea.len = sio_std_names[std].len; qse_awk_seterrnum (awk, QSE_AWK_EOPEN, &ea); } return sio; @@ -366,8 +376,8 @@ static qse_sio_t* open_sio_std_rtx (qse_awk_rtx_t* rtx, qse_sio_std_t std, int f if (sio == QSE_NULL) { qse_cstr_t ea; - ea.ptr = sio_std_names[std]; - ea.len = qse_strlen (sio_std_names[std]); + ea.ptr = sio_std_names[std].ptr; + ea.len = sio_std_names[std].len; qse_awk_rtx_seterrnum (rtx, QSE_AWK_EOPEN, &ea); } return sio; @@ -379,47 +389,42 @@ static qse_ssize_t sf_in_open ( { if (arg == QSE_NULL || arg->name == QSE_NULL) { - switch (xtn->s.in.type) + switch (xtn->s.in.x->type) { case QSE_AWK_PARSESTD_FILE: - if (xtn->s.in.u.file == QSE_NULL) return -1; - - if (xtn->s.in.u.file[0] == QSE_T('-') && - xtn->s.in.u.file[1] == QSE_T('\0')) + if (xtn->s.in.x->u.file.path == QSE_NULL || + (xtn->s.in.x->u.file.path[0] == QSE_T('-') && + xtn->s.in.x->u.file.path[1] == QSE_T('\0'))) { /* special file name '-' */ - xtn->s.in.handle = open_sio_std ( + xtn->s.in.u.file.sio = open_sio_std ( awk, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR); - if (xtn->s.in.handle == QSE_NULL) return -1; + if (xtn->s.in.u.file.sio == QSE_NULL) return -1; } else { const qse_char_t* base; - xtn->s.in.handle = open_sio ( - awk, xtn->s.in.u.file, + xtn->s.in.u.file.sio = open_sio ( + awk, xtn->s.in.x->u.file.path, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR ); - if (xtn->s.in.handle == QSE_NULL) return -1; + if (xtn->s.in.u.file.sio == QSE_NULL) return -1; - base = qse_basename (xtn->s.in.u.file); - if (base != xtn->s.in.u.file) + base = qse_basename (xtn->s.in.x->u.file.path); + if (base != xtn->s.in.x->u.file.path) { - xtn->s.in.dir.ptr = xtn->s.in.u.file; - xtn->s.in.dir.len = base - xtn->s.in.u.file; + xtn->s.in.u.file.dir.ptr = xtn->s.in.x->u.file.path; + xtn->s.in.u.file.dir.len = base - xtn->s.in.x->u.file.path; } } + if (xtn->s.in.x->u.file.cmgr) + qse_sio_setcmgr (xtn->s.in.u.file.sio, xtn->s.in.x->u.file.cmgr); return 1; - case QSE_AWK_PARSESTD_STDIO: - xtn->s.in.handle = open_sio_std ( - awk, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR); - if (xtn->s.in.handle == QSE_NULL) return -1; - return 1; - - case QSE_AWK_PARSESTD_CP: - case QSE_AWK_PARSESTD_CPL: - xtn->s.in.handle = QSE_NULL; + case QSE_AWK_PARSESTD_STR: + xtn->s.in.u.str.ptr = xtn->s.in.x->u.str.ptr; + xtn->s.in.u.str.end = xtn->s.in.x->u.str.ptr + xtn->s.in.x->u.str.len; return 1; } @@ -433,11 +438,11 @@ static qse_ssize_t sf_in_open ( qse_char_t fbuf[64]; qse_char_t* dbuf = QSE_NULL; - if (xtn->s.in.dir.len > 0 && arg->name[0] != QSE_T('/')) + if (xtn->s.in.u.file.dir.len > 0 && arg->name[0] != QSE_T('/')) { qse_size_t tmplen, totlen; - totlen = qse_strlen(arg->name) + xtn->s.in.dir.len; + totlen = qse_strlen(arg->name) + xtn->s.in.u.file.dir.len; if (totlen >= QSE_COUNTOF(fbuf)) { dbuf = QSE_MMGR_ALLOC ( @@ -456,8 +461,8 @@ static qse_ssize_t sf_in_open ( tmplen = qse_strncpy ( (qse_char_t*)file, - xtn->s.in.dir.ptr, - xtn->s.in.dir.len + xtn->s.in.u.file.dir.ptr, + xtn->s.in.u.file.dir.len ); qse_strcpy ((qse_char_t*)file + tmplen, arg->name); } @@ -485,7 +490,16 @@ static qse_ssize_t sf_in_close ( { if (arg == QSE_NULL || arg->name == QSE_NULL) { - if (xtn->s.in.handle) qse_sio_close (xtn->s.in.handle); + switch (xtn->s.in.x->type) + { + case QSE_AWK_PARSESTD_FILE: + qse_sio_close (xtn->s.in.u.file.sio); + break; + + case QSE_AWK_PARSESTD_STR: + /* nothing to close */ + break; + } } else { @@ -502,41 +516,38 @@ static qse_ssize_t sf_in_read ( { if (arg == QSE_NULL || arg->name == QSE_NULL) { - switch (xtn->s.in.type) + switch (xtn->s.in.x->type) { case QSE_AWK_PARSESTD_FILE: - case QSE_AWK_PARSESTD_STDIO: { qse_ssize_t n; - QSE_ASSERT (xtn->s.in.handle != QSE_NULL); - n = qse_sio_getstrn (xtn->s.in.handle, data, size); - if (n == -1) + QSE_ASSERT (xtn->s.in.u.file.sio != QSE_NULL); + n = qse_sio_getstrn (xtn->s.in.u.file.sio, data, size); + if (n <= -1) { qse_cstr_t ea; - ea.ptr = xtn->s.in.u.file; - ea.len = qse_strlen(ea.ptr); + if (xtn->s.in.x->u.file.path) + { + ea.ptr = xtn->s.in.x->u.file.path; + ea.len = qse_strlen(ea.ptr); + } + else + { + ea.ptr = sio_std_names[QSE_SIO_STDIN].ptr; + ea.len = sio_std_names[QSE_SIO_STDIN].len; + } qse_awk_seterrnum (awk, QSE_AWK_EREAD, &ea); } return n; } - case QSE_AWK_PARSESTD_CP: + case QSE_AWK_PARSESTD_STR: { qse_size_t n = 0; - while (n < size && *xtn->s.in.u.cp != QSE_T('\0')) + while (n < size && xtn->s.in.u.str.ptr < xtn->s.in.u.str.end) { - data[n++] = *xtn->s.in.u.cp++; - } - return n; - } - - case QSE_AWK_PARSESTD_CPL: - { - qse_size_t n = 0; - while (n < size && xtn->s.in.u.cpl.ptr < xtn->s.in.u.cpl.end) - { - data[n++] = *xtn->s.in.u.cpl.ptr++; + data[n++] = *xtn->s.in.u.str.ptr++; } return n; } @@ -551,7 +562,7 @@ static qse_ssize_t sf_in_read ( QSE_ASSERT (arg->handle != QSE_NULL); n = qse_sio_getstrn (arg->handle, data, size); - if (n == -1) + if (n <= -1) { qse_cstr_t ea; ea.ptr = arg->name; @@ -595,43 +606,42 @@ static qse_ssize_t sf_out ( { case QSE_AWK_SIO_OPEN: { - switch (xtn->s.out.type) + switch (xtn->s.out.x->type) { case QSE_AWK_PARSESTD_FILE: - if (xtn->s.out.u.file == QSE_NULL) return -1; - - if (xtn->s.out.u.file[0] == QSE_T('-') && - xtn->s.out.u.file[1] == QSE_T('\0')) + if (xtn->s.out.x->u.file.path == QSE_NULL || + (xtn->s.out.x->u.file.path[0] == QSE_T('-') && + xtn->s.out.x->u.file.path[1] == QSE_T('\0'))) { /* special file name '-' */ - xtn->s.out.handle = open_sio_std ( + xtn->s.out.u.file.sio = open_sio_std ( awk, QSE_SIO_STDOUT, QSE_SIO_WRITE | QSE_SIO_IGNOREMBWCERR ); - if (xtn->s.out.handle == QSE_NULL) return -1; + if (xtn->s.out.u.file.sio == QSE_NULL) return -1; } else { - xtn->s.out.handle = open_sio ( - awk, xtn->s.out.u.file, + xtn->s.out.u.file.sio = open_sio ( + awk, xtn->s.out.x->u.file.path, QSE_SIO_WRITE | QSE_SIO_CREATE | QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR ); - if (xtn->s.out.handle == QSE_NULL) return -1; + if (xtn->s.out.u.file.sio == QSE_NULL) return -1; } + + if (xtn->s.out.x->u.file.cmgr) + qse_sio_setcmgr (xtn->s.out.u.file.sio, xtn->s.out.x->u.file.cmgr); return 1; - case QSE_AWK_PARSESTD_STDIO: - xtn->s.out.handle = open_sio_std ( - awk, QSE_SIO_STDOUT, - QSE_SIO_WRITE | QSE_SIO_IGNOREMBWCERR - ); - if (xtn->s.out.handle == QSE_NULL) return -1; - return 1; + case QSE_AWK_PARSESTD_STR: + xtn->s.out.u.str.buf = qse_str_open (awk->mmgr, 0, 512); + if (xtn->s.out.u.str.buf == QSE_NULL) + { + qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL); + return -1; + } - case QSE_AWK_PARSESTD_CP: - case QSE_AWK_PARSESTD_CPL: - xtn->s.out.handle = QSE_NULL; return 1; } @@ -641,23 +651,15 @@ static qse_ssize_t sf_out ( case QSE_AWK_SIO_CLOSE: { - switch (xtn->s.out.type) + switch (xtn->s.out.x->type) { case QSE_AWK_PARSESTD_FILE: - case QSE_AWK_PARSESTD_STDIO: - - qse_sio_flush (xtn->s.out.handle); - qse_sio_close (xtn->s.out.handle); + qse_sio_close (xtn->s.out.u.file.sio); return 0; - case QSE_AWK_PARSESTD_CP: - *xtn->s.out.u.cp = QSE_T('\0'); - return 0; - - case QSE_AWK_PARSESTD_CPL: - xtn->s.out.u.cpl.osp->len = - xtn->s.out.u.cpl.ptr - - xtn->s.out.u.cpl.osp->ptr; + case QSE_AWK_PARSESTD_STR: + /* i don't close xtn->s.out.u.str.buf intentionally here. + * it will be closed at the end of qse_awk_parsestd() */ return 0; } @@ -666,43 +668,41 @@ static qse_ssize_t sf_out ( case QSE_AWK_SIO_WRITE: { - switch (xtn->s.out.type) + switch (xtn->s.out.x->type) { case QSE_AWK_PARSESTD_FILE: - case QSE_AWK_PARSESTD_STDIO: { qse_ssize_t n; - QSE_ASSERT (xtn->s.out.handle != QSE_NULL); - n = qse_sio_putstrn (xtn->s.out.handle, data, size); - if (n == -1) + QSE_ASSERT (xtn->s.out.u.file.sio != QSE_NULL); + n = qse_sio_putstrn (xtn->s.out.u.file.sio, data, size); + if (n <= -1) { qse_cstr_t ea; - ea.ptr = xtn->s.in.u.file; - ea.len = qse_strlen(ea.ptr); + if (xtn->s.out.x->u.file.path) + { + ea.ptr = xtn->s.out.x->u.file.path; + ea.len = qse_strlen(ea.ptr); + } + else + { + ea.ptr = sio_std_names[QSE_SIO_STDOUT].ptr; + ea.len = sio_std_names[QSE_SIO_STDOUT].len; + } qse_awk_seterrnum (awk, QSE_AWK_EWRITE, &ea); } return n; } - case QSE_AWK_PARSESTD_CP: + case QSE_AWK_PARSESTD_STR: { - qse_size_t n = 0; - while (n < size && *xtn->s.out.u.cp != QSE_T('\0')) + if (size > QSE_TYPE_MAX(qse_ssize_t)) size = QSE_TYPE_MAX(qse_ssize_t); + if (qse_str_ncat (xtn->s.out.u.str.buf, data, size) == (qse_size_t)-1) { - *xtn->s.out.u.cp++ = data[n++]; + qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL); + return -1; } - return n; - } - - case QSE_AWK_PARSESTD_CPL: - { - qse_size_t n = 0; - while (n < size && xtn->s.out.u.cpl.ptr < xtn->s.out.u.cpl.end) - { - *xtn->s.out.u.cpl.ptr++ = data[n++]; - } - return n; + return size; } } @@ -715,12 +715,11 @@ static qse_ssize_t sf_out ( } int qse_awk_parsestd ( - qse_awk_t* awk, - const qse_awk_parsestd_in_t* in, - qse_awk_parsestd_out_t* out) + qse_awk_t* awk, qse_awk_parsestd_t* in, qse_awk_parsestd_t* out) { qse_awk_sio_t sio; xtn_t* xtn = (xtn_t*) QSE_XTN (awk); + int n; if (in == QSE_NULL) { @@ -729,67 +728,41 @@ int qse_awk_parsestd ( return -1; } - switch (in->type) + if (in->type != QSE_AWK_PARSESTD_FILE && + in->type != QSE_AWK_PARSESTD_STR) { - case QSE_AWK_PARSESTD_FILE: - xtn->s.in.u.file = in->u.file; - break; - - case QSE_AWK_PARSESTD_CP: - xtn->s.in.u.cp = in->u.cp; - break; - - case QSE_AWK_PARSESTD_CPL: - xtn->s.in.u.cpl.ptr = in->u.cpl.ptr; - xtn->s.in.u.cpl.end = in->u.cpl.ptr + in->u.cpl.len; - break; - - case QSE_AWK_PARSESTD_STDIO: - /* nothing to do */ - break; - - default: - qse_awk_seterrnum (awk, QSE_AWK_EINVAL, QSE_NULL); - return -1; + qse_awk_seterrnum (awk, QSE_AWK_EINVAL, QSE_NULL); + return -1; } - - xtn->s.in.type = in->type; - xtn->s.in.handle = QSE_NULL; sio.in = sf_in; + xtn->s.in.x = in; if (out == QSE_NULL) sio.out = QSE_NULL; else { - switch (out->type) + if (out->type != QSE_AWK_PARSESTD_FILE && + out->type != QSE_AWK_PARSESTD_STR) { - case QSE_AWK_PARSESTD_FILE: - xtn->s.out.u.file = out->u.file; - break; - - case QSE_AWK_PARSESTD_CP: - xtn->s.out.u.cp = out->u.cp; - break; - - case QSE_AWK_PARSESTD_CPL: - xtn->s.out.u.cpl.osp = &out->u.cpl; - xtn->s.out.u.cpl.ptr = out->u.cpl.ptr; - xtn->s.out.u.cpl.end = out->u.cpl.ptr + out->u.cpl.len; - break; - - case QSE_AWK_PARSESTD_STDIO: - /* nothing to do */ - break; - - default: - qse_awk_seterrnum (awk, QSE_AWK_EINVAL, QSE_NULL); - return -1; + qse_awk_seterrnum (awk, QSE_AWK_EINVAL, QSE_NULL); + return -1; } - xtn->s.out.type = out->type; - xtn->s.out.handle = QSE_NULL; sio.out = sf_out; + xtn->s.out.x = out; } - return qse_awk_parse (awk, &sio); + n = qse_awk_parse (awk, &sio); + + if (out && out->type == QSE_AWK_PARSESTD_STR) + { + if (n >= 0) + { + QSE_ASSERT (xtn->s.out.u.str.buf != QSE_NULL); + qse_str_yield (xtn->s.out.u.str.buf, &out->u.str, 0); + } + if (xtn->s.out.u.str.buf) qse_str_close (xtn->s.out.u.str.buf); + } + + return n; } /*** RTX_OPENSTD ***/ @@ -827,7 +800,7 @@ static qse_ssize_t awk_rio_pipe ( 0, riod->name, QSE_NULL, - flags|QSE_PIO_SHELL|QSE_PIO_TEXT + flags|QSE_PIO_SHELL|QSE_PIO_TEXT|QSE_PIO_IGNOREMBWCERR ); if (handle == QSE_NULL) return -1; @@ -1271,6 +1244,13 @@ static qse_ssize_t awk_rio_console ( return -1; } +/* TODO: provide a way to set cmgr for console files icf and ocf... + * should i accept something similar to qse_awk_parsestd_t? + * + * what is the best way to change cmgr for pipes and files? + * currently there is no way to change cmgr for each pipe and file. + * you can change the global cmgr only with qse_setdflcmgr(). + */ qse_awk_rtx_t* qse_awk_rtx_openstd ( qse_awk_t* awk, qse_size_t xtnsize, @@ -1288,8 +1268,8 @@ qse_awk_rtx_t* qse_awk_rtx_openstd ( qse_cstr_t argv[16]; qse_cstr_t* argvp = QSE_NULL, * p2; - rio.pipe = awk_rio_pipe; - rio.file = awk_rio_file; + rio.pipe = awk_rio_pipe; + rio.file = awk_rio_file; rio.console = awk_rio_console; if (icf != QSE_NULL) diff --git a/qse/lib/cmn/slmb.c b/qse/lib/cmn/slmb.c index bfb11a72..faf256a2 100644 --- a/qse/lib/cmn/slmb.c +++ b/qse/lib/cmn/slmb.c @@ -37,59 +37,31 @@ #ifdef HAVE_STDLIB_H # include #endif - -qse_size_t qse_slmbrlen ( - const qse_mchar_t* mb, qse_size_t mbl, qse_mbstate_t* state) -{ -#if defined(HAVE_MBRLEN) - size_t n; - - n = mbrlen (mb, mbl, (mbstate_t*)state); - if (n == 0) return 1; /* a null character */ - - if (n == (size_t)-1) return 0; /* invalid sequence */ - if (n == (size_t)-2) return mbl + 1; /* incomplete sequence */ - - return (qse_size_t)n; - - #if 0 - n = mblen (mb, mbl); - if (n == (size_t)-1) return 0; /* invalid or incomplete sequence */ - if (n == 0) return 1; /* a null character */ - return (qse_size_t)n; - #endif -#else - #error #### NOT SUPPORTED #### +#if defined(_WIN32) +# include #endif -} - -qse_size_t qse_slmbrtoslwc ( - const qse_mchar_t* mb, qse_size_t mbl, - qse_wchar_t* wc, qse_mbstate_t* state) -{ -#if defined(HAVE_MBRTOWC) - size_t n; - - n = mbrtowc (wc, mb, mbl, (mbstate_t*)state); - if (n == 0) - { - *wc = QSE_WT('\0'); - return 1; - } - - if (n == (size_t)-1) return 0; /* invalid sequence */ - if (n == (size_t)-2) return mbl + 1; /* incomplete sequence */ - return (qse_size_t)n; -#else - #error #### NOT SUPPORTED #### -#endif -} qse_size_t qse_slwcrtoslmb ( qse_wchar_t wc, qse_mchar_t* mb, qse_size_t mbl, qse_mbstate_t* state) { -#if defined(HAVE_WCRTOMB) +#if defined(_WIN32) + int n; + + n = WideCharToMultiByte ( + CP_THREAD_ACP, 0 /*WC_ERR_INVALID_CHARS*/, + &wc, 1, mb, mbl, NULL, NULL); + if (n == 0) + { + DWORD e = GetLastError(); + if (e == ERROR_INSUFFICIENT_BUFFER) return mbl + 1; + /*if (e == ERROR_NO_UNICODE_TRANSLATION) return 0;*/ + /* treat all other erros as invalid unicode character */ + } + + return (qse_size_t)n; + +#elif defined(HAVE_WCRTOMB) size_t n; if (mbl < QSE_MBLEN_MAX) @@ -123,6 +95,90 @@ qse_size_t qse_slwcrtoslmb ( #endif } +qse_size_t qse_slmbrtoslwc ( + const qse_mchar_t* mb, qse_size_t mbl, + qse_wchar_t* wc, qse_mbstate_t* state) +{ +#if defined(_WIN32) + qse_size_t dbcslen; + int n; + + QSE_ASSERT (mb != QSE_NULL); + QSE_ASSERT (mbl > 0); + + dbcslen = IsDBCSLeadByteEx(CP_THREAD_ACP, *mb)? 2: 1; + if (mbl < dbcslen) return mbl + 1; /* incomplete sequence */ + + n = MultiByteToWideChar ( + CP_THREAD_ACP, MB_ERR_INVALID_CHARS, mb, dbcslen, wc, 1); + if (n == 0) + { + /*DWORD e = GetLastError();*/ + /*if (e == ERROR_NO_UNICODE_TRANSLATION) return 0;*/ + /*if (e == ERROR_INSUFFICIENT_BUFFER) return mbl + 1;*/ + return 0; + } + + return dbcslen; + +#elif defined(HAVE_MBRTOWC) + size_t n; + + QSE_ASSERT (mb != QSE_NULL); + QSE_ASSERT (mbl > 0); + + n = mbrtowc (wc, mb, mbl, (mbstate_t*)state); + if (n == 0) + { + if (wc) *wc = QSE_WT('\0'); + return 1; + } + + if (n == (size_t)-1) return 0; /* invalid sequence */ + if (n == (size_t)-2) return mbl + 1; /* incomplete sequence */ + return (qse_size_t)n; +#else + #error #### NOT SUPPORTED #### +#endif +} + +qse_size_t qse_slmbrlen ( + const qse_mchar_t* mb, qse_size_t mbl, qse_mbstate_t* state) +{ +#if defined(_WIN32) + qse_size_t dbcslen; + + QSE_ASSERT (mb != QSE_NULL); + QSE_ASSERT (mbl > 0); + + dbcslen = IsDBCSLeadByteEx(CP_THREAD_ACP, *mb)? 2: 1; + if (mbl < dbcslen) return mbl + 1; /* incomplete sequence */ + return dbcslen; +#elif defined(HAVE_MBRLEN) + size_t n; + + QSE_ASSERT (mb != QSE_NULL); + QSE_ASSERT (mbl > 0); + + n = mbrlen (mb, mbl, (mbstate_t*)state); + if (n == 0) return 1; /* a null character */ + + if (n == (size_t)-1) return 0; /* invalid sequence */ + if (n == (size_t)-2) return mbl + 1; /* incomplete sequence */ + + return (qse_size_t)n; + + #if 0 + n = mblen (mb, mbl); + if (n == (size_t)-1) return 0; /* invalid or incomplete sequence */ + if (n == 0) return 1; /* a null character */ + return (qse_size_t)n; + #endif +#else + #error #### NOT SUPPORTED #### +#endif +} + /* man mbsinit * For 8-bit encodings, all states are equivalent to the initial state. * For multibyte encodings like UTF-8, EUC-*, BIG5 or SJIS, the wide char‐ @@ -131,11 +187,6 @@ qse_size_t qse_slwcrtoslmb ( * mbrtowc(3) do produce non-initial states when interrupted in the middle * of a character. */ -qse_size_t qse_slmblen (const qse_mchar_t* mb, qse_size_t mbl) -{ - qse_mbstate_t state = { { 0, } }; - return qse_slmbrlen (mb, mbl, &state); -} qse_size_t qse_slmbtoslwc (const qse_mchar_t* mb, qse_size_t mbl, qse_wchar_t* wc) { @@ -149,7 +200,20 @@ qse_size_t qse_slwctoslmb (qse_wchar_t wc, qse_mchar_t* mb, qse_size_t mbl) return qse_slwcrtoslmb (wc, mb, mbl, &state); } -int qse_slmblenmax (void) +qse_size_t qse_slmblen (const qse_mchar_t* mb, qse_size_t mbl) { - return MB_CUR_MAX; + qse_mbstate_t state = { { 0, } }; + return qse_slmbrlen (mb, mbl, &state); +} + +qse_size_t qse_slmblenmax (void) +{ +#if defined(_WIN32) + /* Windows doesn't handle utf8 properly even when your code page + * is CP_UTF8(65001). you should use functions in utf8.c for utf8 + * handleing on windows. */ + return 2; +#else + return MB_CUR_MAX; +#endif } diff --git a/qse/lib/cmn/utf8.c b/qse/lib/cmn/utf8.c index 94711ee2..81936ac1 100644 --- a/qse/lib/cmn/utf8.c +++ b/qse/lib/cmn/utf8.c @@ -73,53 +73,40 @@ static QSE_INLINE __utf8_t* get_utf8_slot (qse_wchar_t uc) return QSE_NULL; /* invalid character */ } -qse_size_t qse_uctoutf8len (qse_wchar_t uc) -{ - __utf8_t* cur = get_utf8_slot (uc); - return (cur == QSE_NULL)? 0: (qse_size_t)cur->length; -} - -/* wctomb for utf8/unicode */ qse_size_t qse_uctoutf8 (qse_wchar_t uc, qse_mchar_t* utf8, qse_size_t size) { __utf8_t* cur = get_utf8_slot (uc); - int index; if (cur == QSE_NULL) return 0; /* illegal character */ - if (cur->length > size) + if (utf8 && cur->length <= size) { - /* buffer not big enough. index indicates the buffer - * size needed */ - return size + 1; + int index = cur->length; + while (index > 1) + { + /* + * 0x3F: 00111111 + * 0x80: 10000000 + */ + utf8[--index] = (uc & 0x3F) | 0x80; + uc >>= 6; + } + + utf8[0] = uc | cur->fbyte; } - index = cur->length; - while (index > 1) - { - /* - * 0x3F: 00111111 - * 0x80: 10000000 - */ - utf8[--index] = (uc & 0x3F) | 0x80; - uc >>= 6; - } - - utf8[0] = uc | cur->fbyte; + /* small buffer is also indicated by this return value + * greater than 'size'. */ return (qse_size_t)cur->length; } -/* mbtowc for utf8/unicode */ qse_size_t qse_utf8touc ( const qse_mchar_t* utf8, qse_size_t size, qse_wchar_t* uc) { __utf8_t* cur, * end; -#if 0 - qse_mchar_t c, t; - int count = 0; -#endif QSE_ASSERT (utf8 != QSE_NULL); + QSE_ASSERT (size > 0); QSE_ASSERT (QSE_SIZEOF(qse_mchar_t) == 1); QSE_ASSERT (QSE_SIZEOF(qse_wchar_t) >= 2); @@ -130,81 +117,37 @@ qse_size_t qse_utf8touc ( { if ((utf8[0] & cur->mask) == cur->fbyte) { - int i; - qse_wchar_t w; - if (size < cur->length) return size + 1; - - w = utf8[0] & cur->fmask; - for (i = 1; i < cur->length; i++) - { - if (!(utf8[i] & 0x80)) return 0; - w = (w << 6) | (utf8[i] & 0x3F); - } - - *uc = w; - return (qse_size_t)cur->length; - } - cur++; - } - - return 0; /* error - invalid sequence */ - -#if 0 - c = *utf8; - w = c; - - while (cur < end) - { - count++; - - if ((c & cur->mask) == cur->fbyte) - { - w &= cur->upper; - if (w < cur->lower) break; /* wrong value */ - *uc = w; - return (qse_size_t)count; - } - - if (size <= count) break; /* insufficient input */ - utf8++; /* advance to the next character in the sequence */ - - t = (*utf8 ^ 0x80) & 0xFF; - if (t & 0xC0) break; - w = (w << 6) | t; - - cur++; - } - - return 0; /* error - invalid sequence */ -#endif -} - -/* mblen for utf8 */ -qse_size_t qse_utf8len (const qse_mchar_t* utf8, qse_size_t len) -{ - __utf8_t* cur, * end; - - end = utf8_table + QSE_COUNTOF(utf8_table); - cur = utf8_table; - - while (cur < end) - { - if ((utf8[0] & cur->mask) == cur->fbyte) - { - int i; - - /* if len is less that cur->length, the incomplete-seqeunce + /* if size is less that cur->length, the incomplete-seqeunce * error is naturally indicated. so validate the string - * only if len is as large as cur->length. */ + * only if size is as large as cur->length. */ - if (len >= cur->length) + if (size >= cur->length) { - for (i = 1; i < cur->length; i++) + int i; + + if (uc) { - /* in utf8, trailing bytes are all - * set with 0x80. if not, invalid */ - if (!(utf8[i] & 0x80)) return 0; + qse_wchar_t w; + + w = utf8[0] & cur->fmask; + for (i = 1; i < cur->length; i++) + { + /* in utf8, trailing bytes are all + * set with 0x80. if not, invalid */ + if (!(utf8[i] & 0x80)) return 0; + w = (w << 6) | (utf8[i] & 0x3F); + } + *uc = w; + } + else + { + for (i = 1; i < cur->length; i++) + { + /* in utf8, trailing bytes are all + * set with 0x80. if not, invalid */ + if (!(utf8[i] & 0x80)) return 0; + } } } @@ -213,7 +156,7 @@ qse_size_t qse_utf8len (const qse_mchar_t* utf8, qse_size_t len) * and * the incomplete seqeunce error (len < cur->length). */ - return (qse_size_t)cur->length; + return (qse_size_t)cur->length; } cur++; } @@ -221,7 +164,13 @@ qse_size_t qse_utf8len (const qse_mchar_t* utf8, qse_size_t len) return 0; /* error - invalid sequence */ } +qse_size_t qse_utf8len (const qse_mchar_t* utf8, qse_size_t size) +{ + return qse_utf8touc (utf8, size, QSE_NULL); +} + qse_size_t qse_utf8lenmax (void) { return QSE_UTF8LEN_MAX; } + diff --git a/qse/lib/cut/std.c b/qse/lib/cut/std.c index b5de799d..0b2e7fb4 100644 --- a/qse/lib/cut/std.c +++ b/qse/lib/cut/std.c @@ -64,7 +64,7 @@ int qse_cut_compstd (qse_cut_t* cut, const qse_char_t* sptr) return qse_cut_comp (cut, sptr, qse_strlen(sptr)); } -static qse_sio_t* open_sio (qse_cut_t* cut, const qse_char_t* file, int flags) +static qse_sio_t* open_sio_file (qse_cut_t* cut, const qse_char_t* file, int flags) { qse_sio_t* sio; @@ -79,23 +79,29 @@ static qse_sio_t* open_sio (qse_cut_t* cut, const qse_char_t* file, int flags) return sio; } +struct sio_std_name_t +{ + const qse_char_t* ptr; + qse_size_t len; +}; + +static struct sio_std_name_t sio_std_names[] = +{ + { QSE_T("stdin"), 5 }, + { QSE_T("stdout"), 6 }, + { QSE_T("stderr"), 6 } +}; static qse_sio_t* open_sio_std (qse_cut_t* cut, qse_sio_std_t std, int flags) { - static const qse_char_t* sio_std_names[] = - { - QSE_T("stdin"), - QSE_T("stdout"), - QSE_T("stderr"), - }; qse_sio_t* sio; sio = qse_sio_openstd (cut->mmgr, 0, std, flags); if (sio == QSE_NULL) { qse_cstr_t ea; - ea.ptr = sio_std_names[std]; - ea.len = qse_strlen (sio_std_names[std]); + ea.ptr = sio_std_names[std].ptr; + ea.len = sio_std_names[std].len; qse_cut_seterrnum (cut, QSE_CUT_EIOFIL, &ea); } return sio; @@ -114,7 +120,7 @@ static qse_ssize_t xin ( { /* main data stream */ sio = xtn->infile? - open_sio (cut, xtn->infile, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR): + open_sio_file (cut, xtn->infile, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR): open_sio_std (cut, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR); if (sio == QSE_NULL) return -1; arg->handle = sio; @@ -132,15 +138,20 @@ static qse_ssize_t xin ( { qse_ssize_t n = qse_sio_getstrn (arg->handle, buf, len); - if (n == -1) + if (n <= -1) { + qse_cstr_t ea; if (xtn->infile) { - qse_cstr_t ea; ea.ptr = xtn->infile; ea.len = qse_strlen (xtn->infile); - qse_cut_seterrnum (cut, QSE_CUT_EIOFIL, &ea); } + else + { + ea.ptr = sio_std_names[QSE_SIO_STDIN].ptr; + ea.len = sio_std_names[QSE_SIO_STDIN].len; + } + qse_cut_seterrnum (cut, QSE_CUT_EIOFIL, &ea); } return n; @@ -163,7 +174,7 @@ static qse_ssize_t xout ( case QSE_CUT_IO_OPEN: { sio = xtn->outfile? - open_sio (cut, xtn->outfile, QSE_SIO_WRITE | QSE_SIO_CREATE | QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR): + open_sio_file (cut, xtn->outfile, QSE_SIO_WRITE | QSE_SIO_CREATE | QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR): open_sio_std (cut, QSE_SIO_STDOUT, QSE_SIO_WRITE | QSE_SIO_IGNOREMBWCERR); if (sio == QSE_NULL) return -1; arg->handle = sio; @@ -182,15 +193,20 @@ static qse_ssize_t xout ( { qse_ssize_t n = qse_sio_putstrn (arg->handle, dat, len); - if (n == -1) + if (n <= -1) { + qse_cstr_t ea; if (xtn->outfile) { - qse_cstr_t ea; ea.ptr = xtn->outfile; ea.len = qse_strlen (xtn->outfile); - qse_cut_seterrnum (cut, QSE_CUT_EIOFIL, &ea); } + else + { + ea.ptr = sio_std_names[QSE_SIO_STDOUT].ptr; + ea.len = sio_std_names[QSE_SIO_STDOUT].len; + } + qse_cut_seterrnum (cut, QSE_CUT_EIOFIL, &ea); } return n; @@ -202,6 +218,7 @@ static qse_ssize_t xout ( } /* TODO: refer to sed/std.c and make similar enhancements */ +/* TODO: accept cmgr */ int qse_cut_execstd (qse_cut_t* cut, const qse_char_t* infile, const qse_char_t* outfile) { xtn_t* xtn = (xtn_t*) QSE_XTN (cut); diff --git a/qse/lib/sed/std.c b/qse/lib/sed/std.c index a4fb62a6..a9ff58ee 100644 --- a/qse/lib/sed/std.c +++ b/qse/lib/sed/std.c @@ -1,5 +1,5 @@ /* - * $Id: std.c 306 2009-11-22 13:58:53Z baconevi $ + * $Id$ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -136,7 +136,7 @@ static int verify_iostd_in (qse_sed_t* sed, qse_sed_iostd_t in[]) { if (in[i].type != QSE_SED_IOSTD_SIO && in[i].type != QSE_SED_IOSTD_FILE && - in[i].type != QSE_SED_IOSTD_MEM) + in[i].type != QSE_SED_IOSTD_STR) { qse_sed_seterrnum (sed, QSE_SED_EINVAL, QSE_NULL); return -1; @@ -146,7 +146,7 @@ static int verify_iostd_in (qse_sed_t* sed, qse_sed_iostd_t in[]) return 0; } -static qse_sio_t* open_sio (qse_sed_t* sed, const qse_char_t* file, int flags) +static qse_sio_t* open_sio_file (qse_sed_t* sed, const qse_char_t* file, int flags) { qse_sio_t* sio; @@ -161,11 +161,17 @@ static qse_sio_t* open_sio (qse_sed_t* sed, const qse_char_t* file, int flags) return sio; } -static const qse_char_t* sio_std_names[] = +struct sio_std_name_t { - QSE_T("stdin"), - QSE_T("stdout"), - QSE_T("stderr"), + const qse_char_t* ptr; + qse_size_t len; +}; + +static struct sio_std_name_t sio_std_names[] = +{ + { QSE_T("stdin"), 5 }, + { QSE_T("stdout"), 6 }, + { QSE_T("stderr"), 6 } }; static qse_sio_t* open_sio_std (qse_sed_t* sed, qse_sio_std_t std, int flags) @@ -176,8 +182,8 @@ static qse_sio_t* open_sio_std (qse_sed_t* sed, qse_sio_std_t std, int flags) if (sio == QSE_NULL) { qse_cstr_t ea; - ea.ptr = sio_std_names[std]; - ea.len = qse_strlen (sio_std_names[std]); + ea.ptr = sio_std_names[std].ptr; + ea.len = sio_std_names[std].len; qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea); } return sio; @@ -186,7 +192,24 @@ static qse_sio_t* open_sio_std (qse_sed_t* sed, qse_sio_std_t std, int flags) static void close_main_stream ( qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_sed_iostd_t* io) { - if (io->type == QSE_SED_IOSTD_FILE) qse_sio_close (arg->handle); + switch (io->type) + { + case QSE_SED_IOSTD_SIO: + /* nothing to do */ + break; + + case QSE_SED_IOSTD_FILE: + qse_sio_close (arg->handle); + break; + + case QSE_SED_IOSTD_STR: + /* nothing to do for input. + * i don't close xtn->e.out.memstr intentionally. + * i close this in qse_awk_execstd() + */ + break; + } + } static int open_input_stream ( @@ -204,15 +227,16 @@ static int open_input_stream ( case QSE_SED_IOSTD_FILE: { qse_sio_t* sio; - sio = (io->u.file == QSE_NULL)? + sio = (io->u.file.path == QSE_NULL)? open_sio_std (sed, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR): - open_sio (sed, io->u.file, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR); + open_sio_file (sed, io->u.file.path, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR); if (sio == QSE_NULL) return -1; + if (io->u.file.cmgr) qse_sio_setcmgr (sio, io->u.file.cmgr); arg->handle = sio; break; } - case QSE_SED_IOSTD_MEM: + case QSE_SED_IOSTD_STR: /* don't store anything to arg->handle */ base->mempos = 0; break; @@ -220,7 +244,7 @@ static int open_input_stream ( default: QSE_ASSERTX ( !"should never happen", - "io-type must be one of SIO,FILE,MEM" + "io-type must be one of SIO,FILE,STR" ); qse_sed_seterrnum (sed, QSE_SED_EINTERN, QSE_NULL); return -1; @@ -234,8 +258,8 @@ static int open_input_stream ( { qse_sed_setcompid ( sed, - ((io->u.file == QSE_NULL)? - sio_std_names[QSE_SIO_STDIN]: io->u.file) + ((io->u.file.path == QSE_NULL)? + sio_std_names[QSE_SIO_STDIN].ptr: io->u.file.path) ); } else @@ -243,7 +267,7 @@ static int open_input_stream ( qse_char_t buf[64]; /* format an identifier to be something like M#1, S#5 */ - buf[0] = (io->type == QSE_SED_IOSTD_MEM)? QSE_T('M'): QSE_T('S'); + buf[0] = (io->type == QSE_SED_IOSTD_STR)? QSE_T('M'): QSE_T('S'); buf[1] = QSE_T('#'); int_to_str (io - xtn->s.in.ptr, &buf[2], QSE_COUNTOF(buf) - 2); @@ -271,7 +295,7 @@ static int open_output_stream (qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_sed_io case QSE_SED_IOSTD_FILE: { qse_sio_t* sio; - if (io->u.file == QSE_NULL) + if (io->u.file.path == QSE_NULL) { sio = open_sio_std ( sed, QSE_SIO_STDOUT, @@ -283,8 +307,8 @@ static int open_output_stream (qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_sed_io } else { - sio = open_sio ( - sed, io->u.file, + sio = open_sio_file ( + sed, io->u.file.path, QSE_SIO_WRITE | QSE_SIO_CREATE | QSE_SIO_TRUNCATE | @@ -292,11 +316,12 @@ static int open_output_stream (qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_sed_io ); } if (sio == QSE_NULL) return -1; + if (io->u.file.cmgr) qse_sio_setcmgr (sio, io->u.file.cmgr); arg->handle = sio; break; } - case QSE_SED_IOSTD_MEM: + case QSE_SED_IOSTD_STR: /* don't store anything to arg->handle */ xtn->e.out.memstr = qse_str_open (sed->mmgr, 0, 512); if (xtn->e.out.memstr == QSE_NULL) @@ -309,7 +334,7 @@ static int open_output_stream (qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_sed_io default: QSE_ASSERTX ( !"should never happen", - "io-type must be one of SIO,FILE,MEM" + "io-type must be one of SIO,FILE,STR" ); qse_sed_seterrnum (sed, QSE_SED_EINTERN, QSE_NULL); return -1; @@ -341,13 +366,14 @@ static qse_ssize_t read_input_stream ( QSE_ASSERT (io != QSE_NULL); - if (io->type == QSE_SED_IOSTD_MEM) + if (io->type == QSE_SED_IOSTD_STR) { n = 0; - while (base->mempos < io->u.mem.len && n < len) - buf[n++] = io->u.mem.ptr[base->mempos++]; + while (base->mempos < io->u.str.len && n < len) + buf[n++] = io->u.str.ptr[base->mempos++]; } else n = qse_sio_getstrn (arg->handle, buf, len); + if (n != 0) { if (n <= -1) @@ -355,8 +381,16 @@ static qse_ssize_t read_input_stream ( if (io->type == QSE_SED_IOSTD_FILE) { qse_cstr_t ea; - ea.ptr = io->u.file; - ea.len = qse_strlen (io->u.file); + if (io->u.file.path) + { + ea.ptr = io->u.file.path; + ea.len = qse_strlen (io->u.file.path); + } + else + { + ea.ptr = sio_std_names[QSE_SIO_STDIN].ptr; + ea.len = sio_std_names[QSE_SIO_STDIN].len; + } qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea); } } @@ -398,8 +432,16 @@ static qse_ssize_t read_input_stream ( if (next->type == QSE_SED_IOSTD_FILE) { qse_cstr_t ea; - ea.ptr = next->u.file; - ea.len = qse_strlen (next->u.file); + if (next->u.file.path) + { + ea.ptr = next->u.file.path; + ea.len = qse_strlen (next->u.file.path); + } + else + { + ea.ptr = sio_std_names[QSE_SIO_STDIN].ptr; + ea.len = sio_std_names[QSE_SIO_STDIN].len; + } qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea); } @@ -489,7 +531,7 @@ static qse_ssize_t x_in ( } else { - sio = open_sio (sed, arg->path, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR); + sio = open_sio_file (sed, arg->path, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR); if (sio == QSE_NULL) return -1; arg->handle = sio; } @@ -527,8 +569,8 @@ static qse_ssize_t x_in ( if (n <= -1) { qse_cstr_t ea; - ea.ptr = QSE_T("stdin"); - ea.len = 5; + ea.ptr = sio_std_names[QSE_SIO_STDIN].ptr; + ea.len = sio_std_names[QSE_SIO_STDIN].len; qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea); } return n; @@ -574,7 +616,7 @@ static qse_ssize_t x_out ( { if (arg->path == QSE_NULL) { - if (xtn->e.out.ptr== QSE_NULL) + if (xtn->e.out.ptr == QSE_NULL) { sio = open_sio_std ( sed, QSE_SIO_STDOUT, @@ -593,7 +635,7 @@ static qse_ssize_t x_out ( } else { - sio = open_sio ( + sio = open_sio_file ( sed, arg->path, QSE_SIO_WRITE | QSE_SIO_CREATE | @@ -611,7 +653,7 @@ static qse_ssize_t x_out ( { if (arg->path == QSE_NULL) { - if (xtn->e.out.ptr== QSE_NULL) + if (xtn->e.out.ptr == QSE_NULL) qse_sio_close (arg->handle); else close_main_stream (sed, arg, xtn->e.out.ptr); @@ -628,15 +670,15 @@ static qse_ssize_t x_out ( if (arg->path == QSE_NULL) { /* main data stream */ - if (xtn->e.out.ptr== QSE_NULL) + if (xtn->e.out.ptr == QSE_NULL) { qse_ssize_t n; n = qse_sio_putstrn (arg->handle, dat, len); if (n <= -1) { qse_cstr_t ea; - ea.ptr = QSE_T("stdin"); - ea.len = 5; + ea.ptr = sio_std_names[QSE_SIO_STDOUT].ptr; + ea.len = sio_std_names[QSE_SIO_STDOUT].len; qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea); } return n; @@ -644,7 +686,7 @@ static qse_ssize_t x_out ( else { qse_sed_iostd_t* io = xtn->e.out.ptr; - if (io->type == QSE_SED_IOSTD_MEM) + if (io->type == QSE_SED_IOSTD_STR) { if (len > QSE_TYPE_MAX(qse_ssize_t)) len = QSE_TYPE_MAX(qse_ssize_t); @@ -663,8 +705,16 @@ static qse_ssize_t x_out ( if (n <= -1) { qse_cstr_t ea; - ea.ptr = io->u.file; - ea.len = qse_strlen(io->u.file); + if (io->u.file.path) + { + ea.ptr = io->u.file.path; + ea.len = qse_strlen(io->u.file.path); + } + else + { + ea.ptr = sio_std_names[QSE_SIO_STDOUT].ptr; + ea.len = sio_std_names[QSE_SIO_STDOUT].len; + } qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea); } return n; @@ -732,7 +782,7 @@ int qse_sed_execstd ( { if (out->type != QSE_SED_IOSTD_SIO && out->type != QSE_SED_IOSTD_FILE && - out->type != QSE_SED_IOSTD_MEM) + out->type != QSE_SED_IOSTD_STR) { qse_sed_seterrnum (sed, QSE_SED_EINVAL, QSE_NULL); return -1; @@ -746,41 +796,47 @@ int qse_sed_execstd ( n = qse_sed_exec (sed, x_in, x_out); - if (n >= 0 && out && out->type == QSE_SED_IOSTD_MEM) + if (out && out->type == QSE_SED_IOSTD_STR) { - QSE_ASSERT (xtn->e.out.memstr != QSE_NULL); - qse_str_yield (xtn->e.out.memstr, &out->u.mem, 0); + if (n >= 0) + { + QSE_ASSERT (xtn->e.out.memstr != QSE_NULL); + qse_str_yield (xtn->e.out.memstr, &out->u.str, 0); + } + if (xtn->e.out.memstr) qse_str_close (xtn->e.out.memstr); } - if (xtn->e.out.memstr) qse_str_close (xtn->e.out.memstr); return n; } -int qse_sed_compstdfile (qse_sed_t* sed, const qse_char_t* file) +int qse_sed_compstdfile ( + qse_sed_t* sed, const qse_char_t* file, qse_cmgr_t* cmgr) { qse_sed_iostd_t in[2]; in[0].type = QSE_SED_IOSTD_FILE; - in[0].u.file = file; + in[0].u.file.path = file; + in[0].u.file.cmgr = cmgr; in[1].type = QSE_SED_IOSTD_NULL; return qse_sed_compstd (sed, in, QSE_NULL); } -int qse_sed_compstdmem (qse_sed_t* sed, const qse_char_t* script) +int qse_sed_compstdstr (qse_sed_t* sed, const qse_char_t* script) { qse_sed_iostd_t in[2]; - in[0].type = QSE_SED_IOSTD_MEM; - in[0].u.mem.ptr = script; - in[0].u.mem.len = qse_strlen(script); + in[0].type = QSE_SED_IOSTD_STR; + in[0].u.str.ptr = script; + in[0].u.str.len = qse_strlen(script); in[1].type = QSE_SED_IOSTD_NULL; return qse_sed_compstd (sed, in, QSE_NULL); } int qse_sed_execstdfile ( - qse_sed_t* sed, const qse_char_t* infile, const qse_char_t* outfile) + qse_sed_t* sed, const qse_char_t* infile, + const qse_char_t* outfile, qse_cmgr_t* cmgr) { qse_sed_iostd_t in[2]; qse_sed_iostd_t out; @@ -789,7 +845,8 @@ int qse_sed_execstdfile ( if (infile) { in[0].type = QSE_SED_IOSTD_FILE; - in[0].u.file = infile; + in[0].u.file.path = infile; + in[0].u.file.cmgr = cmgr; in[1].type = QSE_SED_IOSTD_NULL; pin = in; } @@ -797,7 +854,8 @@ int qse_sed_execstdfile ( if (outfile) { out.type = QSE_SED_IOSTD_FILE; - out.u.file = outfile; + out.u.file.path = outfile; + out.u.file.cmgr = cmgr; pout = &out; } diff --git a/qse/samples/awk/awk01.c b/qse/samples/awk/awk01.c index d29555b3..f64c59cf 100644 --- a/qse/samples/awk/awk01.c +++ b/qse/samples/awk/awk01.c @@ -37,7 +37,7 @@ int main () qse_awk_t* awk = QSE_NULL; qse_awk_rtx_t* rtx = QSE_NULL; qse_awk_val_t* retv; - qse_awk_parsestd_in_t psin; + qse_awk_parsestd_t psin; int ret = -1; awk = qse_awk_openstd (0); @@ -47,8 +47,9 @@ int main () goto oops; } - psin.type = QSE_AWK_PARSESTD_CP; - psin.u.cp = src; + psin.type = QSE_AWK_PARSESTD_STR; + psin.u.str.ptr = src; + psin.u.str.len = qse_strlen(src); if (qse_awk_parsestd (awk, &psin, QSE_NULL) <= -1) { diff --git a/qse/samples/awk/awk02.c b/qse/samples/awk/awk02.c index 163122c1..0cf4bbab 100644 --- a/qse/samples/awk/awk02.c +++ b/qse/samples/awk/awk02.c @@ -34,16 +34,14 @@ static const qse_char_t* src = QSE_T( "}" ); -static qse_char_t srcout[5000]; - int main () { qse_awk_t* awk = QSE_NULL; qse_awk_rtx_t* rtx = QSE_NULL; qse_awk_val_t* retv; - qse_awk_parsestd_in_t psin; - qse_awk_parsestd_out_t psout; + qse_awk_parsestd_t psin; + qse_awk_parsestd_t psout; int ret; @@ -54,13 +52,13 @@ int main () ret = -1; goto oops; } - qse_memset (srcout, QSE_T(' '), QSE_COUNTOF(srcout)-1); - srcout[QSE_COUNTOF(srcout)-1] = QSE_T('\0'); + psin.type = QSE_AWK_PARSESTD_STR; + psin.u.str.ptr = src; + psin.u.str.len = qse_strlen(src); - psin.type = QSE_AWK_PARSESTD_CP; - psin.u.cp = src; - psout.type = QSE_AWK_PARSESTD_CP; - psout.u.cp = srcout; + psout.type = QSE_AWK_PARSESTD_STR; + /* ps.out.u.str.ptr and ps.out.u.str.len are set when qse_awk_parsestd() + * returns success */ ret = qse_awk_parsestd (awk, &psin, &psout); if (ret <= -1) @@ -70,10 +68,12 @@ int main () ret = -1; goto oops; } - qse_printf (QSE_T("DEPARSED SOURCE:\n%s\n"), srcout); + qse_printf (QSE_T("DEPARSED SOURCE:\n%s\n"), psout.u.str.ptr); qse_printf (QSE_T("=================================\n")); qse_fflush (QSE_STDOUT); + QSE_MMGR_FREE (qse_awk_getmmgr(awk), psout.u.str.ptr); + rtx = qse_awk_rtx_openstd ( awk, 0, diff --git a/qse/samples/awk/awk03.c b/qse/samples/awk/awk03.c index 02d61844..03a48c0b 100644 --- a/qse/samples/awk/awk03.c +++ b/qse/samples/awk/awk03.c @@ -43,7 +43,7 @@ int main () qse_awk_t* awk = QSE_NULL; qse_awk_rtx_t* rtx = QSE_NULL; - qse_awk_parsestd_in_t psin; + qse_awk_parsestd_t psin; int ret, i; @@ -58,8 +58,9 @@ int main () /* don't allow BEGIN, END, pattern-action blocks */ qse_awk_setoption (awk, qse_awk_getoption(awk) & ~QSE_AWK_PABLOCK); - psin.type = QSE_AWK_PARSESTD_CP; - psin.u.cp = src; + psin.type = QSE_AWK_PARSESTD_STR; + psin.u.str.ptr = src; + psin.u.str.len = qse_strlen(src); ret = qse_awk_parsestd (awk, &psin, QSE_NULL); if (ret == -1) diff --git a/qse/samples/awk/awk04.c b/qse/samples/awk/awk04.c index 9eeb04f4..3aa7adcf 100644 --- a/qse/samples/awk/awk04.c +++ b/qse/samples/awk/awk04.c @@ -30,7 +30,7 @@ int main () { qse_awk_t* awk = QSE_NULL; qse_awk_rtx_t* rtx = QSE_NULL; - qse_awk_parsestd_in_t psin; + qse_awk_parsestd_t psin; qse_char_t* str; qse_size_t len; qse_awk_val_t* rtv = QSE_NULL; @@ -58,8 +58,9 @@ int main () qse_awk_setoption (awk, opt); - psin.type = QSE_AWK_PARSESTD_CP; - psin.u.cp = src; + psin.type = QSE_AWK_PARSESTD_STR; + psin.u.str.ptr = src; + psin.u.str.len = qse_strlen(src); ret = qse_awk_parsestd (awk, &psin, QSE_NULL); if (ret == -1) diff --git a/qse/samples/awk/awk09.c b/qse/samples/awk/awk09.c index 0518af62..6daa0dc1 100644 --- a/qse/samples/awk/awk09.c +++ b/qse/samples/awk/awk09.c @@ -40,7 +40,7 @@ int main () qse_awk_t* awk = QSE_NULL; qse_awk_rtx_t* rtx = QSE_NULL; qse_awk_val_t* retv; - qse_awk_parsestd_in_t psin; + qse_awk_parsestd_t psin; int ret = -1; const qse_char_t* output_files[] = @@ -65,8 +65,9 @@ int main () qse_awk_setoption (awk, qse_awk_getoption(awk) | QSE_AWK_NEXTOFILE); - psin.type = QSE_AWK_PARSESTD_CP; - psin.u.cp = src; + psin.type = QSE_AWK_PARSESTD_STR; + psin.u.str.ptr = src; + psin.u.str.len = qse_strlen(src); if (qse_awk_parsestd (awk, &psin, QSE_NULL) <= -1) { diff --git a/qse/samples/awk/awk10.c b/qse/samples/awk/awk10.c index 58c35dfe..47686ff5 100644 --- a/qse/samples/awk/awk10.c +++ b/qse/samples/awk/awk10.c @@ -30,7 +30,7 @@ int main () { qse_awk_t* awk = QSE_NULL; qse_awk_rtx_t* rtx = QSE_NULL; - qse_awk_parsestd_in_t psin; + qse_awk_parsestd_t psin; qse_awk_val_t* rtv = QSE_NULL; qse_awk_val_t* arg = QSE_NULL; int ret, i, opt; @@ -65,8 +65,9 @@ int main () qse_awk_setoption (awk, opt); - psin.type = QSE_AWK_PARSESTD_CP; - psin.u.cp = src; + psin.type = QSE_AWK_PARSESTD_STR; + psin.u.str.ptr = src; + psin.u.str.len = qse_strlen(src); ret = qse_awk_parsestd (awk, &psin, QSE_NULL); if (ret == -1) diff --git a/qse/samples/cmn/slmb01.c b/qse/samples/cmn/slmb01.c index 9cdde221..43df25e2 100644 --- a/qse/samples/cmn/slmb01.c +++ b/qse/samples/cmn/slmb01.c @@ -17,6 +17,12 @@ } while (0) static int test1 (void) +{ + qse_printf (QSE_T("slmblenmax=%d\n"), (int)qse_slmblenmax()); + return 0; +} + +static int test2 (void) { int i; const qse_mchar_t* x[] = @@ -80,9 +86,9 @@ static int test1 (void) return 0; } -static int test2 (void) +static int test3 (void) { - const qse_wchar_t unistr[] = + const qse_wchar_t unistr_kr[] = { /*L"\uB108 \uBB50\uAC00 \uC798\uB0AC\uC5B4!",*/ 0xB108, @@ -97,16 +103,31 @@ static int test2 (void) L'\0' }; + const qse_wchar_t unistr_cn[] = + { + /* 智慧手機帶頭 */ + /* \u667A\u6167\u624B\u6A5F\u5E36\u982D */ + 0x667A, + 0x6167, + 0x624B, + 0x6A5F, + 0x5E36, + 0x982D, + L'\0' + }; + const qse_wchar_t* x[] = { L"\0", L"", + L"", L"Fly to the universe" }; char buf[100]; int i, j; - x[1] = unistr; + x[1] = unistr_kr; + x[2] = unistr_cn; for (i = 0; i < QSE_COUNTOF(x); i++) { @@ -162,6 +183,15 @@ int main () setlocale (LC_ALL, locale); qse_setdflcmgr (qse_slmbcmgr); } + +#if 0 + { + WORD LangID = MAKELANGID(LANG_CHINESE, SUBLANG_DEFAULT); + SetThreadLocale(MAKELCID(LangID, SORT_DEFAULT)); + /* SetThreadUILanguage(), SetThreadPreferredUILanguage(). */ + } +#endif + #else setlocale (LC_ALL, ""); qse_setdflcmgr (qse_slmbcmgr); @@ -169,6 +199,7 @@ int main () R (test1); R (test2); + R (test3); return 0; } diff --git a/qse/samples/sed/sed01.c b/qse/samples/sed/sed01.c index b11786d5..767dd912 100644 --- a/qse/samples/sed/sed01.c +++ b/qse/samples/sed/sed01.c @@ -48,7 +48,7 @@ int sed_main (int argc, qse_char_t* argv[]) goto oops; } - if (qse_sed_compstdmem (sed, argv[1]) <= -1) + if (qse_sed_compstdstr (sed, argv[1]) <= -1) { qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_sed_geterrmsg(sed)); goto oops; @@ -57,7 +57,7 @@ int sed_main (int argc, qse_char_t* argv[]) infile = (argc >= 3)? argv[2]: QSE_NULL; outfile = (argc >= 4)? argv[3]: QSE_NULL; - if (qse_sed_execstdfile (sed, infile, outfile) <= -1) + if (qse_sed_execstdfile (sed, infile, outfile, QSE_NULL) <= -1) { qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_sed_geterrmsg(sed)); goto oops;