enhanced lda with binary heap functions
added more wide character handling functions
This commit is contained in:
		| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * $Id: parse.c 312 2009-12-10 13:03:54Z hyunghwan.chung $ | ||||
|  * $Id: parse.c 323 2010-04-05 12:50:01Z hyunghwan.chung $ | ||||
|  * | ||||
|     Copyright 2006-2009 Chung, Hyung-Hwan. | ||||
|     This file is part of QSE. | ||||
| @ -226,8 +226,6 @@ static int skip_spaces (qse_awk_t* awk); | ||||
| static int skip_comment (qse_awk_t* awk); | ||||
| static int classify_ident ( | ||||
| 	qse_awk_t* awk, const qse_char_t* name, qse_size_t len); | ||||
| static int is_plain_var (qse_awk_nde_t* nde); | ||||
| static int is_var (qse_awk_nde_t* nde); | ||||
|  | ||||
| static int deparse (qse_awk_t* awk); | ||||
| static qse_map_walk_t deparse_func ( | ||||
| @ -400,6 +398,26 @@ static global_t gtab[] = | ||||
|  | ||||
| #define SETERR_ARG(awk,code,ep,el) SETERR_ARG_LOC(awk,code,ep,el,QSE_NULL) | ||||
|  | ||||
| static QSE_INLINE int is_plain_var (qse_awk_nde_t* nde) | ||||
| { | ||||
| 	return nde->type == QSE_AWK_NDE_GBL || | ||||
| 	       nde->type == QSE_AWK_NDE_LCL || | ||||
| 	       nde->type == QSE_AWK_NDE_ARG || | ||||
| 	       nde->type == QSE_AWK_NDE_NAMED; | ||||
| } | ||||
|  | ||||
| static QSE_INLINE int is_var (qse_awk_nde_t* nde) | ||||
| { | ||||
| 	return nde->type == QSE_AWK_NDE_GBL || | ||||
| 	       nde->type == QSE_AWK_NDE_LCL || | ||||
| 	       nde->type == QSE_AWK_NDE_ARG || | ||||
| 	       nde->type == QSE_AWK_NDE_NAMED || | ||||
| 	       nde->type == QSE_AWK_NDE_GBLIDX || | ||||
| 	       nde->type == QSE_AWK_NDE_LCLIDX || | ||||
| 	       nde->type == QSE_AWK_NDE_ARGIDX || | ||||
| 	       nde->type == QSE_AWK_NDE_NAMEDIDX; | ||||
| } | ||||
|  | ||||
| static int get_char (qse_awk_t* awk) | ||||
| { | ||||
| 	qse_ssize_t n; | ||||
| @ -5762,26 +5780,6 @@ static int classify_ident ( | ||||
| 	return TOK_IDENT; | ||||
| } | ||||
|  | ||||
| static int is_plain_var (qse_awk_nde_t* nde) | ||||
| { | ||||
| 	return nde->type == QSE_AWK_NDE_GBL || | ||||
| 	       nde->type == QSE_AWK_NDE_LCL || | ||||
| 	       nde->type == QSE_AWK_NDE_ARG || | ||||
| 	       nde->type == QSE_AWK_NDE_NAMED; | ||||
| } | ||||
|  | ||||
| static int is_var (qse_awk_nde_t* nde) | ||||
| { | ||||
| 	return nde->type == QSE_AWK_NDE_GBL || | ||||
| 	       nde->type == QSE_AWK_NDE_LCL || | ||||
| 	       nde->type == QSE_AWK_NDE_ARG || | ||||
| 	       nde->type == QSE_AWK_NDE_NAMED || | ||||
| 	       nde->type == QSE_AWK_NDE_GBLIDX || | ||||
| 	       nde->type == QSE_AWK_NDE_LCLIDX || | ||||
| 	       nde->type == QSE_AWK_NDE_ARGIDX || | ||||
| 	       nde->type == QSE_AWK_NDE_NAMEDIDX; | ||||
| } | ||||
|  | ||||
| struct deparse_func_t  | ||||
| { | ||||
| 	qse_awk_t* awk; | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * $Id: run.c 312 2009-12-10 13:03:54Z hyunghwan.chung $ | ||||
|  * $Id: run.c 323 2010-04-05 12:50:01Z hyunghwan.chung $ | ||||
|  * | ||||
|     Copyright 2006-2009 Chung, Hyung-Hwan. | ||||
|     This file is part of QSE. | ||||
| @ -273,17 +273,17 @@ static qse_cstr_t* xstr_to_cstr (qse_xstr_t* xstr) | ||||
| } | ||||
| #endif | ||||
|  | ||||
| qse_size_t qse_awk_rtx_getnargs (qse_awk_rtx_t* run) | ||||
| QSE_INLINE qse_size_t qse_awk_rtx_getnargs (qse_awk_rtx_t* run) | ||||
| { | ||||
| 	return (qse_size_t) STACK_NARGS (run); | ||||
| } | ||||
|  | ||||
| qse_awk_val_t* qse_awk_rtx_getarg (qse_awk_rtx_t* run, qse_size_t idx) | ||||
| QSE_INLINE qse_awk_val_t* qse_awk_rtx_getarg (qse_awk_rtx_t* run, qse_size_t idx) | ||||
| { | ||||
| 	return STACK_ARG (run, idx); | ||||
| } | ||||
|  | ||||
| qse_awk_val_t* qse_awk_rtx_getgbl (qse_awk_rtx_t* run, int id) | ||||
| QSE_INLINE qse_awk_val_t* qse_awk_rtx_getgbl (qse_awk_rtx_t* run, int id) | ||||
| { | ||||
| 	QSE_ASSERT (id >= 0 && id < (int)QSE_LDA_SIZE(run->awk->parse.gbls)); | ||||
| 	return STACK_GBL (run, id); | ||||
| @ -618,7 +618,7 @@ static int set_global ( | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void qse_awk_rtx_setretval (qse_awk_rtx_t* rtx, qse_awk_val_t* val) | ||||
| QSE_INLINE void qse_awk_rtx_setretval (qse_awk_rtx_t* rtx, qse_awk_val_t* val) | ||||
| { | ||||
| 	qse_awk_rtx_refdownval (rtx, STACK_RETVAL(rtx)); | ||||
| 	STACK_RETVAL(rtx) = val; | ||||
| @ -626,7 +626,7 @@ void qse_awk_rtx_setretval (qse_awk_rtx_t* rtx, qse_awk_val_t* val) | ||||
| 	qse_awk_rtx_refupval (rtx, val); | ||||
| } | ||||
|  | ||||
| int qse_awk_rtx_setgbl (qse_awk_rtx_t* rtx, int id, qse_awk_val_t* val) | ||||
| QSE_INLINE int qse_awk_rtx_setgbl (qse_awk_rtx_t* rtx, int id, qse_awk_val_t* val) | ||||
| { | ||||
| 	QSE_ASSERT (id >= 0 && id < (int)QSE_LDA_SIZE(rtx->awk->parse.gbls)); | ||||
| 	return set_global (rtx, (qse_size_t)id, QSE_NULL, val); | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * $Id: chr_cnv.c 287 2009-09-15 10:01:02Z hyunghwan.chung $ | ||||
|  * $Id: chr_cnv.c 323 2010-04-05 12:50:01Z hyunghwan.chung $ | ||||
|  * | ||||
|     Copyright 2006-2009 Chung, Hyung-Hwan. | ||||
|     This file is part of QSE. | ||||
| @ -41,6 +41,13 @@ qse_size_t qse_mblen (const qse_mchar_t* mb, qse_size_t mblen) | ||||
| 	if (n == (size_t)-2) return mblen + 1; /* incomplete sequence */ | ||||
|  | ||||
| 	return (qse_size_t)n; | ||||
|  | ||||
| 	#if 0 | ||||
| 	n = mblen (mb, mblen, &mbs); | ||||
| 	if (n == 0) return 1; /* a null character */ | ||||
| 	if (n == (size_t)-1) return 0; /* invalid or incomplete sequence */ | ||||
| 	return (qse_size_t)n; | ||||
| 	#endif | ||||
| #else | ||||
| 	#error #### NOT SUPPORTED #### | ||||
| #endif | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * $Id: fio.c 287 2009-09-15 10:01:02Z hyunghwan.chung $ | ||||
|  * $Id: fio.c 323 2010-04-05 12:50:01Z hyunghwan.chung $ | ||||
|  * | ||||
|     Copyright 2006-2009 Chung, Hyung-Hwan. | ||||
|     This file is part of QSE. | ||||
| @ -213,16 +213,16 @@ qse_fio_t* qse_fio_init ( | ||||
| 		qse_tio_t* tio; | ||||
|  | ||||
| 		tio = qse_tio_open (fio->mmgr, 0); | ||||
| 		if (tio == QSE_NULL) QSE_ERR_THROW (tio); | ||||
| 		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) | ||||
| 		{ | ||||
| 			qse_tio_close (tio); | ||||
| 			QSE_ERR_THROW (tio); | ||||
| 			QSE_THROW_ERR (tio); | ||||
| 		} | ||||
|  | ||||
| 		QSE_ERR_CATCH (tio)  | ||||
| 		QSE_CATCH_ERR (tio)  | ||||
| 		{ | ||||
| 		#ifdef _WIN32 | ||||
| 			CloseHandle (handle); | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * $Id: lda.c 287 2009-09-15 10:01:02Z hyunghwan.chung $ | ||||
|  * $Id: lda.c 323 2010-04-05 12:50:01Z hyunghwan.chung $ | ||||
|  * | ||||
|     Copyright 2006-2009 Chung, Hyung-Hwan. | ||||
|     This file is part of QSE. | ||||
| @ -39,7 +39,7 @@ QSE_IMPLEMENT_COMMON_FUNCTIONS (lda) | ||||
| #define DPTR(node)   ((node)->dptr) | ||||
| #define DLEN(node)   ((node)->dlen) | ||||
|  | ||||
| static int comp_data (lda_t* lda,  | ||||
| static int default_comparator (lda_t* lda,  | ||||
| 	const void* dptr1, size_t dlen1,  | ||||
| 	const void* dptr2, size_t dlen2) | ||||
| { | ||||
| @ -58,7 +58,7 @@ static int comp_data (lda_t* lda, | ||||
| 	return n; | ||||
| } | ||||
|  | ||||
| static node_t* alloc_node (lda_t* lda, void* dptr, size_t dlen) | ||||
| static QSE_INLINE node_t* alloc_node (lda_t* lda, void* dptr, size_t dlen) | ||||
| { | ||||
| 	node_t* n; | ||||
|  | ||||
| @ -136,7 +136,7 @@ lda_t* qse_lda_init (lda_t* lda, mmgr_t* mmgr, size_t capa) | ||||
| 	lda->node = QSE_NULL; | ||||
|  | ||||
| 	lda->copier = QSE_LDA_COPIER_SIMPLE; | ||||
| 	lda->comper = comp_data; | ||||
| 	lda->comper = default_comparator; | ||||
|  | ||||
| 	if (qse_lda_setcapa (lda, capa) == QSE_NULL) return QSE_NULL; | ||||
| 	return lda; | ||||
| @ -162,7 +162,8 @@ int qse_lda_getscale (lda_t* lda) | ||||
| void qse_lda_setscale (lda_t* lda, int scale) | ||||
| { | ||||
| 	QSE_ASSERTX (scale > 0 && scale <= QSE_TYPE_MAX(qse_byte_t),  | ||||
| 		"The scale should be larger than 0 and less than or equal to the maximum value that the qse_byte_t type can hold"); | ||||
| 		"The scale should be larger than 0 and less than or " | ||||
| 		"equal to the maximum value that the qse_byte_t type can hold"); | ||||
|  | ||||
| 	if (scale <= 0) scale = 1; | ||||
| 	if (scale > QSE_TYPE_MAX(qse_byte_t)) scale = QSE_TYPE_MAX(qse_byte_t); | ||||
| @ -198,7 +199,7 @@ comper_t qse_lda_getcomper (lda_t* lda) | ||||
|  | ||||
| void qse_lda_setcomper (lda_t* lda, comper_t comper) | ||||
| { | ||||
| 	if (comper == QSE_NULL) comper = comp_data; | ||||
| 	if (comper == QSE_NULL) comper = default_comparator; | ||||
| 	lda->comper = comper; | ||||
| } | ||||
|  | ||||
| @ -236,8 +237,11 @@ lda_t* qse_lda_setcapa (lda_t* lda, size_t capa) | ||||
| { | ||||
| 	void* tmp; | ||||
|  | ||||
| 	if (capa == lda->capa) return lda; | ||||
|  | ||||
| 	if (lda->size > capa)  | ||||
| 	{ | ||||
| 		/* to trigger freeers on the items truncated */ | ||||
| 		qse_lda_delete (lda, capa, lda->size - capa); | ||||
| 		QSE_ASSERT (lda->size <= capa); | ||||
| 	} | ||||
| @ -246,13 +250,14 @@ lda_t* qse_lda_setcapa (lda_t* lda, size_t capa) | ||||
| 	{ | ||||
| 		if (lda->mmgr->realloc != QSE_NULL && lda->node != QSE_NULL) | ||||
| 		{ | ||||
| 			tmp = (qse_lda_node_t**)QSE_MMGR_REALLOC ( | ||||
| 				lda->mmgr, lda->node, QSE_SIZEOF(*lda->node)*capa); | ||||
| 			tmp = (node_t**) QSE_MMGR_REALLOC ( | ||||
| 				lda->mmgr, lda->node, | ||||
| 				QSE_SIZEOF(*lda->node)*capa); | ||||
| 			if (tmp == QSE_NULL) return QSE_NULL; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			tmp = (qse_lda_node_t**) QSE_MMGR_ALLOC ( | ||||
| 			tmp = (node_t**) QSE_MMGR_ALLOC ( | ||||
| 				lda->mmgr, QSE_SIZEOF(*lda->node)*capa); | ||||
| 			if (tmp == QSE_NULL) return QSE_NULL; | ||||
|  | ||||
| @ -261,7 +266,7 @@ lda_t* qse_lda_setcapa (lda_t* lda, size_t capa) | ||||
| 				size_t x; | ||||
| 				x = (capa > lda->capa)? lda->capa: capa; | ||||
| 				QSE_MEMCPY (tmp, lda->node,  | ||||
| 					QSE_SIZEOF(*lda->node) * x); | ||||
| 					QSE_SIZEOF(*lda->node)*x); | ||||
| 				QSE_MMGR_FREE (lda->mmgr, lda->node); | ||||
| 			} | ||||
| 		} | ||||
| @ -514,6 +519,8 @@ void qse_lda_walk (lda_t* lda, walker_t walker, void* arg) | ||||
| 	qse_lda_walk_t w = QSE_LDA_WALK_FORWARD; | ||||
| 	size_t i = 0; | ||||
|  | ||||
| 	if (lda->size <= 0) return; | ||||
|  | ||||
| 	while (1)	 | ||||
| 	{ | ||||
| 		if (lda->node[i] != QSE_NULL)  | ||||
| @ -562,3 +569,108 @@ void qse_lda_rwalk (lda_t* lda, walker_t walker, void* arg) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| size_t qse_lda_pushstack (lda_t* lda, void* dptr, size_t dlen) | ||||
| { | ||||
| 	return qse_lda_insert (lda, lda->size, dptr, dlen); | ||||
| } | ||||
|  | ||||
| void qse_lda_popstack (lda_t* lda) | ||||
| { | ||||
| 	QSE_ASSERT (lda->size > 0); | ||||
| 	qse_lda_delete (lda, lda->size - 1, 1); | ||||
| } | ||||
|  | ||||
| #define HEAP_PARENT(x) (((x)-1) / 2) | ||||
| #define HEAP_LEFT(x)   ((x)*2 + 1) | ||||
| #define HEAP_RIGHT(x)  ((x)*2 + 2) | ||||
|  | ||||
| size_t qse_lda_pushheap (lda_t* lda, void* dptr, size_t dlen) | ||||
| { | ||||
| 	size_t cur, par; | ||||
| 	int n; | ||||
|  | ||||
| 	/* add a value to the bottom */ | ||||
| 	cur = lda->size; | ||||
| 	if (qse_lda_insert (lda, cur, dptr, dlen) == QSE_LDA_NIL) | ||||
| 		return QSE_LDA_NIL; | ||||
|  | ||||
| 	while (cur != 0) | ||||
| 	{ | ||||
| 		node_t* tmp; | ||||
|  | ||||
| 		/* compare with the parent */ | ||||
| 		par = HEAP_PARENT(cur); | ||||
| 		n = lda->comper (lda, | ||||
| 			DPTR(lda->node[cur]), DLEN(lda->node[cur]), | ||||
| 			DPTR(lda->node[par]), DLEN(lda->node[par])); | ||||
| 		if (n <= 0) break; /* ok */ | ||||
|  | ||||
| 		/* swap the current with the parent */ | ||||
| 		tmp = lda->node[cur]; | ||||
| 		lda->node[cur] = lda->node[par]; | ||||
| 		lda->node[par] = tmp; | ||||
|  | ||||
| 		cur = par; | ||||
| 	} | ||||
|  | ||||
| 	return lda->size; | ||||
| } | ||||
|  | ||||
| void qse_lda_popheap (lda_t* lda) | ||||
| { | ||||
| 	size_t cur, child; | ||||
| 	node_t* tmp; | ||||
|  | ||||
| 	QSE_ASSERT (lda->size > 0); | ||||
|  | ||||
| 	/* destroy the top */ | ||||
| 	tmp = lda->node[0]; | ||||
| 	if (lda->freeer) lda->freeer (lda, DPTR(tmp), DLEN(tmp)); | ||||
| 	QSE_MMGR_FREE (lda->mmgr, tmp); | ||||
|  | ||||
| 	/* move the last item to the top position also shrink the size */ | ||||
| 	lda->node[0] = lda->node[--lda->size]; | ||||
|  | ||||
| 	if (lda->size <= 1) return; /* only 1 element. nothing further to do */ | ||||
|  | ||||
| 	for (cur = 0; cur < lda->size; cur = child) | ||||
| 	{ | ||||
| 		size_t left, right; | ||||
| 		int n; | ||||
|  | ||||
| 		left = HEAP_LEFT(cur); | ||||
| 		right = HEAP_RIGHT(cur); | ||||
|  | ||||
| 		if (left >= lda->size)  | ||||
| 		{ | ||||
| 			/* the left child does not exist.  | ||||
| 			 * reached the bottom. abort exchange */ | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		if (right >= lda->size)  | ||||
| 		{ | ||||
| 			/* the right child does not exist. only the left */ | ||||
| 			child = left;	 | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			/* get the larger child of the two */ | ||||
| 			n = lda->comper (lda, | ||||
| 				DPTR(lda->node[left]), DLEN(lda->node[left]), | ||||
| 				DPTR(lda->node[right]), DLEN(lda->node[right])); | ||||
| 			child = (n > 0)? left: right; | ||||
| 		} | ||||
| 		 | ||||
| 		/* compare the current one with the child */ | ||||
| 		n = lda->comper (lda, | ||||
| 			DPTR(lda->node[cur]), DLEN(lda->node[cur]), | ||||
| 			DPTR(lda->node[child]), DLEN(lda->node[child])); | ||||
| 		if (n > 0) break; /* current one is larger. stop exchange */ | ||||
|  | ||||
| 		/* swap the current with the child */ | ||||
| 		tmp = lda->node[cur]; | ||||
| 		lda->node[cur] = lda->node[child]; | ||||
| 		lda->node[child] = tmp; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -19,10 +19,9 @@ | ||||
|  */ | ||||
|  | ||||
| #include <qse/cmn/main.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <qse/cmn/str.h> | ||||
| #include <locale.h> | ||||
| #include "mem.h" | ||||
|  | ||||
| #if defined(_WIN32) && !defined(__MINGW32__) | ||||
|  | ||||
| @ -37,62 +36,62 @@ int qse_runmain (int argc, qse_achar_t* argv[], int(*mf) (int,qse_char_t*[])) | ||||
| { | ||||
| 	int i, ret; | ||||
| 	qse_char_t** v; | ||||
| 	qse_mmgr_t* mmgr = QSE_MMGR_GETDFL (); | ||||
|  | ||||
| 	setlocale (LC_ALL, ""); | ||||
|  | ||||
| 	v = (qse_char_t**) malloc (argc * QSE_SIZEOF(qse_char_t*)); | ||||
| 	if (v == NULL) return -1; | ||||
| 	v = (qse_char_t**) QSE_MMGR_ALLOC ( | ||||
| 		mmgr, argc * QSE_SIZEOF(qse_char_t*)); | ||||
| 	if (v == QSE_NULL) return -1; | ||||
|  | ||||
| 	for (i = 0; i < argc; i++) v[i] = QSE_NULL; | ||||
|  | ||||
| 	for (i = 0; i < argc; i++) v[i] = NULL; | ||||
| 	for (i = 0; i < argc; i++)  | ||||
| 	{ | ||||
| 		qse_size_t n, len, rem; | ||||
| 		char* p = argv[i]; | ||||
| 		qse_size_t n, len, nlen; | ||||
| 		qse_size_t mbslen; | ||||
|  | ||||
| 		len = 0; rem = strlen (p); | ||||
| 		while (*p != '\0') | ||||
| 		mbslen = qse_mbslen (argv[i]); | ||||
|  | ||||
| 		n = qse_mbstowcslen (argv[i], &len); | ||||
| 		if (n < mbslen) | ||||
| 		{ | ||||
| 			int x = mblen (p, rem);  | ||||
| 			if (x == -1)  | ||||
| 			{ | ||||
| 				ret = -1; | ||||
| 				goto exit_main; | ||||
| 			} | ||||
| 			if (x == 0) break; | ||||
| 			p += x; rem -= x; len++; | ||||
| 			ret = -1; goto oops; | ||||
| 		} | ||||
|  | ||||
| 	#if (defined(vms) || defined(__vms)) && (QSE_SIZEOF_VOID_P >= 8) | ||||
| 		v[i] = (qse_char_t*) _malloc32 ((len+1)*QSE_SIZEOF(qse_char_t)); | ||||
| 	#else | ||||
| 		v[i] = (qse_char_t*) malloc ((len+1)*QSE_SIZEOF(qse_char_t)); | ||||
| 	#endif | ||||
| 		if (v[i] == NULL)  | ||||
| 		len++; /* include the terminating null */ | ||||
|  | ||||
| 		v[i] = (qse_char_t*) QSE_MMGR_ALLOC ( | ||||
| 			mmgr, len*QSE_SIZEOF(qse_char_t)); | ||||
| 		if (v[i] == QSE_NULL)  | ||||
| 		{ | ||||
| 			ret = -1; | ||||
| 			goto exit_main; | ||||
| 			ret = -1; goto oops; | ||||
| 		} | ||||
|  | ||||
| 		n = mbstowcs (v[i], argv[i], len); | ||||
| 		if (n == (size_t)-1)  | ||||
| 		nlen = len; | ||||
| 		n = qse_mbstowcs (argv[i], v[i], &nlen); | ||||
| 		if (nlen >= len) | ||||
| 		{ | ||||
| 			/* error */ | ||||
| 			return -1; | ||||
| 			/* no null-termination */ | ||||
| 			ret = -1; goto oops; | ||||
| 		} | ||||
| 		if (argv[i][n] != '\0') | ||||
| 		{		 | ||||
| 			/* partial processing */ | ||||
| 			ret = -1; goto oops; | ||||
| 		} | ||||
|  | ||||
| 		if (n == len) v[i][len] = QSE_T('\0'); | ||||
| 	} | ||||
|  | ||||
| 	/* TODO: envp... */ | ||||
| 	//ret = mf (argc, v, NULL); | ||||
| 	//ret = mf (argc, v, QSE_NULL); | ||||
| 	ret = mf (argc, v); | ||||
|  | ||||
| exit_main: | ||||
| oops: | ||||
| 	for (i = 0; i < argc; i++)  | ||||
| 	{ | ||||
| 		if (v[i] != NULL) free (v[i]); | ||||
| 		if (v[i] != QSE_NULL) QSE_MMGR_FREE (mmgr, v[i]); | ||||
| 	} | ||||
| 	free (v); | ||||
| 	QSE_MMGR_FREE (mmgr, v); | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * $Id: str_bas.c 320 2009-12-21 12:29:52Z hyunghwan.chung $ | ||||
|  * $Id: str_bas.c 323 2010-04-05 12:50:01Z hyunghwan.chung $ | ||||
|  * | ||||
|     Copyright 2006-2009 Chung, Hyung-Hwan. | ||||
|     This file is part of QSE. | ||||
| @ -36,6 +36,20 @@ qse_size_t qse_strbytes (const qse_char_t* str) | ||||
| 	return (p - str) * QSE_SIZEOF(qse_char_t); | ||||
| } | ||||
|  | ||||
| qse_size_t qse_mbslen (const qse_mchar_t* mbs) | ||||
| { | ||||
| 	const qse_mchar_t* p = mbs; | ||||
| 	while (*p != QSE_T('\0')) p++; | ||||
| 	return p - mbs; | ||||
| } | ||||
|  | ||||
| qse_size_t qse_wcslen (const qse_wchar_t* wcs) | ||||
| { | ||||
| 	const qse_wchar_t* p = wcs; | ||||
| 	while (*p != QSE_T('\0')) p++; | ||||
| 	return p - wcs; | ||||
| } | ||||
|  | ||||
| qse_size_t qse_strcpy (qse_char_t* buf, const qse_char_t* str) | ||||
| { | ||||
| 	qse_char_t* org = buf; | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * $Id: str_cnv.c 287 2009-09-15 10:01:02Z hyunghwan.chung $ | ||||
|  * $Id: str_cnv.c 323 2010-04-05 12:50:01Z hyunghwan.chung $ | ||||
|  * | ||||
|     Copyright 2006-2009 Chung, Hyung-Hwan. | ||||
|     This file is part of QSE. | ||||
| @ -133,6 +133,45 @@ qse_ulong_t qse_strxtoulong (const qse_char_t* str, qse_size_t len) | ||||
| 	return v; | ||||
| } | ||||
|  | ||||
| qse_size_t qse_mbstowcslen (const qse_mchar_t* mcs, qse_size_t* wcslen) | ||||
| { | ||||
| 	qse_wchar_t wc; | ||||
| 	qse_size_t n, ml, wl = 0; | ||||
| 	const qse_mchar_t* p = mcs; | ||||
| 	 | ||||
| 	while (*p != '\0') p++; | ||||
| 	ml = p - mcs; | ||||
| 	 | ||||
| 	for (p = mcs; ml > 0; p += n, ml -= n)  | ||||
| 	{ | ||||
| 		n = qse_mbtowc (p, ml, &wc); | ||||
| 		/* insufficient input or wrong sequence */ | ||||
| 		if (n == 0 || n > ml) break; | ||||
| 		wl++; | ||||
| 	} | ||||
|  | ||||
| 	if (wcslen) *wcslen = wl; | ||||
| 	return p - mcs; | ||||
| } | ||||
|  | ||||
| qse_size_t qse_mbsntowcsnlen (const qse_mchar_t* mcs, qse_size_t mcslen, qse_size_t* wcslen) | ||||
| { | ||||
| 	qse_wchar_t wc; | ||||
| 	qse_size_t n, ml = mcslen, wl = 0; | ||||
| 	const qse_mchar_t* p = mcs; | ||||
| 	 | ||||
| 	for (p = mcs; ml > 0; p += n, ml -= n)  | ||||
| 	{ | ||||
| 		n = qse_mbtowc (p, ml, &wc); | ||||
| 		/* insufficient or invalid sequence */ | ||||
| 		if (n == 0 || n > ml) break; | ||||
| 		wl++; | ||||
| 	} | ||||
|  | ||||
| 	if (wcslen) *wcslen = wl; | ||||
| 	return mcslen - ml; | ||||
| } | ||||
|  | ||||
| qse_size_t qse_mbstowcs ( | ||||
| 	const qse_mchar_t* mbs, qse_wchar_t* wcs, qse_size_t* wcslen) | ||||
| { | ||||
| @ -141,24 +180,26 @@ qse_size_t qse_mbstowcs ( | ||||
|  | ||||
| 	/* get the length of mbs and pass it to qse_mbsntowcsn as  | ||||
| 	 * qse_mbtowc called by qse_mbsntowcsn needs it. */ | ||||
| 	wlen = *wcslen; | ||||
| 	if (wlen <= 0) | ||||
| 	{ | ||||
| 		/* buffer too small. also cannot null-terminate it */ | ||||
| 		*wcslen = 0; | ||||
| 		return 0; /* 0 byte processed */ | ||||
| 	} | ||||
|  | ||||
| 	for (mp = mbs; *mp != '\0'; mp++); | ||||
|  | ||||
| 	if (*wcslen <= 0)  | ||||
| 	{ | ||||
| 		/* buffer too small. cannot null-terminate it */ | ||||
| 		return 0; | ||||
| 	} | ||||
| 	if (*wcslen == 1)  | ||||
| 	{ | ||||
| 		wcs[0] = L'\0'; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	wlen = *wcslen - 1; | ||||
| 	mlen = qse_mbsntowcsn (mbs, mp - mbs, wcs, &wlen); | ||||
| 	if (wlen < *wcslen)  | ||||
| 	{ | ||||
| 		/* null-terminate wcs if it is large enough. */ | ||||
| 		wcs[wlen] = L'\0'; | ||||
| 	} | ||||
|  | ||||
| 	wcs[wlen] = L'\0'; | ||||
| 	*wcslen = wlen; | ||||
| 	/* if null-terminated properly, the input wcslen must be less than | ||||
| 	 * the output wcslen. (input length includs the terminating null | ||||
| 	 * while the output length excludes the terminating null) */ | ||||
| 	*wcslen = wlen;  | ||||
|  | ||||
| 	return mlen; | ||||
| } | ||||
| @ -305,6 +346,29 @@ qse_size_t qse_wcsntombsn ( | ||||
| 	return p - wcs;  | ||||
| } | ||||
|  | ||||
| int qse_mbstowcs_strict ( | ||||
| 	const qse_mchar_t* mbs, qse_wchar_t* wcs, qse_size_t wcslen) | ||||
| { | ||||
| 	qse_size_t n; | ||||
| 	qse_size_t wn = wcslen; | ||||
|  | ||||
| 	n = qse_mbstowcs (mbs, wcs, &wn); | ||||
| 	if (wn >= wcslen) | ||||
| 	{ | ||||
| 		/* wcs not big enough to be null-terminated. | ||||
| 		 * if it has been null-terminated properly,  | ||||
| 		 * wn should be less than wcslen. */ | ||||
|                 return -1; | ||||
|         } | ||||
| 	if (mbs[n] != QSE_MT('\0')) | ||||
| 	{ | ||||
| 		/* incomplete sequence or invalid sequence */ | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
|         return 0; | ||||
| } | ||||
|  | ||||
| int qse_wcstombs_strict ( | ||||
| 	const qse_wchar_t* wcs, qse_mchar_t* mbs, qse_size_t mbslen) | ||||
| { | ||||
| @ -312,13 +376,6 @@ int qse_wcstombs_strict ( | ||||
| 	qse_size_t mn = mbslen; | ||||
|  | ||||
| 	n = qse_wcstombs (wcs, mbs, &mn); | ||||
| 	if (wcs[n] != QSE_WT('\0'))  | ||||
| 	{ | ||||
| 		/* if qse_wcstombs() processed all wide characters, | ||||
| 		 * the character at position 'n' should be a null character | ||||
| 		 * as 'n' is the number of wide characters processed. */ | ||||
| 		return -1; | ||||
| 	} | ||||
| 	if (mn >= mbslen)  | ||||
| 	{ | ||||
| 		/* mbs not big enough to be null-terminated. | ||||
| @ -326,6 +383,14 @@ int qse_wcstombs_strict ( | ||||
| 		 * mn should be less than mbslen. */ | ||||
| 		return -1;  | ||||
| 	} | ||||
| 	if (wcs[n] != QSE_WT('\0'))  | ||||
| 	{ | ||||
| 		/* if qse_wcstombs() processed all wide characters, | ||||
| 		 * the character at position 'n' should be a null character | ||||
| 		 * as 'n' is the number of wide characters processed. */ | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user