From 4527bf0a348dc1361b29a55f8ff9f4cac1ee0214 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sun, 14 Aug 2011 10:04:14 +0000 Subject: [PATCH] * 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 --- qse/cmd/awk/awk.c | 61 ++++++++++++++++++++++++++++++++++++++- qse/doc/Doxyfile.in | 11 +++---- qse/doc/page/Makefile.am | 2 ++ qse/doc/page/Makefile.in | 2 ++ qse/doc/page/cmn.doc | 10 ------- qse/doc/page/io.doc | 8 +++++ qse/doc/page/main.doc | 5 ++-- qse/doc/page/mem.doc | 6 ++++ qse/include/qse/cmn/sio.h | 8 +++-- qse/include/qse/cmn/tio.h | 24 +++++++-------- qse/lib/awk/parse.c | 4 ++- 11 files changed, 107 insertions(+), 34 deletions(-) delete mode 100644 qse/doc/page/cmn.doc create mode 100644 qse/doc/page/io.doc create mode 100644 qse/doc/page/mem.doc diff --git a/qse/cmd/awk/awk.c b/qse/cmd/awk/awk.c index d7baa3bd..495b67f4 100644 --- a/qse/cmd/awk/awk.c +++ b/qse/cmd/awk/awk.c @@ -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); diff --git a/qse/doc/Doxyfile.in b/qse/doc/Doxyfile.in index 0991bd50..5af4cbf6 100644 --- a/qse/doc/Doxyfile.in +++ b/qse/doc/Doxyfile.in @@ -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 diff --git a/qse/doc/page/Makefile.am b/qse/doc/page/Makefile.am index c996df3b..30182c87 100644 --- a/qse/doc/page/Makefile.am +++ b/qse/doc/page/Makefile.am @@ -3,5 +3,7 @@ AUTOMAKE_OPTIONS = no-dependencies EXTRA_DIST = \ main.doc \ + mem.doc \ + io.doc \ awk.doc \ sed.doc diff --git a/qse/doc/page/Makefile.in b/qse/doc/page/Makefile.in index ebb47b61..9498780b 100644 --- a/qse/doc/page/Makefile.in +++ b/qse/doc/page/Makefile.in @@ -195,6 +195,8 @@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = no-dependencies EXTRA_DIST = \ main.doc \ + mem.doc \ + io.doc \ awk.doc \ sed.doc diff --git a/qse/doc/page/cmn.doc b/qse/doc/page/cmn.doc deleted file mode 100644 index 4117d314..00000000 --- a/qse/doc/page/cmn.doc +++ /dev/null @@ -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. - -*/ diff --git a/qse/doc/page/io.doc b/qse/doc/page/io.doc new file mode 100644 index 00000000..92664569 --- /dev/null +++ b/qse/doc/page/io.doc @@ -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 + +*/ diff --git a/qse/doc/page/main.doc b/qse/doc/page/main.doc index cb9e504b..95d6829b 100644 --- a/qse/doc/page/main.doc +++ b/qse/doc/page/main.doc @@ -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" diff --git a/qse/doc/page/mem.doc b/qse/doc/page/mem.doc new file mode 100644 index 00000000..15a75836 --- /dev/null +++ b/qse/doc/page/mem.doc @@ -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 +*/ diff --git a/qse/include/qse/cmn/sio.h b/qse/include/qse/cmn/sio.h index d34ac302..617043d5 100644 --- a/qse/include/qse/cmn/sio.h +++ b/qse/include/qse/cmn/sio.h @@ -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 */ diff --git a/qse/include/qse/cmn/tio.h b/qse/include/qse/cmn/tio.h index 6de5d914..cdfb3d56 100644 --- a/qse/include/qse/cmn/tio.h +++ b/qse/include/qse/cmn/tio.h @@ -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 diff --git a/qse/lib/awk/parse.c b/qse/lib/awk/parse.c index 823df68c..2d38f687 100644 --- a/qse/lib/awk/parse.c +++ b/qse/lib/awk/parse.c @@ -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);