* fixed a bug of not setting an error code upon a few cases of QSE_AWK_STRXDUP failures
* added a new memory debugging facility to qseawk
This commit is contained in:
		| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * $Id: awk.c 516 2011-07-23 09:03:48Z hyunghwan.chung $ | ||||
|  * $Id: awk.c 547 2011-08-13 16:04:14Z hyunghwan.chung $ | ||||
|  * | ||||
|     Copyright 2006-2011 Chung, Hyung-Hwan. | ||||
|     This file is part of QSE. | ||||
| @ -78,6 +78,9 @@ struct arg_t | ||||
| 	int          opton; | ||||
| 	int          optoff; | ||||
| 	qse_ulong_t  memlimit; | ||||
| #if defined(QSE_BUILD_DEBUG) | ||||
| 	qse_ulong_t  failmalloc; | ||||
| #endif | ||||
| }; | ||||
|  | ||||
| struct gvmv_t | ||||
| @ -425,6 +428,9 @@ static void print_usage (QSE_FILE* out, const qse_char_t* argv0) | ||||
| 	qse_fprintf (out, QSE_T(" -F/--field-separator string       set a field separator(FS)\n")); | ||||
| 	qse_fprintf (out, QSE_T(" -v/--assign          var=value    add a global variable with a value\n")); | ||||
| 	qse_fprintf (out, QSE_T(" -m/--memory-limit    number       limit the memory usage (bytes)\n")); | ||||
| #if defined(QSE_BUILD_DEBUG) | ||||
| 	qse_fprintf (out, QSE_T(" -X                   number       fail the number'th memory allocation\n")); | ||||
| #endif | ||||
|  | ||||
| 	for (j = 0; opttab[j].name != QSE_NULL; j++) | ||||
| 	{ | ||||
| @ -467,7 +473,11 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg) | ||||
|  | ||||
| 	static qse_opt_t opt =  | ||||
| 	{ | ||||
| #if defined(QSE_BUILD_DEBUG) | ||||
| 		QSE_T("dc:f:F:o:v:m:X:h"), | ||||
| #else | ||||
| 		QSE_T("dc:f:F:o:v:m:h"), | ||||
| #endif | ||||
| 		lng | ||||
| 	}; | ||||
|  | ||||
| @ -598,6 +608,14 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg) | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| #if defined(QSE_BUILD_DEBUG) | ||||
| 			case QSE_T('X'): | ||||
| 			{ | ||||
| 				arg->failmalloc = qse_strtoulong (opt.arg); | ||||
| 				break; | ||||
| 			} | ||||
| #endif | ||||
|  | ||||
| 			case QSE_T('\0'): | ||||
| 			{ | ||||
| 				/* a long option with no corresponding short option */ | ||||
| @ -774,6 +792,39 @@ static qse_mmgr_t xma_mmgr = | ||||
| 	QSE_NULL | ||||
| }; | ||||
|  | ||||
| #if defined(QSE_BUILD_DEBUG) | ||||
| static qse_ulong_t debug_mmgr_count = 0; | ||||
|  | ||||
| static void* debug_mmgr_alloc (void* ctx, qse_size_t size) | ||||
| { | ||||
| 	struct arg_t* arg = (struct arg_t*)ctx; | ||||
| 	debug_mmgr_count++; | ||||
| 	if (debug_mmgr_count % arg->failmalloc == 0) return QSE_NULL; | ||||
| 	return malloc (size); | ||||
| } | ||||
|  | ||||
| static void* debug_mmgr_realloc (void* ctx, void* ptr, qse_size_t size) | ||||
| { | ||||
| 	struct arg_t* arg = (struct arg_t*)ctx; | ||||
| 	debug_mmgr_count++; | ||||
| 	if (debug_mmgr_count % arg->failmalloc == 0) return QSE_NULL; | ||||
| 	return realloc (ptr, size); | ||||
| } | ||||
|  | ||||
| static void debug_mmgr_free (void* ctx, void* ptr) | ||||
| { | ||||
| 	free (ptr); | ||||
| } | ||||
|  | ||||
| static qse_mmgr_t debug_mmgr = | ||||
| { | ||||
| 	debug_mmgr_alloc, | ||||
| 	debug_mmgr_realloc, | ||||
| 	debug_mmgr_free, | ||||
| 	QSE_NULL | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| static int awk_main (int argc, qse_char_t* argv[]) | ||||
| { | ||||
| 	qse_awk_t* awk = QSE_NULL; | ||||
| @ -810,6 +861,14 @@ static int awk_main (int argc, qse_char_t* argv[]) | ||||
| 		psout.u.file = arg.osf; | ||||
| 	} | ||||
|  | ||||
| #if defined(QSE_BUILD_DEBUG) | ||||
| 	if (arg.failmalloc > 0) | ||||
| 	{ | ||||
| 		debug_mmgr.udd = &arg; | ||||
| 		mmgr = &debug_mmgr;	 | ||||
| 	} | ||||
| 	else  | ||||
| #endif | ||||
| 	if (arg.memlimit > 0) | ||||
| 	{ | ||||
| 		xma_mmgr.udd = qse_xma_open (QSE_NULL, 0, arg.memlimit); | ||||
|  | ||||
| @ -38,7 +38,8 @@ PROJECT_NUMBER         = @VERSION@ | ||||
| # If a relative path is entered, it will be relative to the location  | ||||
| # where doxygen was started. If left blank the current directory will be used. | ||||
|  | ||||
| OUTPUT_DIRECTORY       = ./qse-@VERSION@ | ||||
| #OUTPUT_DIRECTORY       = ./qse-@VERSION@ | ||||
| OUTPUT_DIRECTORY        = @abs_top_srcdir@/doc/qse-@VERSION@ | ||||
|  | ||||
| # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create  | ||||
| # 4096 sub-directories (in 2 levels) under the output directory of each output  | ||||
| @ -564,7 +565,7 @@ WARN_LOGFILE           = | ||||
| # directories like "/usr/src/myproject". Separate the files or directories  | ||||
| # with spaces. | ||||
|  | ||||
| INPUT                  = @abs_top_srcdir@/include ./page | ||||
| INPUT                  = @abs_top_srcdir@/include @abs_top_srcdir@/doc/page | ||||
|  | ||||
| # This tag can be used to specify the character encoding of the source files  | ||||
| # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is  | ||||
| @ -621,7 +622,7 @@ EXCLUDE_SYMBOLS        = | ||||
| # directories that contain example code fragments that are included (see  | ||||
| # the \include command). | ||||
|  | ||||
| EXAMPLE_PATH           = ../samples ../cmd | ||||
| EXAMPLE_PATH           = @abs_top_srcdir@/samples @abs_top_srcdir@/cmd | ||||
|  | ||||
| # If the value of the EXAMPLE_PATH tag contains directories, you can use the  | ||||
| # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp  | ||||
| @ -823,14 +824,14 @@ GENERATE_DOCSET        = NO | ||||
| # documentation sets from a single provider (such as a company or product suite)  | ||||
| # can be grouped. | ||||
|  | ||||
| DOCSET_FEEDNAME        = "Doxygen generated docs" | ||||
| DOCSET_FEEDNAME        = "QSE Documentation" | ||||
|  | ||||
| # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that  | ||||
| # should uniquely identify the documentation set bundle. This should be a  | ||||
| # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen  | ||||
| # will append .docset to the name. | ||||
|  | ||||
| DOCSET_BUNDLE_ID       = org.hyunghwan.qse | ||||
| DOCSET_BUNDLE_ID       = net.abiyo.qse | ||||
|  | ||||
| # If the GENERATE_HTMLHELP tag is set to YES, additional index files  | ||||
| # will be generated that can be used as input for tools like the  | ||||
|  | ||||
| @ -3,5 +3,7 @@ AUTOMAKE_OPTIONS = no-dependencies | ||||
|  | ||||
| EXTRA_DIST = \ | ||||
| 	main.doc \ | ||||
| 	mem.doc \ | ||||
| 	io.doc \ | ||||
| 	awk.doc \ | ||||
| 	sed.doc | ||||
|  | ||||
| @ -195,6 +195,8 @@ top_srcdir = @top_srcdir@ | ||||
| AUTOMAKE_OPTIONS = no-dependencies | ||||
| EXTRA_DIST = \ | ||||
| 	main.doc \ | ||||
| 	mem.doc \ | ||||
| 	io.doc \ | ||||
| 	awk.doc \ | ||||
| 	sed.doc | ||||
|  | ||||
|  | ||||
| @ -1,10 +0,0 @@ | ||||
| /** @page cmn COMMON FUNCTIONS | ||||
|  | ||||
| @section xma MEMORY ALLOCATOR | ||||
| - QSE provides a memory allocator #qse_xma_t for private heap management. | ||||
| - QSE provides a fixed-size block memory allocator #qse_fma_t. | ||||
|  | ||||
| @section rex REGULAR EXPRESSION | ||||
| QSE provides a regular expression processor #qse_rex_t. | ||||
|  | ||||
| */ | ||||
							
								
								
									
										8
									
								
								qse/doc/page/io.doc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								qse/doc/page/io.doc
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| /** @page io I/O Handling | ||||
|  | ||||
| @section io_stream Stream | ||||
| - Generic text stream interface #qse_tio_t | ||||
| - Simple text stream over a file #qse_sio_t  | ||||
| - Pipe stream to/from a process #qse_pio_t | ||||
|  | ||||
| */ | ||||
| @ -95,9 +95,8 @@ foundation for other modules. Specialized functions and data structures are | ||||
| organized to dedicated modules.  See relevant subpages for more information  | ||||
| on each module. | ||||
|  | ||||
| - @subpage cmn "Common Functions"  | ||||
|   -# xma.h variable-size block memory allocator | ||||
|   -# fma.h fixed-size block memory allocator  | ||||
| - @subpage mem "Memory Management" | ||||
| - @subpage io  "I/O Handling" | ||||
| - @subpage awk "AWK Interpreter"  | ||||
| - @subpage cut "CUT Text Cutter"  | ||||
| - @subpage sed "SED Stream Editor"  | ||||
|  | ||||
							
								
								
									
										6
									
								
								qse/doc/page/mem.doc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								qse/doc/page/mem.doc
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| /** @page mem Memory Management | ||||
|  | ||||
| @section mem_alloc Memory Allocator | ||||
| - Private heap allocator #qse_xma_t  | ||||
| - Fixed-size block allocator #qse_fma_t | ||||
| */ | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * $Id: sio.h 441 2011-04-22 14:28:43Z hyunghwan.chung $ | ||||
|  * $Id: sio.h 547 2011-08-13 16:04:14Z hyunghwan.chung $ | ||||
|  * | ||||
|     Copyright 2006-2011 Chung, Hyung-Hwan. | ||||
|     This file is part of QSE. | ||||
| @ -50,6 +50,10 @@ enum qse_sio_open_flag_t | ||||
| typedef qse_fio_off_t qse_sio_pos_t; | ||||
| typedef qse_fio_hnd_t qse_sio_hnd_t; | ||||
|  | ||||
| /** | ||||
|  * The qse_sio_t type defines a simple text stream over a file. It also | ||||
|  * provides predefined streams for standard input, output, and error. | ||||
|  */ | ||||
| typedef struct qse_sio_t qse_sio_t; | ||||
|  | ||||
| struct qse_sio_t | ||||
| @ -145,7 +149,7 @@ qse_ssize_t qse_sio_putsn ( | ||||
| ); | ||||
|  | ||||
| /** | ||||
|  * The get_sio_getpos() gets the current position in a stream. | ||||
|  * The qse_sio_getpos() gets the current position in a stream. | ||||
|  * Note that it may not return the desired postion due to buffering. | ||||
|  * @return 0 on success, -1 on failure | ||||
|  */ | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * $Id: tio.h 441 2011-04-22 14:28:43Z hyunghwan.chung $ | ||||
|  * $Id: tio.h 547 2011-08-13 16:04:14Z hyunghwan.chung $ | ||||
|  * | ||||
|     Copyright 2006-2011 Chung, Hyung-Hwan. | ||||
|     This file is part of QSE. | ||||
| @ -51,12 +51,12 @@ typedef enum qse_tio_errnum_t qse_tio_errnum_t; | ||||
|  | ||||
| enum | ||||
| { | ||||
|         /* the size of input buffer should be at least equal to or greater | ||||
|          * than the maximum sequence length of the qse_mchar_t string. | ||||
|          * (i.e. 6 for utf8) | ||||
|          */ | ||||
|         QSE_TIO_MAX_INBUF_LEN = 4096, | ||||
|         QSE_TIO_MAX_OUTBUF_LEN = 4096 | ||||
| 	/* the size of input buffer should be at least equal to or greater | ||||
| 	 * than the maximum sequence length of the qse_mchar_t string. | ||||
| 	 * (i.e. 6 for utf8) | ||||
| 	 */ | ||||
| 	QSE_TIO_MAX_INBUF_LEN = 4096, | ||||
| 	QSE_TIO_MAX_OUTBUF_LEN = 4096 | ||||
| }; | ||||
|  | ||||
| enum  | ||||
| @ -98,12 +98,12 @@ struct qse_tio_t | ||||
|  | ||||
| 	/* for housekeeping */ | ||||
| 	int         input_status; | ||||
|         qse_size_t  inbuf_curp; | ||||
|         qse_size_t  inbuf_len; | ||||
|         qse_size_t  outbuf_len; | ||||
| 	qse_size_t  inbuf_curp; | ||||
| 	qse_size_t  inbuf_len; | ||||
| 	qse_size_t  outbuf_len; | ||||
|  | ||||
|         qse_mchar_t inbuf[QSE_TIO_MAX_INBUF_LEN]; | ||||
|         qse_mchar_t outbuf[QSE_TIO_MAX_OUTBUF_LEN]; | ||||
| 	qse_mchar_t inbuf[QSE_TIO_MAX_INBUF_LEN]; | ||||
| 	qse_mchar_t outbuf[QSE_TIO_MAX_OUTBUF_LEN]; | ||||
| }; | ||||
|  | ||||
| #ifdef __cplusplus | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * $Id: parse.c 541 2011-08-12 14:16:05Z hyunghwan.chung $ | ||||
|  * $Id: parse.c 547 2011-08-13 16:04:14Z hyunghwan.chung $ | ||||
|  * | ||||
|     Copyright 2006-2011 Chung, Hyung-Hwan. | ||||
|     This file is part of QSE. | ||||
| @ -4255,6 +4255,7 @@ static qse_awk_nde_t* parse_primary_nogetline ( | ||||
| 		if (nde->str == QSE_NULL) | ||||
| 		{ | ||||
| 			QSE_AWK_FREE (awk, nde); | ||||
| 			SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc); | ||||
| 			return QSE_NULL;			 | ||||
| 		} | ||||
| 		nde->len = QSE_STR_LEN(awk->tok.name); | ||||
| @ -4295,6 +4296,7 @@ static qse_awk_nde_t* parse_primary_nogetline ( | ||||
| 		if (nde->str == QSE_NULL) | ||||
| 		{ | ||||
| 			QSE_AWK_FREE (awk, nde); | ||||
| 			SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc); | ||||
| 			return QSE_NULL;			 | ||||
| 		} | ||||
| 		nde->len = QSE_STR_LEN(awk->tok.name); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user