* 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:
parent
e833fdff6f
commit
4527bf0a34
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user