From cf09e22560ae292d29e1fa22b1a685053d4d877a Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sun, 11 Jan 2009 09:25:33 +0000 Subject: [PATCH] interim commit while writing qse_pio_t functions. - enhanced qse_pio_init() to handle a wide character string. - added qse_wcsntombsnlen(). --- qse/include/qse/cmn/Makefile.in | 2 +- qse/include/qse/cmn/lda.h | 2 +- qse/include/qse/cmn/pio.h | 49 ++++++----- qse/include/qse/cmn/str.h | 28 +++++- qse/lib/awk/parse.c | 38 ++++---- qse/lib/cmn/Makefile.am | 2 +- qse/lib/cmn/Makefile.in | 9 +- qse/lib/cmn/lda.c | 17 ++-- qse/lib/cmn/pio.c | 151 ++++++++++++++++++++++++-------- qse/lib/cmn/str_cnv.c | 80 +++++++++++------ qse/lib/cmn/str_utl.c | 28 +----- qse/test/cmn/chr.c | 4 +- qse/test/cmn/fio.c | 4 +- qse/test/cmn/lda.c | 20 ++--- qse/test/cmn/pio.c | 85 ++++-------------- 15 files changed, 289 insertions(+), 230 deletions(-) diff --git a/qse/include/qse/cmn/Makefile.in b/qse/include/qse/cmn/Makefile.in index 1ecf740b..71d4ef07 100644 --- a/qse/include/qse/cmn/Makefile.in +++ b/qse/include/qse/cmn/Makefile.in @@ -172,7 +172,7 @@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -pkginclude_HEADERS = mem.h chr.h str.h lda.h map.h rex.h sll.h dll.h opt.h fio.h tio.h sio.h time.h +pkginclude_HEADERS = mem.h chr.h str.h lda.h map.h rex.h sll.h dll.h opt.h fio.h pio.h tio.h sio.h time.h CLEANFILES = *dist all: all-am diff --git a/qse/include/qse/cmn/lda.h b/qse/include/qse/cmn/lda.h index bfe4738a..5fe5e5a3 100644 --- a/qse/include/qse/cmn/lda.h +++ b/qse/include/qse/cmn/lda.h @@ -45,7 +45,7 @@ typedef enum qse_lda_walk_t qse_lda_walk_t; #define QSE_LDA_COPIER_SIMPLE ((qse_lda_copier_t)1) #define QSE_LDA_COPIER_INLINE ((qse_lda_copier_t)2) -#define QSE_LDA_INVALID ((qse_size_t)-1) +#define QSE_LDA_NIL ((qse_size_t)-1) #define QSE_LDA_SIZE(lda) ((lda)->size) #define QSE_LDA_CAPA(lda) ((lda)->capa) diff --git a/qse/include/qse/cmn/pio.h b/qse/include/qse/cmn/pio.h index 94bcb854..45b4e10b 100644 --- a/qse/include/qse/cmn/pio.h +++ b/qse/include/qse/cmn/pio.h @@ -50,13 +50,16 @@ enum qse_pio_hid_t QSE_PIO_ERR = 2 }; +typedef enum qse_pio_hid_t qse_pio_hid_t; + #ifdef _WIN32 -/* => typedef PVOID HANDLE; */ -typedef void* qse_pio_hnd_t; -typedef int qse_pio_pid_t; /* TODO */ + /* => typedef PVOID HANDLE; */ + typedef void* qse_pio_hnd_t; + typedef int qse_pio_pid_t; /* TODO */ #else -typedef int qse_pio_hnd_t; -typedef int qse_pio_pid_t; + typedef int qse_pio_hnd_t; + typedef int qse_pio_pid_t; +# define QSE_PIO_HND_NIL ((qse_pio_hnd_t)-1) #endif typedef struct qse_pio_t qse_pio_t; @@ -68,8 +71,8 @@ struct qse_pio_t qse_pio_hnd_t handle[3]; }; -#define QSE_PIO_MMGR(pio) ((pio)->mmgr) -#define QSE_PIO_HANDLE(pio) ((pio)->handle) +#define QSE_PIO_MMGR(pio) ((pio)->mmgr) +#define QSE_PIO_HANDLE(pio,hid) ((pio)->handle[hid]) #ifdef __cplusplus extern "C" { @@ -79,12 +82,16 @@ extern "C" { * NAME * qse_pio_open - open a pipe to a child process * + * DESCRIPTION + * QSE_PIO_SHELL drives the function to execute the command via /bin/sh. + * If flags is clear of QSE_PIO_SHELL, you should pass the full program path. + * * SYNOPSIS */ qse_pio_t* qse_pio_open ( qse_mmgr_t* mmgr, qse_size_t ext, - const qse_char_t* path, + const qse_char_t* cmd, int flags ); /******/ @@ -124,13 +131,13 @@ int qse_pio_wait ( /****f* qse.cmn.pio/qse_pio_gethandle * NAME - * qse_pio_gethandle - get system handle + * qse_pio_gethandle - get native handle * * SYNOPSIS */ qse_pio_hnd_t qse_pio_gethandle ( - qse_pio_t* pio, - int hid + qse_pio_t* pio, + qse_pio_hid_t hid ); /******/ @@ -141,10 +148,10 @@ qse_pio_hnd_t qse_pio_gethandle ( * SYNOPSIS */ qse_ssize_t qse_pio_read ( - qse_pio_t* pio, - void* buf, - qse_size_t size, - int hid + qse_pio_t* pio, + void* buf, + qse_size_t size, + qse_pio_hid_t hid ); /******/ @@ -159,10 +166,10 @@ qse_ssize_t qse_pio_read ( * SYNOPSIS */ qse_ssize_t qse_pio_write ( - qse_pio_t* pio, - const void* data, - qse_size_t size, - int hid + qse_pio_t* pio, + const void* data, + qse_size_t size, + qse_pio_hid_t hid ); /******/ @@ -173,8 +180,8 @@ qse_ssize_t qse_pio_write ( * SYNOPSIS */ void qse_pio_end ( - qse_pio_t* pio, - int hid + qse_pio_t* pio, + qse_pio_hid_t hid ); /******/ diff --git a/qse/include/qse/cmn/str.h b/qse/include/qse/cmn/str.h index 4791d332..f4b9d0c3 100644 --- a/qse/include/qse/cmn/str.h +++ b/qse/include/qse/cmn/str.h @@ -403,12 +403,11 @@ qse_size_t qse_str_nccat ( * SYNOPSIS */ int qse_strspl ( - qse_char_t* s, + qse_char_t* str, const qse_char_t* delim, qse_char_t lquote, qse_char_t rquote, - qse_char_t escape, - qse_size_t* count + qse_char_t escape ); /******/ @@ -464,6 +463,29 @@ qse_size_t qse_wcstombslen ( ); /******/ +/****f* qse.cmn.str/qse_wcsntombsnlen + * NAME + * qse_wcsntombsnlen - get the length + * + * DESCRIPTION + * The qse_wcsntombsnlen() function scans a wide character wcs as long as + * wcslen characters to get the get the total number of multibyte characters + * that it can be converted to. The resulting number of characters is stored + * into memory pointed to by mbslen. + * + * RETURN + * The qse_wcsntombsnlen() function returns the number of wide characters + * handled. + * + * SYNOPSIS + */ +qse_size_t qse_wcsntombsnlen ( + const qse_wchar_t* wcs, + qse_size_t wcslen, + qse_size_t* mbslen +); +/******/ + /****f* qse.cmn.str/qse_wcstombs * NAME * qse_wcstombs - convert a wide character string to a multibyte string. diff --git a/qse/lib/awk/parse.c b/qse/lib/awk/parse.c index 7732aafe..89524cae 100644 --- a/qse/lib/awk/parse.c +++ b/qse/lib/awk/parse.c @@ -871,7 +871,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk) /* check if it coincides to be a global variable name */ g = find_global (awk, name, name_len); - if (g != QSE_LDA_INVALID) + if (g != QSE_LDA_NIL) { SETERRARG ( awk, QSE_AWK_EGBLRED, awk->token.line, @@ -952,7 +952,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk) /* check if a parameter conflicts with other parameters */ if (qse_lda_search (awk->parse.params, - 0, param, param_len) != QSE_LDA_INVALID) + 0, param, param_len) != QSE_LDA_NIL) { QSE_AWK_FREE (awk, name_dup); qse_lda_clear (awk->parse.params); @@ -977,7 +977,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk) if (qse_lda_insert ( awk->parse.params, QSE_LDA_SIZE(awk->parse.params), - param, param_len) == QSE_LDA_INVALID) + param, param_len) == QSE_LDA_NIL) { QSE_AWK_FREE (awk, name_dup); qse_lda_clear (awk->parse.params); @@ -1397,7 +1397,7 @@ int qse_awk_initglobals (qse_awk_t* awk) QSE_LDA_SIZE(awk->parse.globals), (qse_char_t*)gtab[id].name, gtab[id].name_len); - if (g == QSE_LDA_INVALID) return -1; + if (g == QSE_LDA_NIL) return -1; QSE_ASSERT ((int)g == id); @@ -1479,7 +1479,7 @@ static qse_size_t get_global ( cg.name.ptr = name; cg.name.len = len; - cg.index = QSE_LDA_INVALID; + cg.index = QSE_LDA_NIL; cg.walk = QSE_LDA_WALK_BACKWARD; /* return qse_lda_rsearch ( @@ -1497,7 +1497,7 @@ static qse_size_t find_global ( cg.name.ptr = name; cg.name.len = len; - cg.index = QSE_LDA_INVALID; + cg.index = QSE_LDA_NIL; cg.walk = QSE_LDA_WALK_FORWARD; /* return qse_lda_search (awk->parse.globals, 0, name, len); */ @@ -1548,7 +1548,7 @@ static int add_global ( #endif /* check if it conflicts with other global variable names */ - if (find_global (awk, name, len) != QSE_LDA_INVALID) + if (find_global (awk, name, len) != QSE_LDA_NIL) { SETERRARG (awk, QSE_AWK_EDUPGBL, line, name, len); return -1; @@ -1563,7 +1563,7 @@ static int add_global ( if (qse_lda_insert (awk->parse.globals, QSE_LDA_SIZE(awk->parse.globals), - (qse_char_t*)name, len) == QSE_LDA_INVALID) + (qse_char_t*)name, len) == QSE_LDA_NIL) { SETERRLIN (awk, QSE_AWK_ENOMEM, line); return -1; @@ -1625,7 +1625,7 @@ int qse_awk_delglobal ( n = qse_lda_search (awk->parse.globals, QSE_AWK_NUM_STATIC_GLOBALS, name, len); - if (n == QSE_LDA_INVALID) + if (n == QSE_LDA_NIL) { SETERRARG (awk, QSE_AWK_ENOENT, 0, name, len); return -1; @@ -1748,7 +1748,7 @@ static qse_awk_t* collect_locals ( { /* check if it conflicts with a paremeter name */ n = qse_lda_search (awk->parse.params, 0, local.ptr, local.len); - if (n != QSE_LDA_INVALID) + if (n != QSE_LDA_NIL) { SETERRARG ( awk, QSE_AWK_EPARRED, awk->token.line, @@ -1762,7 +1762,7 @@ static qse_awk_t* collect_locals ( awk->parse.locals, nlocals, /*((awk->option&QSE_AWK_SHADING)? nlocals:0)*/ local.ptr, local.len); - if (n != QSE_LDA_INVALID) + if (n != QSE_LDA_NIL) { SETERRARG ( awk, QSE_AWK_EDUPLCL, awk->token.line, @@ -1772,7 +1772,7 @@ static qse_awk_t* collect_locals ( /* check if it conflicts with global variable names */ n = find_global (awk, local.ptr, local.len); - if (n != QSE_LDA_INVALID) + if (n != QSE_LDA_NIL) { if (n < awk->tree.nbglobals) { @@ -1804,7 +1804,7 @@ static qse_awk_t* collect_locals ( if (qse_lda_insert ( awk->parse.locals, QSE_LDA_SIZE(awk->parse.locals), - local.ptr, local.len) == QSE_LDA_INVALID) + local.ptr, local.len) == QSE_LDA_NIL) { SETERRLIN (awk, QSE_AWK_ENOMEM, awk->token.line); return QSE_NULL; @@ -3211,7 +3211,7 @@ static qse_awk_nde_t* parse_primary_ident (qse_awk_t* awk, qse_size_t line) if (nde == QSE_NULL) QSE_AWK_FREE (awk, name_dup); return (qse_awk_nde_t*)nde; } - else if ((idxa = qse_lda_rsearch (awk->parse.locals, QSE_LDA_SIZE(awk->parse.locals), name_dup, name_len)) != QSE_LDA_INVALID) + else if ((idxa = qse_lda_rsearch (awk->parse.locals, QSE_LDA_SIZE(awk->parse.locals), name_dup, name_len)) != QSE_LDA_NIL) { /* local variable */ @@ -3245,7 +3245,7 @@ static qse_awk_nde_t* parse_primary_ident (qse_awk_t* awk, qse_size_t line) return (qse_awk_nde_t*)nde; } - else if ((idxa = qse_lda_search (awk->parse.params, 0, name_dup, name_len)) != QSE_LDA_INVALID) + else if ((idxa = qse_lda_search (awk->parse.params, 0, name_dup, name_len)) != QSE_LDA_NIL) { /* parameter */ @@ -3279,7 +3279,7 @@ static qse_awk_nde_t* parse_primary_ident (qse_awk_t* awk, qse_size_t line) return (qse_awk_nde_t*)nde; } - else if ((idxa = get_global (awk, name_dup, name_len)) != QSE_LDA_INVALID) + else if ((idxa = get_global (awk, name_dup, name_len)) != QSE_LDA_NIL) { /* global variable */ @@ -3486,7 +3486,7 @@ static qse_awk_nde_t* parse_hashidx ( /* search the local variable list */ idxa = qse_lda_rsearch (awk->parse.locals, QSE_LDA_SIZE(awk->parse.locals), name, name_len); - if (idxa != QSE_LDA_INVALID) + if (idxa != QSE_LDA_NIL) { nde->type = QSE_AWK_NDE_LOCALIDX; nde->line = line; @@ -3502,7 +3502,7 @@ static qse_awk_nde_t* parse_hashidx ( /* search the parameter name list */ idxa = qse_lda_search (awk->parse.params, 0, name, name_len); - if (idxa != QSE_LDA_INVALID) + if (idxa != QSE_LDA_NIL) { nde->type = QSE_AWK_NDE_ARGIDX; nde->line = line; @@ -3518,7 +3518,7 @@ static qse_awk_nde_t* parse_hashidx ( /* gets the global variable index */ idxa = get_global (awk, name, name_len); - if (idxa != QSE_LDA_INVALID) + if (idxa != QSE_LDA_NIL) { nde->type = QSE_AWK_NDE_GLOBALIDX; nde->line = line; diff --git a/qse/lib/cmn/Makefile.am b/qse/lib/cmn/Makefile.am index b560dcd5..27aaeac9 100644 --- a/qse/lib/cmn/Makefile.am +++ b/qse/lib/cmn/Makefile.am @@ -4,7 +4,7 @@ AM_CFLAGS = -I$(top_builddir)/include lib_LTLIBRARIES = libqsecmn.la libqsecmn_la_SOURCES = mem.h chr.h \ - mem.c chr.c chr_cnv.c rex.c str_bas.c str_cnv.c str_dyn.c \ + mem.c chr.c chr_cnv.c rex.c str_bas.c str_cnv.c str_dyn.c str_utl.c \ lda.c map.c sll.c dll.c opt.c \ fio.c pio.c sio.c tio.c tio_get.c tio_put.c \ time.c \ diff --git a/qse/lib/cmn/Makefile.in b/qse/lib/cmn/Makefile.in index 2b6f1fc3..1085b1ce 100644 --- a/qse/lib/cmn/Makefile.in +++ b/qse/lib/cmn/Makefile.in @@ -52,9 +52,9 @@ libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) libqsecmn_la_DEPENDENCIES = am_libqsecmn_la_OBJECTS = mem.lo chr.lo chr_cnv.lo rex.lo str_bas.lo \ - str_cnv.lo str_dyn.lo lda.lo map.lo sll.lo dll.lo opt.lo \ - fio.lo pio.lo sio.lo tio.lo tio_get.lo tio_put.lo time.lo \ - misc.lo + str_cnv.lo str_dyn.lo str_utl.lo lda.lo map.lo sll.lo dll.lo \ + opt.lo fio.lo pio.lo sio.lo tio.lo tio_get.lo tio_put.lo \ + time.lo misc.lo libqsecmn_la_OBJECTS = $(am_libqsecmn_la_OBJECTS) libqsecmn_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -196,7 +196,7 @@ AUTOMAKE_OPTIONS = nostdinc AM_CFLAGS = -I$(top_builddir)/include lib_LTLIBRARIES = libqsecmn.la libqsecmn_la_SOURCES = mem.h chr.h \ - mem.c chr.c chr_cnv.c rex.c str_bas.c str_cnv.c str_dyn.c \ + mem.c chr.c chr_cnv.c rex.c str_bas.c str_cnv.c str_dyn.c str_utl.c \ lda.c map.c sll.c dll.c opt.c \ fio.c pio.c sio.c tio.c tio_get.c tio_put.c \ time.c \ @@ -289,6 +289,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_bas.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_cnv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_dyn.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_utl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tio.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tio_get.Plo@am__quote@ diff --git a/qse/lib/cmn/lda.c b/qse/lib/cmn/lda.c index d66590db..83c1283f 100644 --- a/qse/lib/cmn/lda.c +++ b/qse/lib/cmn/lda.c @@ -34,7 +34,6 @@ #define TOB(lda,len) ((len)*(lda)->scale) #define DPTR(node) ((node)->dptr) #define DLEN(node) ((node)->dlen) -#define INVALID QSE_LDA_INVALID static int comp_data (lda_t* lda, const void* dptr1, size_t dlen1, @@ -308,7 +307,7 @@ size_t qse_lda_search (lda_t* lda, size_t pos, const void* dptr, size_t dlen) dptr, dlen) == 0) return i; } - return INVALID; + return QSE_LDA_NIL; } size_t qse_lda_rsearch (lda_t* lda, size_t pos, const void* dptr, size_t dlen) @@ -329,7 +328,7 @@ size_t qse_lda_rsearch (lda_t* lda, size_t pos, const void* dptr, size_t dlen) } } - return INVALID; + return QSE_LDA_NIL; } size_t qse_lda_upsert (lda_t* lda, size_t pos, void* dptr, size_t dlen) @@ -345,7 +344,7 @@ size_t qse_lda_insert (lda_t* lda, size_t pos, void* dptr, size_t dlen) /* allocate the node first */ node = alloc_node (lda, dptr, dlen); - if (node == QSE_NULL) return INVALID; + if (node == QSE_NULL) return QSE_LDA_NIL; /* do resizeing if necessary. * resizing is performed after node allocation because that way, it @@ -378,7 +377,7 @@ size_t qse_lda_insert (lda_t* lda, size_t pos, void* dptr, size_t dlen) if (lda->freeer) lda->freeer (lda, DPTR(node), DLEN(node)); QSE_MMGR_FREE (lda->mmgr, node); - return INVALID; + return QSE_LDA_NIL; } } @@ -388,7 +387,7 @@ size_t qse_lda_insert (lda_t* lda, size_t pos, void* dptr, size_t dlen) if (lda->freeer) lda->freeer (lda, DPTR(node), DLEN(node)); QSE_MMGR_FREE (lda->mmgr, node); - return INVALID; + return QSE_LDA_NIL; } /* fill in the gap with QSE_NULL */ @@ -410,14 +409,14 @@ size_t qse_lda_update (lda_t* lda, size_t pos, void* dptr, size_t dlen) { node_t* c; - if (pos >= lda->size) return INVALID; + if (pos >= lda->size) return QSE_LDA_NIL; c = lda->node[pos]; if (c == QSE_NULL) { /* no previous data */ lda->node[pos] = alloc_node (lda, dptr, dlen); - if (lda->node[pos] == QSE_NULL) return INVALID; + if (lda->node[pos] == QSE_NULL) return QSE_LDA_NIL; } else { @@ -430,7 +429,7 @@ size_t qse_lda_update (lda_t* lda, size_t pos, void* dptr, size_t dlen) { /* updated to different data */ node_t* node = alloc_node (lda, dptr, dlen); - if (node == QSE_NULL) return INVALID; + if (node == QSE_NULL) return QSE_LDA_NIL; if (lda->freeer != QSE_NULL) lda->freeer (lda, DPTR(c), DLEN(c)); diff --git a/qse/lib/cmn/pio.c b/qse/lib/cmn/pio.c index 89c3b938..ff8453e5 100644 --- a/qse/lib/cmn/pio.c +++ b/qse/lib/cmn/pio.c @@ -17,6 +17,7 @@ */ #include +#include #include "mem.h" #ifdef _WIN32 @@ -67,7 +68,15 @@ qse_pio_t* qse_pio_init ( qse_pio_t* pio, qse_mmgr_t* mmgr, const qse_char_t* cmd, int flags) { qse_pio_pid_t pid; - qse_pio_hnd_t handle[6] = { -1, -1, -1, -1, -1, -1 }; + qse_pio_hnd_t handle[6] = + { + QSE_PIO_HND_NIL, + QSE_PIO_HND_NIL, + QSE_PIO_HND_NIL, + QSE_PIO_HND_NIL, + QSE_PIO_HND_NIL, + QSE_PIO_HND_NIL + }; int i, minidx = -1, maxidx = -1; QSE_ASSERT (QSE_COUNTOF(pio->hanlde) == QSE_COUNTOF(handle)); @@ -107,6 +116,14 @@ qse_pio_t* qse_pio_init ( { /* child */ qse_pio_hnd_t devnull; + qse_mchar_t* mcmd; + extern char** environ; + int fcnt = 0; + #ifndef QSE_CHAR_IS_MCHAR + qse_size_t n, mn, wl; + qse_char_t* wcmd = QSE_NULL; + qse_mchar_t buf[64]; + #endif if (flags & QSE_PIO_WRITEIN) { @@ -171,40 +188,88 @@ qse_pio_t* qse_pio_init ( if (flags & QSE_PIO_DROPOUT) QSE_CLOSE(1); if (flags & QSE_PIO_DROPERR) QSE_CLOSE(2); + #ifdef QSE_CHAR_IS_MCHAR + if (flags & QSE_PIO_SHELL) mcmd = (qse_char_t*)cmd; + else + { + mcmd = qse_strdup (cmd, pio->mmgr); + if (mcmd == QSE_NULL) goto child_oops; + + fcnt = qse_strspl (mcmd, QSE_T(""), + QSE_T('\"'), QSE_T('\"'), QSE_T('\'')); + if (fcnt <= 0) + { + /* no field or an error */ + goto child_oops; + } + } + #else if (flags & QSE_PIO_SHELL) { - const qse_mchar_t* mcmd; - qse_mchar_t* argv[4]; - extern char** environ; - - #ifdef QSE_CHAR_IS_MCHAR - mcmd = cmd; - #else - qse_size_t n, mn; - qse_mchar_t buf[64]; - - n = qse_wcstombslen (cmd, &mn); + n = qse_wcstombslen (cmd, &mn); if (cmd[n] != QSE_WT('\0')) { /* cmd has illegal sequence */ goto child_oops; } + } + else + { + wcmd = qse_strdup (cmd, pio->mmgr); + if (wcmd == QSE_NULL) goto child_oops; - mn = mn + 1; - - if (mn <= QSE_COUNTOF(buf)) + fcnt = qse_strspl (wcmd, QSE_T(""), + QSE_T('\"'), QSE_T('\"'), QSE_T('\'')); + if (fcnt <= 0) { - mcmd = buf; - mn = QSE_COUNTOF(buf); + /* no field or an error */ + goto child_oops; } - else + + for (wl = 0, n = fcnt; n > 0; ) { - mcmd = QSE_MMGR_ALLOC ( - pio->mmgr, mn*QSE_SIZEOF(*mcmd)); - if (mcmd == QSE_NULL) goto child_oops; + if (wcmd[wl++] == QSE_T('\0')) n--; } - n = qse_wcstombs (cmd, mcmd, &mn); + n = qse_wcsntombsnlen (wcmd, wl, &mn); + if (n != wl) goto child_oops; + } + + mn = mn + 1; + + if (mn <= QSE_COUNTOF(buf)) + { + mcmd = buf; + mn = QSE_COUNTOF(buf); + } + else + { + mcmd = QSE_MMGR_ALLOC ( + pio->mmgr, mn*QSE_SIZEOF(*mcmd)); + if (mcmd == QSE_NULL) goto child_oops; + } + + if (flags & QSE_PIO_SHELL) + { + /* qse_wcstombs() should succeed as + * qse_wcstombslen() was successful above */ + qse_wcstombs (cmd, mcmd, &mn); + /* qse_wcstombs() null-terminate mcmd */ + } + else + { + QSE_ASSERT (wcmd != QSE_NULL); + /* qse_wcsntombsn() should succeed as + * qse_wcsntombsnlen() was successful above */ + qse_wcsntombsn (wcmd, wl, mcmd, &mn); + /* qse_wcsntombsn() doesn't null-terminate mcmd */ + mcmd[mn] = QSE_MT('\0'); + } + #endif + + if (flags & QSE_PIO_SHELL) + { + const qse_mchar_t* argv[4]; argv[0] = QSE_MT("/bin/sh"); argv[1] = QSE_MT("-c"); @@ -215,14 +280,26 @@ qse_pio_t* qse_pio_init ( } else { - /* TODO: need to parse the command in a simple manner */ - QSE_EXECVE (mcmd, argv, environ); + int i; + qse_mchar_t** argv; + + argv = QSE_MMGR_ALLOC (pio->mmgr, (fcnt+1)*QSE_SIZEOF(argv[0])); + if (argv == QSE_NULL) goto child_oops; + + for (i = 0; i < fcnt; i++) + { + argv[i] = mcmd; + while (*mcmd != QSE_MT('\0')) mcmd++; + mcmd++; + } + argv[i] = QSE_NULL; + + QSE_EXECVE (argv[0], argv, environ); } child_oops: QSE_EXIT(127); } -#endif /* parent */ pio->child = pid; @@ -235,7 +312,7 @@ qse_pio_t* qse_pio_init ( * X * WRITE => 1 */ - QSE_CLOSE (handle[0]); handle[0] = -1; + QSE_CLOSE (handle[0]); handle[0] = QSE_PIO_HND_NIL; } if (flags & QSE_PIO_READOUT) @@ -246,7 +323,7 @@ qse_pio_t* qse_pio_init ( * X * READ => 2 */ - QSE_CLOSE (handle[3]); handle[3] = -1; + QSE_CLOSE (handle[3]); handle[3] = QSE_PIO_HND_NIL; } if (flags & QSE_PIO_READERR) @@ -257,7 +334,7 @@ qse_pio_t* qse_pio_init ( * X * READ => 4 */ - QSE_CLOSE (handle[5]); handle[5] = -1; + QSE_CLOSE (handle[5]); handle[5] = QSE_PIO_HND_NIL; } #endif @@ -303,7 +380,7 @@ int qse_pio_wait (qse_pio_t* pio) while (1) { - n = waitpid (pio->child, &status, opt); + n = QSE_WAITPID (pio->child, &status, opt); if (n == 0) break; /* TODO: .... */ } @@ -315,13 +392,13 @@ int qse_pio_wait (qse_pio_t* pio) return -1; } -qse_pio_hnd_t qse_pio_gethandle (qse_pio_t* pio, int hid) +qse_pio_hnd_t qse_pio_gethandle (qse_pio_t* pio, qse_pio_hid_t hid) { return pio->handle[hid]; } qse_ssize_t qse_pio_read ( - qse_pio_t* pio, void* buf, qse_size_t size, int hid) + qse_pio_t* pio, void* buf, qse_size_t size, qse_pio_hid_t hid) { #ifdef _WIN32 DWORD count; @@ -329,7 +406,7 @@ qse_ssize_t qse_pio_read ( if (ReadFile(pio->handle, buf, size, &count, QSE_NULL) == FALSE) return -1; return (qse_ssize_t)count; #else - if (pio->handle[hid] == -1) + if (pio->handle[hid] == QSE_PIO_HND_NIL) { /* the stream is already closed */ return (qse_ssize_t)-1; @@ -341,7 +418,7 @@ qse_ssize_t qse_pio_read ( } qse_ssize_t qse_pio_write ( - qse_pio_t* pio, const void* data, qse_size_t size, int hid) + qse_pio_t* pio, const void* data, qse_size_t size, qse_pio_hid_t hid) { #ifdef _WIN32 DWORD count; @@ -349,7 +426,7 @@ qse_ssize_t qse_pio_write ( if (WriteFile(pio->handle, data, size, &count, QSE_NULL) == FALSE) return -1; return (qse_ssize_t)count; #else - if (pio->handle[hid] == -1) + if (pio->handle[hid] == QSE_PIO_HND_NIL) { /* the stream is already closed */ return (qse_ssize_t)-1; @@ -360,11 +437,11 @@ qse_ssize_t qse_pio_write ( #endif } -void qse_pio_end (qse_pio_t* pio, int hid) +void qse_pio_end (qse_pio_t* pio, qse_pio_hid_t hid) { - if (pio->handle[hid] != -1) + if (pio->handle[hid] != QSE_PIO_HND_NIL) { QSE_CLOSE (pio->handle[hid]); - pio->handle[hid] = -1; + pio->handle[hid] = QSE_PIO_HND_NIL; } } diff --git a/qse/lib/cmn/str_cnv.c b/qse/lib/cmn/str_cnv.c index 2b29c122..9e750cca 100644 --- a/qse/lib/cmn/str_cnv.c +++ b/qse/lib/cmn/str_cnv.c @@ -186,6 +186,60 @@ qse_size_t qse_mbsntowcsn ( return p - mbs; /* returns the number of bytes processed */ } +qse_size_t qse_wcstombslen (const qse_wchar_t* wcs, qse_size_t* mbslen) +{ + const qse_wchar_t* p = wcs; + qse_mchar_t mbs[32]; + qse_size_t mlen = 0; + + while (*p != QSE_WT('\0')) + { + qse_size_t n = qse_wctomb (*p, mbs, QSE_COUNTOF(mbs)); + if (n == 0) break; /* illegal character */ + + /* it assumes that mbs is large enough to hold a character */ + QSE_ASSERT (n <= QSE_COUNTOF(mbs)); + + p++; mlen += n; + } + + /* this length excludes the terminating null character. */ + *mbslen = mlen; + + /* returns the number of characters handled. + * if the function has encountered an illegal character in + * the while loop above, wcs[p-wcs] will not be a null character */ + return p - wcs; +} + +qse_size_t qse_wcsntombsnlen ( + const qse_wchar_t* wcs, qse_size_t wcslen, qse_size_t* mbslen) +{ + const qse_wchar_t* p = wcs; + const qse_wchar_t* end = wcs + wcslen; + qse_mchar_t mbs[32]; + qse_size_t mlen = 0; + + while (p < end) + { + qse_size_t n = qse_wctomb (*p, mbs, QSE_COUNTOF(mbs)); + if (n == 0) break; /* illegal character */ + + /* it assumes that mbs is large enough to hold a character */ + QSE_ASSERT (n <= QSE_COUNTOF(mbs)); + + p++; mlen += n; + } + + /* this length excludes the terminating null character. */ + *mbslen = mlen; + + /* returns the number of characters handled. + * if the function has encountered an illegal character in + * the while loop above, wcs[p-wcs] will not be a null character */ + return p - wcs; +} + qse_size_t qse_wcstombs ( const qse_wchar_t* wcs, qse_mchar_t* mbs, qse_size_t* mbslen) { @@ -221,32 +275,6 @@ qse_size_t qse_wcstombs ( return p - wcs; } -qse_size_t qse_wcstombslen (const qse_wchar_t* wcs, qse_size_t* mbslen) -{ - const qse_wchar_t* p = wcs; - qse_mchar_t mbs[32]; - qse_size_t mlen = 0; - - while (*p != QSE_WT('\0')) - { - qse_size_t n = qse_wctomb (*p, mbs, QSE_COUNTOF(mbs)); - if (n == 0) break; /* illegal character */ - - /* it assumes that mbs is large enough to hold a character */ - QSE_ASSERT (n <= QSE_COUNTOF(mbs)); - - p++; mlen += n; - } - - /* this length excludes the terminating null character. */ - *mbslen = mlen; - - /* returns the number of characters handled. - * if the function has encountered an illegal character in - * the while loop above, wcs[p-wcs] will not be a null character */ - return p - wcs; -} - qse_size_t qse_wcsntombsn ( const qse_wchar_t* wcs, qse_size_t wcslen, qse_mchar_t* mbs, qse_size_t* mbslen) diff --git a/qse/lib/cmn/str_utl.c b/qse/lib/cmn/str_utl.c index b72926e3..cb43b727 100644 --- a/qse/lib/cmn/str_utl.c +++ b/qse/lib/cmn/str_utl.c @@ -16,18 +16,17 @@ limitations under the License. */ -#includle +#include #include "chr.h" int qse_strspl ( qse_char_t* s, const qse_char_t* delim, - qse_char_t lquote, qse_char_t rquote, - qse_char_t escape, qse_size_t* count) + qse_char_t lquote, qse_char_t rquote, qse_char_t escape) { qse_char_t* p = s, *d; qse_char_t* sp = QSE_NULL, * ep = QSE_NULL; int delim_mode; - qse_size_t cnt = 0; + int cnt = 0; if (delim == QSE_NULL) delim_mode = 0; else @@ -258,25 +257,6 @@ exit_point: } - *count = cnt; - return 0; + return cnt; } -int qse_strspls ( - qse_char_t* s, const qse_char_t* delim, - qse_char_t lquote, qse_char_t rquote, - qse_char_t escape, qse_size_t* count, qse_char_t* ptrs[]) -{ - qse_size_t cnt = *count, i; - - if (qse_strspl (s, delim, lquote, rquote, escape, count) == -1) return -1; - for (i = 0; i < *count && i < cnt; i++) - { - ptrs[i] = s; - s += qse_strlen(s) + 1; - } - - return 0; -} - - diff --git a/qse/test/cmn/chr.c b/qse/test/cmn/chr.c index 47e535a3..72728185 100644 --- a/qse/test/cmn/chr.c +++ b/qse/test/cmn/chr.c @@ -74,7 +74,7 @@ static int test2 (void) } else { - #if QSE_CHAR_IS_MCHAR + #ifdef QSE_CHAR_IS_MCHAR qse_printf (QSE_T("%C"), wc); #else qse_printf (QSE_T("%c"), wc); @@ -127,7 +127,7 @@ static int test3 (void) } else { - #if QSE_CHAR_IS_MCHAR + #ifdef QSE_CHAR_IS_MCHAR qse_printf (QSE_T("%.*s"), (int)n, buf); #else qse_printf (QSE_T("%.*S"), (int)n, buf); diff --git a/qse/test/cmn/fio.c b/qse/test/cmn/fio.c index de724e0b..2a0c157e 100644 --- a/qse/test/cmn/fio.c +++ b/qse/test/cmn/fio.c @@ -60,7 +60,7 @@ static int test1 (void) if (n > 0) { #ifdef QSE_CHAR_IS_MCHAR - qse_printf (QSE_T("buf => [%.*s]\n"), (int)n. buf); + qse_printf (QSE_T("buf => [%.*s]\n"), (int)n, buf); #else qse_printf (QSE_T("buf => [%.*S]\n"), (int)n, buf); #endif @@ -139,7 +139,7 @@ static int test2 (void) if (n > 0) { #ifdef QSE_CHAR_IS_MCHAR - qse_printf (QSE_T("buf => [%.*s]\n"), (int)n. buf); + qse_printf (QSE_T("buf => [%.*s]\n"), (int)n, buf); #else qse_printf (QSE_T("buf => [%.*S]\n"), (int)n, buf); #endif diff --git a/qse/test/cmn/lda.c b/qse/test/cmn/lda.c index eab6f635..d72b7023 100644 --- a/qse/test/cmn/lda.c +++ b/qse/test/cmn/lda.c @@ -53,7 +53,7 @@ static int test1 () for (i = 0; i < QSE_COUNTOF(x); i++) { - if (qse_lda_insert (s1, 0, x[i], qse_strlen(x[i])) == QSE_LDA_INVALID) + if (qse_lda_insert (s1, 0, x[i], qse_strlen(x[i])) == QSE_LDA_NIL) { qse_printf (QSE_T("failed to add at 0 => [%.*s]\n"), (int)qse_strlen(x[i]), x[i]); @@ -65,7 +65,7 @@ static int test1 () } } - if (qse_lda_update (s1, 0, QSE_LDA_DPTR(s1,0), QSE_LDA_DLEN(s1,0)) == QSE_LDA_INVALID) + if (qse_lda_update (s1, 0, QSE_LDA_DPTR(s1,0), QSE_LDA_DLEN(s1,0)) == QSE_LDA_NIL) { qse_printf (QSE_T("failed to update index 0 with [%.*s]\n"), (int)QSE_LDA_DLEN(s1,0), QSE_LDA_DPTR(s1,0)); } @@ -74,7 +74,7 @@ static int test1 () qse_printf (QSE_T("updated index 0 with [%.*s]\n"), (int)QSE_LDA_DLEN(s1,0), QSE_LDA_DPTR(s1,0)); } - if (qse_lda_update (s1, 0, QSE_LDA_DPTR(s1,1), QSE_LDA_DLEN(s1,1)) == QSE_LDA_INVALID) + if (qse_lda_update (s1, 0, QSE_LDA_DPTR(s1,1), QSE_LDA_DLEN(s1,1)) == QSE_LDA_NIL) { qse_printf (QSE_T("updated index 0 with [%.*s]\n"), (int)QSE_LDA_DLEN(s1,1), QSE_LDA_DPTR(s1,1)); } @@ -85,7 +85,7 @@ static int test1 () for (i = 0; i < QSE_COUNTOF(x); i++) { - if (qse_lda_insert (s1, 10, x[i], qse_strlen(x[i])) == QSE_LDA_INVALID) + if (qse_lda_insert (s1, 10, x[i], qse_strlen(x[i])) == QSE_LDA_NIL) { qse_printf (QSE_T("failed to add at 10 => [%.*s]\n"), (int)qse_strlen(x[i]), x[i]); @@ -141,7 +141,7 @@ static int test2 () qse_size_t index; for (i = 0; i < QSE_COUNTOF(x); i++) { - if (qse_lda_insert (s1, (i + 1) * j - 1, x[i], qse_strlen(x[i])) == QSE_LDA_INVALID) + if (qse_lda_insert (s1, (i + 1) * j - 1, x[i], qse_strlen(x[i])) == QSE_LDA_NIL) { qse_printf (QSE_T("failed to add at %u => [%.*s]\n"), @@ -169,7 +169,7 @@ static int test2 () for (i = 0; i < QSE_COUNTOF(y); i++) { index = qse_lda_search (s1, 0, y[i], qse_strlen(y[i])); - if (index == QSE_LDA_INVALID) + if (index == QSE_LDA_NIL) { qse_printf (QSE_T("failed to find [%s]\n"), y[i]); } @@ -180,7 +180,7 @@ static int test2 () } index = qse_lda_rsearch (s1, QSE_LDA_SIZE(s1), y[i], qse_strlen(y[i])); - if (index == QSE_LDA_INVALID) + if (index == QSE_LDA_NIL) { qse_printf (QSE_T("failed to find [%s]\n"), y[i]); } @@ -228,7 +228,7 @@ static int test3 () { for (i = 0; i < QSE_COUNTOF(x); i++) { - if (qse_lda_insert (s1, (i + 1) * j - 1, x[i], qse_strlen(x[i])) == QSE_LDA_INVALID) + if (qse_lda_insert (s1, (i + 1) * j - 1, x[i], qse_strlen(x[i])) == QSE_LDA_NIL) { qse_printf (QSE_T("failed to add at %u => [%.*s]\n"), @@ -259,7 +259,7 @@ static int test3 () if (i < QSE_LDA_SIZE(s1)) { - if (qse_lda_update (s1, i, y, qse_strlen(y)) == QSE_LDA_INVALID) + if (qse_lda_update (s1, i, y, qse_strlen(y)) == QSE_LDA_NIL) { qse_printf (QSE_T("failed to update at %d => [%.*s]\n"), i, (int)qse_strlen(y), y); @@ -338,7 +338,7 @@ static int test4 () for (i = 0; i < QSE_COUNTOF(x); i++) { - if (qse_lda_insert (s1, 0, x[i], qse_strlen(x[i])) == QSE_LDA_INVALID) + if (qse_lda_insert (s1, 0, x[i], qse_strlen(x[i])) == QSE_LDA_NIL) { qse_printf (QSE_T("failed to add at 0 => [%.*s]\n"), (int)qse_strlen(x[i]), x[i]); diff --git a/qse/test/cmn/pio.c b/qse/test/cmn/pio.c index fe39e6ae..3d5f2170 100644 --- a/qse/test/cmn/pio.c +++ b/qse/test/cmn/pio.c @@ -10,15 +10,15 @@ if (f() == -1) return -1; \ } while (0) -static int test1 (void) +static int pio1 (const qse_char_t* cmd, int oflags, qse_pio_hid_t rhid) { qse_pio_t* pio; pio = qse_pio_open ( QSE_NULL, 0, - QSE_T("ls -laF"), - QSE_PIO_READOUT|QSE_PIO_WRITEIN|QSE_PIO_SHELL + cmd, + oflags ); if (pio == QSE_NULL) { @@ -31,7 +31,7 @@ static int test1 (void) qse_byte_t buf[128]; /*qse_pio_canread (pio, QSE_PIO_ERR, 1000)*/ - qse_ssize_t n = qse_pio_read (pio, buf, sizeof(buf), QSE_PIO_OUT); + qse_ssize_t n = qse_pio_read (pio, buf, sizeof(buf), rhid); if (n == 0) break; if (n < 0) { @@ -41,7 +41,7 @@ static int test1 (void) qse_printf (QSE_T("N===> %d\n"), (int)n); #ifdef QSE_CHAR_IS_MCHAR - qse_printf (QSE_T("buf => [%.*s]\n"), (int)n. buf); + qse_printf (QSE_T("buf => [%.*s]\n"), (int)n, buf); #else qse_printf (QSE_T("buf => [%.*S]\n"), (int)n, buf); #endif @@ -53,77 +53,21 @@ static int test1 (void) return 0; } +static int test1 (void) +{ + return pio1 (QSE_T("ls -laF"), QSE_PIO_READOUT|QSE_PIO_WRITEIN|QSE_PIO_SHELL, QSE_PIO_OUT); +} + static int test2 (void) { - qse_pio_t* pio; - - pio = qse_pio_open ( - QSE_NULL, - 0, - QSE_T("ls -laF"), - QSE_PIO_READERR|QSE_PIO_WRITEIN|QSE_PIO_OUTTOERR|QSE_PIO_SHELL - ); - if (pio == QSE_NULL) - { - qse_printf (QSE_T("cannot open program through pipe\n")); - return -1; - } - - while (1) - { - qse_byte_t buf[128]; - - qse_ssize_t n = qse_pio_read (pio, buf, sizeof(buf), QSE_PIO_ERR); - if (n == 0) break; - if (n < 0) - { - qse_printf (QSE_T("qse_pio_read() returned error\n")); - break; - } - - qse_printf (QSE_T("N===> %d\n"), (int)n); - #ifdef QSE_CHAR_IS_MCHAR - qse_printf (QSE_T("buf => [%.*s]\n"), (int)n. buf); - #else - qse_printf (QSE_T("buf => [%.*S]\n"), (int)n, buf); - #endif - - } - - qse_pio_close (pio); - - return 0; + return pio1 (QSE_T("ls -laF"), QSE_PIO_READERR|QSE_PIO_OUTTOERR|QSE_PIO_WRITEIN|QSE_PIO_SHELL, QSE_PIO_ERR); } -#if 0 -static int test1 (void) +static int test3 (void) { - qse_pio_t* pio; - - pio = qse_pio_open ( - QSE_NULL, - 0, - QSE_T("ls -laF"), - QSE_PIO_READ | QSE_PIO_WRITE | QSE_PIO_READ_ERR - ); - if (pio == QSE_NULL) - { - qse_printf (QSE_T("cannot open program through pipe\n")); - return -1; - } - - -qse_pio_open (RW, "/bin/ls -laF", R, W, E) - qse_pio_write ("xxx"); - - qse_pio_read (buf, QSE_COUNOF(buf), QSE_PIO_OUT); - qse_pio_read (buf, QSE_COUNOF(buf), QSE_PIO_ERR); - qse_pio_write ("xxxx", 4, QSE_PIO_IN | QSE_PIO_EOF); - - qse_pio_close (pio); - return 0; + //return pio1 (QSE_T("/bin/ls -laF"), QSE_PIO_READERR|QSE_PIO_OUTTOERR|QSE_PIO_WRITEIN, QSE_PIO_ERR); + return pio1 (QSE_T("\"/bin/ls\" -laF"), QSE_PIO_READERR|QSE_PIO_OUTTOERR|QSE_PIO_WRITEIN, QSE_PIO_ERR); } -#endif int main () { @@ -135,6 +79,7 @@ int main () R (test1); R (test2); + R (test3); return 0; }