* 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:
hyung-hwan 2011-08-14 10:04:14 +00:00
parent e833fdff6f
commit 4527bf0a34
11 changed files with 107 additions and 34 deletions

View File

@ -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);

View File

@ -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

View File

@ -3,5 +3,7 @@ AUTOMAKE_OPTIONS = no-dependencies
EXTRA_DIST = \
main.doc \
mem.doc \
io.doc \
awk.doc \
sed.doc

View File

@ -195,6 +195,8 @@ top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = no-dependencies
EXTRA_DIST = \
main.doc \
mem.doc \
io.doc \
awk.doc \
sed.doc

View File

@ -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
View 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
*/

View File

@ -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
View 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
*/

View File

@ -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
*/

View File

@ -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.

View File

@ -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);