* 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.
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
This file is part of QSE.
|
||||||
@ -78,6 +78,9 @@ struct arg_t
|
|||||||
int opton;
|
int opton;
|
||||||
int optoff;
|
int optoff;
|
||||||
qse_ulong_t memlimit;
|
qse_ulong_t memlimit;
|
||||||
|
#if defined(QSE_BUILD_DEBUG)
|
||||||
|
qse_ulong_t failmalloc;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gvmv_t
|
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(" -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(" -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"));
|
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++)
|
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 =
|
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"),
|
QSE_T("dc:f:F:o:v:m:h"),
|
||||||
|
#endif
|
||||||
lng
|
lng
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -598,6 +608,14 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(QSE_BUILD_DEBUG)
|
||||||
|
case QSE_T('X'):
|
||||||
|
{
|
||||||
|
arg->failmalloc = qse_strtoulong (opt.arg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
case QSE_T('\0'):
|
case QSE_T('\0'):
|
||||||
{
|
{
|
||||||
/* a long option with no corresponding short option */
|
/* a long option with no corresponding short option */
|
||||||
@ -774,6 +792,39 @@ static qse_mmgr_t xma_mmgr =
|
|||||||
QSE_NULL
|
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[])
|
static int awk_main (int argc, qse_char_t* argv[])
|
||||||
{
|
{
|
||||||
qse_awk_t* awk = QSE_NULL;
|
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;
|
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)
|
if (arg.memlimit > 0)
|
||||||
{
|
{
|
||||||
xma_mmgr.udd = qse_xma_open (QSE_NULL, 0, arg.memlimit);
|
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
|
# 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.
|
# 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
|
# 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
|
# 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
|
# directories like "/usr/src/myproject". Separate the files or directories
|
||||||
# with spaces.
|
# 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
|
# 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
|
# 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
|
# directories that contain example code fragments that are included (see
|
||||||
# the \include command).
|
# 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
|
# 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
|
# 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)
|
# documentation sets from a single provider (such as a company or product suite)
|
||||||
# can be grouped.
|
# 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
|
# 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
|
# should uniquely identify the documentation set bundle. This should be a
|
||||||
# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
|
# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
|
||||||
# will append .docset to the name.
|
# 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
|
# 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
|
# will be generated that can be used as input for tools like the
|
||||||
|
@ -3,5 +3,7 @@ AUTOMAKE_OPTIONS = no-dependencies
|
|||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
main.doc \
|
main.doc \
|
||||||
|
mem.doc \
|
||||||
|
io.doc \
|
||||||
awk.doc \
|
awk.doc \
|
||||||
sed.doc
|
sed.doc
|
||||||
|
@ -195,6 +195,8 @@ top_srcdir = @top_srcdir@
|
|||||||
AUTOMAKE_OPTIONS = no-dependencies
|
AUTOMAKE_OPTIONS = no-dependencies
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
main.doc \
|
main.doc \
|
||||||
|
mem.doc \
|
||||||
|
io.doc \
|
||||||
awk.doc \
|
awk.doc \
|
||||||
sed.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
|
organized to dedicated modules. See relevant subpages for more information
|
||||||
on each module.
|
on each module.
|
||||||
|
|
||||||
- @subpage cmn "Common Functions"
|
- @subpage mem "Memory Management"
|
||||||
-# xma.h variable-size block memory allocator
|
- @subpage io "I/O Handling"
|
||||||
-# fma.h fixed-size block memory allocator
|
|
||||||
- @subpage awk "AWK Interpreter"
|
- @subpage awk "AWK Interpreter"
|
||||||
- @subpage cut "CUT Text Cutter"
|
- @subpage cut "CUT Text Cutter"
|
||||||
- @subpage sed "SED Stream Editor"
|
- @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.
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
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_off_t qse_sio_pos_t;
|
||||||
typedef qse_fio_hnd_t qse_sio_hnd_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;
|
typedef struct qse_sio_t qse_sio_t;
|
||||||
|
|
||||||
struct 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.
|
* Note that it may not return the desired postion due to buffering.
|
||||||
* @return 0 on success, -1 on failure
|
* @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.
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
This file is part of QSE.
|
||||||
|
@ -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.
|
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||||
This file is part of QSE.
|
This file is part of QSE.
|
||||||
@ -4255,6 +4255,7 @@ static qse_awk_nde_t* parse_primary_nogetline (
|
|||||||
if (nde->str == QSE_NULL)
|
if (nde->str == QSE_NULL)
|
||||||
{
|
{
|
||||||
QSE_AWK_FREE (awk, nde);
|
QSE_AWK_FREE (awk, nde);
|
||||||
|
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
nde->len = QSE_STR_LEN(awk->tok.name);
|
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)
|
if (nde->str == QSE_NULL)
|
||||||
{
|
{
|
||||||
QSE_AWK_FREE (awk, nde);
|
QSE_AWK_FREE (awk, nde);
|
||||||
|
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
nde->len = QSE_STR_LEN(awk->tok.name);
|
nde->len = QSE_STR_LEN(awk->tok.name);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user