integrated Ville Laurikari's TRE

This commit is contained in:
hyung-hwan 2011-09-01 09:43:46 +00:00
parent 621eefef0c
commit 6aba3f8f89
108 changed files with 7867 additions and 437 deletions

View File

@ -26,6 +26,7 @@ pkginclude_HEADERS = \
str.h \
time.h \
tio.h \
tre.h \
xma.h
if ENABLE_CXX

View File

@ -53,8 +53,8 @@ SOURCES =
DIST_SOURCES =
am__pkginclude_HEADERS_DIST = alg.h chr.h dll.h env.h fio.h fma.h \
gdl.h htb.h lda.h main.h map.h mem.h misc.h oht.h opt.h pio.h \
pma.h rbt.h rex.h sio.h sll.h stdio.h str.h time.h tio.h xma.h \
Mmgr.hpp StdMmgr.hpp Mmged.hpp
pma.h rbt.h rex.h sio.h sll.h stdio.h str.h time.h tio.h tre.h \
xma.h Mmgr.hpp StdMmgr.hpp Mmged.hpp
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@ -225,7 +225,7 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
pkginclude_HEADERS = alg.h chr.h dll.h env.h fio.h fma.h gdl.h htb.h \
lda.h main.h map.h mem.h misc.h oht.h opt.h pio.h pma.h rbt.h \
rex.h sio.h sll.h stdio.h str.h time.h tio.h xma.h \
rex.h sio.h sll.h stdio.h str.h time.h tio.h tre.h xma.h \
$(am__append_1)
all: all-am

View File

@ -1,5 +1,5 @@
/*
* $Id: dll.h 474 2011-05-23 16:52:37Z hyunghwan.chung $
* $Id: dll.h 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -257,7 +257,7 @@ void qse_dll_close (
/**
* The qse_dll_init() function initializes a statically declared list.
*/
qse_dll_t* qse_dll_init (
int qse_dll_init (
qse_dll_t* dll, /**< doubly linked list */
qse_mmgr_t* mmgr /**< memory manager */
);

View File

@ -84,7 +84,7 @@ void qse_env_close (
qse_env_t* env
);
qse_env_t* qse_env_init (
int qse_env_init (
qse_env_t* env,
qse_mmgr_t* mmgr,
int fromcurenv

View File

@ -1,5 +1,5 @@
/*
* $Id: fio.h 550 2011-08-14 15:59:55Z hyunghwan.chung $
* $Id: fio.h 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -152,7 +152,7 @@ void qse_fio_close (
/***
* The qse_fio_close() function opens a file into @a fio.
*/
qse_fio_t* qse_fio_init (
int qse_fio_init (
qse_fio_t* fio,
qse_mmgr_t* mmgr,
const qse_char_t* path,

View File

@ -232,7 +232,7 @@ void qse_fma_close (
* The qse_fma_init() function initializes an memory allocator statically
* declared.
*/
qse_fma_t* qse_fma_init (
int qse_fma_init (
qse_fma_t* fma, /**< memory allocator */
qse_mmgr_t* mmgr, /**< outer memory manager */
qse_size_t blksize, /**< fixed block size in bytes */

View File

@ -1,5 +1,5 @@
/*
* $Id: htb.h 477 2011-05-24 04:22:40Z hyunghwan.chung $
* $Id: htb.h 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -341,7 +341,7 @@ void qse_htb_close (
/**
* The qse_htb_init() function initializes a hash table
*/
qse_htb_t* qse_htb_init (
int qse_htb_init (
qse_htb_t* htb, /**< hash table */
qse_mmgr_t* mmgr, /**< memory manager */
qse_size_t capa, /**< initial capacity */

View File

@ -1,5 +1,5 @@
/*
* $Id: lda.h 479 2011-05-24 15:14:58Z hyunghwan.chung $
* $Id: lda.h 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -176,7 +176,7 @@ void qse_lda_close (
/**
* The qse_lda_init() function initializes a linear dynamic array.
*/
qse_lda_t* qse_lda_init (
int qse_lda_init (
qse_lda_t* lda,
qse_mmgr_t* mmgr,
qse_size_t capa

View File

@ -165,10 +165,9 @@ void qse_oht_close (
);
/**
* The qse_oht_open() function initializes a statically declared
* open-addressed hash table.
* The qse_oht_open() function initializes an open-addressed hash table.
*/
qse_oht_t* qse_oht_init (
int qse_oht_init (
qse_oht_t* oht,
qse_mmgr_t* mmgr,
int scale,

View File

@ -1,5 +1,5 @@
/*
* $Id: pio.h 539 2011-08-10 16:18:35Z hyunghwan.chung $
* $Id: pio.h 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -117,6 +117,7 @@ enum qse_pio_errnum_t
{
QSE_PIO_ENOERR = 0, /**< no error */
QSE_PIO_ENOMEM, /**< out of memory */
QSE_PIO_EINVAL, /**< out of memory */
QSE_PIO_ENOHND, /**< no handle available */
QSE_PIO_ECHILD, /**< the child is not valid */
QSE_PIO_EINTR, /**< interrupted */
@ -223,9 +224,9 @@ void qse_pio_close (
* The qse_pio_init() functions performs the same task as the qse_pio_open()
* except that you need to allocate a #qse_pio_t structure and pass it to the
* function.
* @return @a pio on success, #QSE_NULL on failure
* @return 0 on success, -1 on failure
*/
qse_pio_t* qse_pio_init (
int qse_pio_init (
qse_pio_t* pio, /**< pio object */
qse_mmgr_t* mmgr, /**< memory manager */
const qse_char_t* cmd, /**< command to execute */

View File

@ -71,7 +71,7 @@ void qse_pma_close (
qse_pma_t* pma /**< memory allocator */
);
qse_pma_t* qse_pma_init (
int qse_pma_init (
qse_pma_t* pma, /**< memory allocator */
qse_mmgr_t* mmgr /**< memory manager */
);

View File

@ -301,7 +301,7 @@ void qse_rbt_close (
/**
* The qse_rbt_init() function initializes a red-black tree
*/
qse_rbt_t* qse_rbt_init (
int qse_rbt_init (
qse_rbt_t* rbt, /**< red-black tree */
qse_mmgr_t* mmgr, /**< memory manager */
int kscale, /**< key scale */

View File

@ -1,5 +1,5 @@
/*
* $Id: rex.h 462 2011-05-18 14:36:40Z hyunghwan.chung $
* $Id: rex.h 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -210,7 +210,7 @@ void qse_rex_close (
qse_rex_t* rex
);
qse_rex_t* qse_rex_init (
int qse_rex_init (
qse_rex_t* rex,
qse_mmgr_t* mmgr,
qse_rex_node_t* code

View File

@ -1,5 +1,5 @@
/*
* $Id: sio.h 547 2011-08-13 16:04:14Z hyunghwan.chung $
* $Id: sio.h 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -92,7 +92,7 @@ void qse_sio_close (
qse_sio_t* sio /**< stream */
);
qse_sio_t* qse_sio_init (
int qse_sio_init (
qse_sio_t* sio,
qse_mmgr_t* mmgr,
const qse_char_t* file,

View File

@ -1,5 +1,5 @@
/*
* $Id: sll.h 474 2011-05-23 16:52:37Z hyunghwan.chung $
* $Id: sll.h 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -192,12 +192,11 @@ void qse_sll_close (
* to it. The caller may declare a static variable of the qse_sll_t type
* and pass its address. A memory manager still needs to be passed for
* node manipulation later.
*
* @return
* @return 0 on success, -1 on failure
* The qse_sll_init() function returns the first parameter on success and
* QSE_NULL on failure.
*/
qse_sll_t* qse_sll_init (
int qse_sll_init (
qse_sll_t* sll, /* singly linked list */
qse_mmgr_t* mmgr /* memory manager */
);

View File

@ -1,5 +1,5 @@
/*
* $Id: str.h 550 2011-08-14 15:59:55Z hyunghwan.chung $
* $Id: str.h 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -877,6 +877,19 @@ int qse_wcsxncasecmp (
qse_size_t ln2 /**< length of the second string */
);
int qse_mbszcmp (
const qse_mchar_t* s1,
const qse_mchar_t* s2,
qse_size_t n
);
int qse_wcszcmp (
const qse_wchar_t* s1,
const qse_wchar_t* s2,
qse_size_t n
);
#ifdef QSE_CHAR_IS_MCHAR
# define qse_strcmp(s1,s2) qse_mbscmp(s1,s2)
# define qse_strxcmp(s1,ln1,s2) qse_mbsxcmp(s1,ln1,s2)
@ -884,6 +897,7 @@ int qse_wcsxncasecmp (
# define qse_strcasecmp(s1,s2) qse_mbscasecmp(s1,s2)
# define qse_strxcasecmp(s1,ln1,s2) qse_mbsxcasecmp(s1,ln1,s2)
# define qse_strxncasecmp(s1,ln1,s2,ln2) qse_mbsxncasecmp(s1,ln1,s2,ln2)
# define qse_strzcmp(s1,s2,n) qse_mbszcmp(s1,s2,n)
#else
# define qse_strcmp(s1,s2) qse_wcscmp(s1,s2)
# define qse_strxcmp(s1,ln1,s2) qse_wcsxcmp(s1,ln1,s2)
@ -891,6 +905,7 @@ int qse_wcsxncasecmp (
# define qse_strcasecmp(s1,s2) qse_wcscasecmp(s1,s2)
# define qse_strxcasecmp(s1,ln1,s2) qse_wcsxcasecmp(s1,ln1,s2)
# define qse_strxncasecmp(s1,ln1,s2,ln2) qse_wcsxncasecmp(s1,ln1,s2,ln2)
# define qse_strzcmp(s1,s2,n) qse_wcszcmp(s1,s2,n)
#endif
qse_mchar_t* qse_mbsdup (
@ -2265,9 +2280,9 @@ void qse_mbs_close (
* The qse_mbs_init() function initializes a dynamically resizable string
* If the parameter capa is 0, it doesn't allocate the internal buffer
* in advance and always succeeds.
* @return @a mbs on success, #QSE_NULL on failure.
* @return 0 on success, -1 on failure.
*/
qse_mbs_t* qse_mbs_init (
int qse_mbs_init (
qse_mbs_t* mbs,
qse_mmgr_t* mmgr,
qse_size_t capa
@ -2439,9 +2454,9 @@ void qse_wcs_close (
* The qse_wcs_init() function initializes a dynamically resizable string
* If the parameter capa is 0, it doesn't allocate the internal buffer
* in advance and always succeeds.
* @return @a wcs on success, #QSE_NULL on failure.
* @return 0 on success, -1 on failure.
*/
qse_wcs_t* qse_wcs_init (
int qse_wcs_init (
qse_wcs_t* wcs,
qse_mmgr_t* mmgr,
qse_size_t capa

View File

@ -1,5 +1,5 @@
/*
* $Id: tio.h 554 2011-08-22 05:26:26Z hyunghwan.chung $
* $Id: tio.h 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -126,7 +126,7 @@ QSE_DEFINE_COMMON_FUNCTIONS (tio)
*/
qse_tio_t* qse_tio_open (
qse_mmgr_t* mmgr,
qse_size_t ext
qse_size_t xtnsize
);
/**
@ -140,8 +140,8 @@ int qse_tio_close (
* The qse_tio_init() function initialize a statically declared
* text stream processor.
*/
qse_tio_t* qse_tio_init (
qse_tio_t* tip,
int qse_tio_init (
qse_tio_t* tio,
qse_mmgr_t* mmgr
);

134
qse/include/qse/cmn/tre.h Normal file
View File

@ -0,0 +1,134 @@
/*
* $Id$
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
QSE is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
QSE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _QSE_TRE_TRE_H_
#define _QSE_TRE_TRE_H_
#include <qse/types.h>
#include <qse/macros.h>
enum qse_tre_errnum_t
{
QSE_TRE_ENOERR,
QSE_TRE_ENOMEM, /* Out of memory */
QSE_TRE_ENOMATCH, /* No match */
QSE_TRE_EBADPAT, /* Invalid regular expression */
QSE_TRE_ECOLLATE, /* Unknown collating element */
QSE_TRE_ECTYPE, /* Unknown character class name */
QSE_TRE_EESCAPE, /* Traling backslash */
QSE_TRE_ESUBREG, /* Invalid backreference */
QSE_TRE_EBRACK, /* "[]" imbalance */
QSE_TRE_EPAREN, /* "\(\)" or "()" imbalance */
QSE_TRE_EBRACE, /* "\{\}" or "{}" imbalance */
QSE_TRE_EBADBR, /* Invalid content of {} */
QSE_TRE_ERANGE, /* Invalid use of range operator */
QSE_TRE_EBADRPT /* Invalid use of repetition operators */
};
typedef enum qse_tre_errnum_t qse_tre_errnum_t;
typedef struct qse_tre_t qse_tre_t;
struct qse_tre_t
{
qse_mmgr_t* mmgr;
qse_tre_errnum_t errnum;
qse_size_t re_nsub; /* Number of parenthesized subexpressions. */
void* value; /* For internal use only. */
};
#define QSE_TRE_ERRNUM(tre) ((const qse_tre_errnum_t)((tre)->errnum))
typedef int qse_tre_off_t;
typedef struct qse_tre_match_t qse_tre_match_t;
struct qse_tre_match_t
{
qse_tre_off_t rm_so;
qse_tre_off_t rm_eo;
};
enum qse_tre_cflag_t
{
QSE_TRE_EXTENDED = (1 << 0),
QSE_TRE_IGNORECASE = (1 << 1),
QSE_TRE_NEWLINE = (1 << 2),
QSE_TRE_NOSUBREG = (1 << 3),
QSE_TRE_LITERAL = (1 << 4),
QSE_TRE_RIGHTASSOC = (1 << 5),
QSE_TRE_UNGREEDY = (1 << 6)
};
enum qse_tre_eflag_t
{
QSE_TRE_NOTBOL = (1 << 0),
QSE_TRE_NOTEOL = (1 << 1),
QSE_TRE_BACKTRACKING = (1 << 2)
};
typedef struct qse_tre_strsrc_t qse_tre_strsrc_t;
struct qse_tre_strsrc_t
{
int (*get_next_char) (qse_char_t *c, unsigned int* pos_add, void* context);
void (*rewind)(qse_size_t pos, void *context);
int (*compare)(qse_size_t pos1, qse_size_t pos2, qse_size_t len, void* context);
void* context;
};
#ifdef __cplusplus
extern "C" {
#endif
int qse_tre_init (
qse_tre_t* tre,
qse_mmgr_t* mmgr
);
void qse_tre_fini (
qse_tre_t* tre
);
int qse_tre_compx (
qse_tre_t* tre,
const qse_char_t* regex,
qse_size_t n,
int cflags
);
int qse_tre_comp (
qse_tre_t* tre,
const qse_char_t* regex,
int cflags
);
int qse_tre_execx (
qse_tre_t* tre,
const qse_char_t* str,
qse_size_t len,
qse_size_t nmatch,
qse_tre_match_t pmatch[],
int eflags
);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -150,9 +150,9 @@ void qse_xma_close (
* to this function instead of calling qse_xma_open(). It obtains a memory zone
* of @a zonesize bytes with the memory manager @a mmgr. Unlike qse_xma_open(),
* it does not accept the extension size, thus not creating an extention area.
* @return @a xma on success, #QSE_NULL on failure
* @return 0 on success, -1 on failure
*/
qse_xma_t* qse_xma_init (
int qse_xma_init (
qse_xma_t* xma, /**< memory allocator */
qse_mmgr_t* mmgr, /**< memory manager */
qse_size_t zonesize /**< zone size in bytes */

View File

@ -127,7 +127,7 @@ void qse_htrd_close (
qse_htrd_t* htrd
);
qse_htrd_t* qse_htrd_init (
int qse_htrd_init (
qse_htrd_t* htrd,
qse_mmgr_t* mmgr
);

View File

@ -129,7 +129,7 @@ typedef int (*qse_htre_header_walker_t) (
extern "C" {
#endif
qse_htre_t* qse_htre_init (
int qse_htre_init (
qse_htre_t* re,
qse_mmgr_t* mmgr
);

View File

@ -1,2 +1,2 @@
SUBDIRS = cmn sed awk cut net stx
SUBDIRS = cmn awk cut sed net stx
DIST_SUBDIRS = $(SUBDIRS)

View File

@ -230,7 +230,7 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
SUBDIRS = cmn sed awk cut net stx
SUBDIRS = cmn awk cut sed net stx
DIST_SUBDIRS = $(SUBDIRS)
all: all-recursive

View File

@ -1,5 +1,5 @@
/*
* $Id: Awk.cpp 518 2011-07-24 14:24:13Z hyunghwan.chung $
* $Id: Awk.cpp 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -1066,7 +1066,8 @@ int Awk::open ()
QSE_ASSERT (awk == QSE_NULL && functionMap == QSE_NULL);
qse_awk_prm_t prm;
memset (&prm, 0, QSE_SIZEOF(prm));
QSE_MEMSET (&prm, 0, QSE_SIZEOF(prm));
prm.sprintf = sprintf;
prm.math.pow = pow;
prm.math.mod = mod;

View File

@ -1,5 +1,5 @@
/*
* $Id: fnc.c 518 2011-07-24 14:24:13Z hyunghwan.chung $
* $Id: fnc.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -979,7 +979,7 @@ static int __substitute (qse_awk_rtx_t* run, qse_long_t max_count)
}
}
if (qse_str_init (&new, run->awk->mmgr, s2.len) == QSE_NULL)
if (qse_str_init (&new, run->awk->mmgr, s2.len) <= -1)
{
qse_awk_rtx_seterrnum (run, QSE_AWK_ENOMEM, QSE_NULL);
goto oops;
@ -1343,14 +1343,14 @@ static int fnc_sprintf (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
nargs = qse_awk_rtx_getnargs (run);
QSE_ASSERT (nargs > 0);
if (qse_str_init (&out, run->awk->mmgr, 256) == QSE_NULL)
if (qse_str_init (&out, run->awk->mmgr, 256) <= -1)
{
qse_awk_rtx_seterrnum (run, QSE_AWK_ENOMEM, QSE_NULL);
goto oops;
}
out_inited = 1;
if (qse_str_init (&fbu, run->awk->mmgr, 256) == QSE_NULL)
if (qse_str_init (&fbu, run->awk->mmgr, 256) <= -1)
{
qse_awk_rtx_seterrnum (run, QSE_AWK_ENOMEM, QSE_NULL);
goto oops;

View File

@ -1,5 +1,5 @@
/*
* $Id: misc.c 522 2011-07-25 13:08:07Z hyunghwan.chung $
* $Id: misc.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -1071,7 +1071,7 @@ void* qse_awk_buildrex (
p = qse_buildrex (
awk->mmgr, awk->rex.depth.max.build,
((awk->option&QSE_AWK_REXBOUND)? 0:QSE_REX_NOBOUND),
((awk->option&QSE_AWK_REXBOUND)? 0: QSE_REX_NOBOUND),
ptn, len, &err
);
if (p == QSE_NULL) *errnum = QSE_AWK_REXERRTOERR(err);

View File

@ -1,5 +1,5 @@
/*
* $Id: run.c 551 2011-08-15 13:52:48Z hyunghwan.chung $
* $Id: run.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -818,21 +818,21 @@ static int init_rtx (qse_awk_rtx_t* rtx, qse_awk_t* awk, qse_awk_rio_t* rio)
rtx->inrec.maxflds = 0;
rtx->inrec.d0 = qse_awk_val_nil;
if (qse_str_init (
&rtx->inrec.line, MMGR(rtx), DEF_BUF_CAPA) == QSE_NULL)
&rtx->inrec.line, MMGR(rtx), DEF_BUF_CAPA) <= -1)
{
qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
return -1;
}
if (qse_str_init (
&rtx->inrec.linew, MMGR(rtx), DEF_BUF_CAPA) == QSE_NULL)
&rtx->inrec.linew, MMGR(rtx), DEF_BUF_CAPA) <= -1)
{
qse_str_fini (&rtx->inrec.line);
qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
return -1;
}
if (qse_str_init (&rtx->format.out, MMGR(rtx), 256) == QSE_NULL)
if (qse_str_init (&rtx->format.out, MMGR(rtx), 256) <= -1)
{
qse_str_fini (&rtx->inrec.linew);
qse_str_fini (&rtx->inrec.line);
@ -840,7 +840,7 @@ static int init_rtx (qse_awk_rtx_t* rtx, qse_awk_t* awk, qse_awk_rio_t* rio)
return -1;
}
if (qse_str_init (&rtx->format.fmt, MMGR(rtx), 256) == QSE_NULL)
if (qse_str_init (&rtx->format.fmt, MMGR(rtx), 256) <= -1)
{
qse_str_fini (&rtx->format.out);
qse_str_fini (&rtx->inrec.linew);
@ -6311,7 +6311,7 @@ static qse_awk_val_t* eval_getline (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
dst = (in == QSE_NULL)? QSE_T(""): in;
/* TODO: optimize the line buffer management */
if (qse_str_init (&buf, MMGR(run), DEF_BUF_CAPA) == QSE_NULL)
if (qse_str_init (&buf, MMGR(run), DEF_BUF_CAPA) <= -1)
{
if (in != QSE_NULL) QSE_AWK_FREE (run->awk, in);
SETERR_LOC (run, QSE_AWK_ENOMEM, &nde->loc);
@ -6483,7 +6483,7 @@ static int shorten_record (qse_awk_rtx_t* run, qse_size_t nflds)
}
if (qse_str_init (
&tmp, MMGR(run), QSE_STR_LEN(&run->inrec.line)) == QSE_NULL)
&tmp, MMGR(run), QSE_STR_LEN(&run->inrec.line)) <= -1)
{
if (ofs_free != QSE_NULL)
QSE_AWK_FREE (run->awk, ofs_free);
@ -6607,7 +6607,7 @@ static qse_char_t* idxnde_to_str (
out.type = QSE_AWK_RTX_VALTOSTR_STRPCAT;
out.u.strpcat = &idxstr;
if (qse_str_init (&idxstr, MMGR(run), DEF_BUF_CAPA) == QSE_NULL)
if (qse_str_init (&idxstr, MMGR(run), DEF_BUF_CAPA) <= -1)
{
SETERR_LOC (run, QSE_AWK_ENOMEM, &nde->loc);
return QSE_NULL;

View File

@ -1,5 +1,5 @@
/*
* $Id: val.c 518 2011-07-24 14:24:13Z hyunghwan.chung $
* $Id: val.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -448,10 +448,9 @@ qse_awk_val_t* qse_awk_rtx_makemapval (qse_awk_rtx_t* rtx)
val->nstr = 0;
val->map = (qse_htb_t*)(val + 1);
val->map = qse_htb_init (
val->map, rtx->awk->mmgr, 256, 70, QSE_SIZEOF(qse_char_t), 1
);
if (val->map == QSE_NULL)
if (qse_htb_init (
val->map, rtx->awk->mmgr,
256, 70, QSE_SIZEOF(qse_char_t), 1) <= -1)
{
QSE_AWK_FREE (rtx->awk, val);
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
@ -981,14 +980,14 @@ static int val_real_to_str (
tmp_len = rtx->gbl.convfmt.len;
}
if (qse_str_init (&buf, rtx->awk->mmgr, 256) == QSE_NULL)
if (qse_str_init (&buf, rtx->awk->mmgr, 256) <= -1)
{
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
return -1;
}
buf_inited = 1;
if (qse_str_init (&fbu, rtx->awk->mmgr, 256) == QSE_NULL)
if (qse_str_init (&fbu, rtx->awk->mmgr, 256) <= -1)
{
qse_str_fini (&buf);
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);

View File

@ -5,26 +5,84 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/include \
-I$(includedir)
lib_LTLIBRARIES = libqsecmn.la
libqsecmn_la_SOURCES = \
syscall.h mem.h \
mem.c xma.c fma.c pma.c chr.c chr_cnv.c rex.c \
str_beg.c str_cat.c str_chr.c str_cnv.c str_cmp.c str_cpy.c \
str_del.c str_dup.c str_dynm.c str_dynw.c str_end.c str_excl.c \
str_fcpy.c str_incl.c str_len.c str_pac.c str_pbrk.c str_put.c \
str_rev.c str_rot.c str_set.c str_spl.c str_spn.c str_str.c \
str_subst.c str_tok.c str_trm.c str_word.c \
lda.c oht.c htb.c rbt.c sll.c gdl.c dll.c opt.c \
tio.c tio_get.c tio_put.c \
fio.c pio.c sio.c \
alg_search.c \
alg_sort.c \
env.c \
time.c \
misc.c \
tre.h \
alg-search.c \
alg-sort.c \
assert.c \
chr.c \
chr-cnv.c \
dll.c \
env.c \
gdl.c \
htb.c \
lda.c \
fio.c \
fma.c \
main.c \
stdio.c
mem.c \
mem.h \
misc.c \
oht.c \
opt.c \
pma.c \
pio.c \
rbt.c \
rex.c \
sio.c \
sll.c \
str-beg.c \
str-cat.c \
str-chr.c \
str-cnv.c \
str-cmp.c \
str-cpy.c \
str-del.c \
str-dup.c \
str-dynm.c \
str-dynw.c \
str-end.c \
str-excl.c \
str-fcpy.c \
str-incl.c \
str-len.c \
str-pac.c \
str-pbrk.c \
str-put.c \
str-rev.c \
str-rot.c \
str-set.c \
str-spl.c \
str-spn.c \
str-str.c \
str-subst.c \
str-tok.c \
str-trm.c \
str-word.c \
syscall.h \
time.c \
tio.c \
tio-get.c \
tio-put.c \
tre.c \
tre.h \
tre-ast.c \
tre-ast.h \
tre-compile.c \
tre-compile.h \
tre-match-backtrack.c \
tre-match-parallel.c \
tre-match-utils.h \
tre-parse.c \
tre-parse.h \
tre-stack.c \
tre-stack.h \
stdio.c \
xma.c
libqsecmn_la_LDFLAGS = -L$(libdir) -version-info 1:0:0 -no-undefined
if WIN32

View File

@ -73,16 +73,18 @@ am__base_list = \
am__installdirs = "$(DESTDIR)$(libdir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libqsecmn_la_DEPENDENCIES =
am_libqsecmn_la_OBJECTS = mem.lo xma.lo fma.lo pma.lo chr.lo \
chr_cnv.lo rex.lo str_beg.lo str_cat.lo str_chr.lo str_cnv.lo \
str_cmp.lo str_cpy.lo str_del.lo str_dup.lo str_dynm.lo \
str_dynw.lo str_end.lo str_excl.lo str_fcpy.lo str_incl.lo \
str_len.lo str_pac.lo str_pbrk.lo str_put.lo str_rev.lo \
str_rot.lo str_set.lo str_spl.lo str_spn.lo str_str.lo \
str_subst.lo str_tok.lo str_trm.lo str_word.lo lda.lo oht.lo \
htb.lo rbt.lo sll.lo gdl.lo dll.lo opt.lo tio.lo tio_get.lo \
tio_put.lo fio.lo pio.lo sio.lo alg_search.lo alg_sort.lo \
env.lo time.lo misc.lo assert.lo main.lo stdio.lo
am_libqsecmn_la_OBJECTS = alg-search.lo alg-sort.lo assert.lo chr.lo \
chr-cnv.lo dll.lo env.lo gdl.lo htb.lo lda.lo fio.lo fma.lo \
main.lo mem.lo misc.lo oht.lo opt.lo pma.lo pio.lo rbt.lo \
rex.lo sio.lo sll.lo str-beg.lo str-cat.lo str-chr.lo \
str-cnv.lo str-cmp.lo str-cpy.lo str-del.lo str-dup.lo \
str-dynm.lo str-dynw.lo str-end.lo str-excl.lo str-fcpy.lo \
str-incl.lo str-len.lo str-pac.lo str-pbrk.lo str-put.lo \
str-rev.lo str-rot.lo str-set.lo str-spl.lo str-spn.lo \
str-str.lo str-subst.lo str-tok.lo str-trm.lo str-word.lo \
time.lo tio.lo tio-get.lo tio-put.lo tre.lo tre-ast.lo \
tre-compile.lo tre-match-backtrack.lo tre-match-parallel.lo \
tre-parse.lo tre-stack.lo stdio.lo xma.lo
libqsecmn_la_OBJECTS = $(am_libqsecmn_la_OBJECTS)
libqsecmn_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@ -272,24 +274,79 @@ AM_CPPFLAGS = \
lib_LTLIBRARIES = libqsecmn.la $(am__append_1)
libqsecmn_la_SOURCES = \
syscall.h mem.h \
mem.c xma.c fma.c pma.c chr.c chr_cnv.c rex.c \
str_beg.c str_cat.c str_chr.c str_cnv.c str_cmp.c str_cpy.c \
str_del.c str_dup.c str_dynm.c str_dynw.c str_end.c str_excl.c \
str_fcpy.c str_incl.c str_len.c str_pac.c str_pbrk.c str_put.c \
str_rev.c str_rot.c str_set.c str_spl.c str_spn.c str_str.c \
str_subst.c str_tok.c str_trm.c str_word.c \
lda.c oht.c htb.c rbt.c sll.c gdl.c dll.c opt.c \
tio.c tio_get.c tio_put.c \
fio.c pio.c sio.c \
alg_search.c \
alg_sort.c \
env.c \
time.c \
misc.c \
tre.h \
alg-search.c \
alg-sort.c \
assert.c \
chr.c \
chr-cnv.c \
dll.c \
env.c \
gdl.c \
htb.c \
lda.c \
fio.c \
fma.c \
main.c \
stdio.c
mem.c \
mem.h \
misc.c \
oht.c \
opt.c \
pma.c \
pio.c \
rbt.c \
rex.c \
sio.c \
sll.c \
str-beg.c \
str-cat.c \
str-chr.c \
str-cnv.c \
str-cmp.c \
str-cpy.c \
str-del.c \
str-dup.c \
str-dynm.c \
str-dynw.c \
str-end.c \
str-excl.c \
str-fcpy.c \
str-incl.c \
str-len.c \
str-pac.c \
str-pbrk.c \
str-put.c \
str-rev.c \
str-rot.c \
str-set.c \
str-spl.c \
str-spn.c \
str-str.c \
str-subst.c \
str-tok.c \
str-trm.c \
str-word.c \
syscall.h \
time.c \
tio.c \
tio-get.c \
tio-put.c \
tre.c \
tre.h \
tre-ast.c \
tre-ast.h \
tre-compile.c \
tre-compile.h \
tre-match-backtrack.c \
tre-match-parallel.c \
tre-match-utils.h \
tre-parse.c \
tre-parse.h \
tre-stack.c \
tre-stack.h \
stdio.c \
xma.c
libqsecmn_la_LDFLAGS = -L$(libdir) -version-info 1:0:0 -no-undefined
@WIN32_TRUE@libqsecmn_la_LIBADD = -lpsapi
@ -375,11 +432,11 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Mmgr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StdMmgr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alg_search.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alg_sort.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alg-search.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alg-sort.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/assert.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chr-cnv.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chr_cnv.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dll.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/env.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fio.Plo@am__quote@
@ -399,38 +456,45 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sio.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sll.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stdio.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_beg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_cat.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_chr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_cmp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_cnv.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_cpy.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_del.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_dup.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_dynm.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_dynw.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_end.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_excl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_fcpy.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_incl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_len.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_pac.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_pbrk.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_put.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_rev.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_rot.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_set.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_spl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_spn.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_str.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_subst.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_tok.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_trm.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_word.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-beg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-cat.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-chr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-cmp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-cnv.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-cpy.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-del.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-dup.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-dynm.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-dynw.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-end.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-excl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-fcpy.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-incl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-len.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-pac.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-pbrk.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-put.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-rev.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-rot.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-set.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-spl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-spn.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-str.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-subst.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-tok.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-trm.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str-word.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tio-get.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tio-put.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tio.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tio_get.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tio_put.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tre-ast.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tre-compile.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tre-match-backtrack.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tre-match-parallel.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tre-parse.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tre-stack.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tre.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xma.Plo@am__quote@
.c.o:

View File

@ -1,5 +1,5 @@
/*
* $Id: chr_cnv.c 554 2011-08-22 05:26:26Z hyunghwan.chung $
* $Id: chr-cnv.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: chr.c 555 2011-08-24 06:54:19Z hyunghwan.chung $
* $Id: chr.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -289,8 +289,8 @@ int qse_getwctypebyxname (const qse_wchar_t* name, qse_size_t len, qse_wctype_t*
mid = (left + right) / 2;
kwp = &wtab[mid];
n = qse_wcsxcmp (name, len, wtab->name);
if (n > 0)
n = qse_wcsxcmp (name, len, kwp->name);
if (n < 0)
{
/* if left, right, mid were of qse_size_t,
* you would need the following line.
@ -298,7 +298,7 @@ int qse_getwctypebyxname (const qse_wchar_t* name, qse_size_t len, qse_wctype_t*
*/
right = mid - 1;
}
else if (n < 0) left = mid + 1;
else if (n > 0) left = mid + 1;
else
{
*id = kwp->class;
@ -332,8 +332,7 @@ static struct mtab_t
{ QSE_MT("punct"), QSE_MCTYPE_PUNCT },
{ QSE_MT("space"), QSE_MCTYPE_SPACE },
{ QSE_MT("upper"), QSE_MCTYPE_UPPER },
{ QSE_MT("xdigit"), QSE_MCTYPE_XDIGIT },
{ QSE_NULL, 0 }
{ QSE_MT("xdigit"), QSE_MCTYPE_XDIGIT }
};
int qse_getmctypebyname (const qse_mchar_t* name, qse_mctype_t* id)
@ -364,7 +363,7 @@ int qse_getmctypebyname (const qse_mchar_t* name, qse_mctype_t* id)
}
}
return (qse_mctype_t)0;
return -1;
}
int qse_getmctypebyxname (const qse_mchar_t* name, qse_size_t len, qse_mctype_t* id)
@ -378,8 +377,8 @@ int qse_getmctypebyxname (const qse_mchar_t* name, qse_size_t len, qse_mctype_t*
mid = (left + right) / 2;
kwp = &mtab[mid];
n = qse_mbsxcmp (name, len, mtab->name);
if (n > 0)
n = qse_mbsxcmp (name, len, kwp->name);
if (n < 0)
{
/* if left, right, mid were of qse_size_t,
* you would need the following line.
@ -387,7 +386,7 @@ int qse_getmctypebyxname (const qse_mchar_t* name, qse_size_t len, qse_mctype_t*
*/
right = mid - 1;
}
else if (n < 0) left = mid + 1;
else if (n > 0) left = mid + 1;
else
{
*id = kwp->class;
@ -395,7 +394,7 @@ int qse_getmctypebyxname (const qse_mchar_t* name, qse_size_t len, qse_mctype_t*
}
}
return (qse_mctype_t)0;
return -1;
}
qse_mctype_t qse_getmctype (const qse_mchar_t* name)

View File

@ -1,5 +1,5 @@
/*
* $Id: dll.c 474 2011-05-23 16:52:37Z hyunghwan.chung $
* $Id: dll.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -29,8 +29,8 @@ QSE_IMPLEMENT_COMMON_FUNCTIONS (dll)
static int default_comper (
qse_dll_t* dll,
const void* dptr1, size_t dlen1,
const void* dptr2, size_t dlen2)
const void* dptr1, qse_size_t dlen1,
const void* dptr2, qse_size_t dlen2)
{
if (dlen1 == dlen2) return QSE_MEMCMP (dptr1, dptr2, TOB(dll,dlen1));
/* it just returns 1 to indicate that they are different. */
@ -64,7 +64,7 @@ qse_dll_t* qse_dll_open (qse_mmgr_t* mmgr, qse_size_t xtnsize)
dll = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_dll_t) + xtnsize);
if (dll == QSE_NULL) return QSE_NULL;
if (qse_dll_init (dll, mmgr) == QSE_NULL)
if (qse_dll_init (dll, mmgr) <= -1)
{
QSE_MMGR_FREE (mmgr, dll);
return QSE_NULL;
@ -79,7 +79,7 @@ void qse_dll_close (qse_dll_t* dll)
QSE_MMGR_FREE (dll->mmgr, dll);
}
qse_dll_t* qse_dll_init (qse_dll_t* dll, qse_mmgr_t* mmgr)
int qse_dll_init (qse_dll_t* dll, qse_mmgr_t* mmgr)
{
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
@ -93,7 +93,7 @@ qse_dll_t* qse_dll_init (qse_dll_t* dll, qse_mmgr_t* mmgr)
dll->copier = QSE_DLL_COPIER_SIMPLE;
QSE_DLL_INIT (dll);
return dll;
return 0;
}
void qse_dll_fini (qse_dll_t* dll)

View File

@ -51,7 +51,7 @@ qse_env_t* qse_env_open (qse_mmgr_t* mmgr, qse_size_t xtnsize, int fromcurenv)
env = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_env_t) + xtnsize);
if (env == QSE_NULL) return QSE_NULL;
if (qse_env_init (env, mmgr, fromcurenv) == QSE_NULL)
if (qse_env_init (env, mmgr, fromcurenv) <= -1)
{
QSE_MMGR_FREE (mmgr, env);
return QSE_NULL;
@ -66,13 +66,13 @@ void qse_env_close (qse_env_t* env)
QSE_MMGR_FREE (env->mmgr, env);
}
qse_env_t* qse_env_init (qse_env_t* env, qse_mmgr_t* mmgr, int fromcurenv)
int qse_env_init (qse_env_t* env, qse_mmgr_t* mmgr, int fromcurenv)
{
QSE_MEMSET (env, 0, QSE_SIZEOF(*env));
env->mmgr = mmgr;
if (fromcurenv && load_curenv (env) <= -1) return QSE_NULL;
return env;
if (fromcurenv && load_curenv (env) <= -1) return -1;
return 0;
}
void qse_env_fini (qse_env_t* env)

View File

@ -1,5 +1,5 @@
/*
* $Id: fio.c 550 2011-08-14 15:59:55Z hyunghwan.chung $
* $Id: fio.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -24,7 +24,7 @@
#if defined(_WIN32)
# include <windows.h>
# include <psapi.h>
# include <psapi.h> /* for GetMappedFileName() */
# include <tchar.h>
#elif defined(__OS2__)
# define INCL_DOSFILEMGR
@ -67,7 +67,7 @@ qse_fio_t* qse_fio_open (
fio = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_fio_t) + ext);
if (fio == QSE_NULL) return QSE_NULL;
if (qse_fio_init (fio, mmgr, path, flags, mode) == QSE_NULL)
if (qse_fio_init (fio, mmgr, path, flags, mode) <= -1)
{
QSE_MMGR_FREE (mmgr, fio);
return QSE_NULL;
@ -82,7 +82,7 @@ void qse_fio_close (qse_fio_t* fio)
QSE_MMGR_FREE (fio->mmgr, fio);
}
qse_fio_t* qse_fio_init (
int qse_fio_init (
qse_fio_t* fio, qse_mmgr_t* mmgr,
const qse_char_t* path, int flags, int mode)
{
@ -157,13 +157,13 @@ qse_fio_t* qse_fio_init (
creation_disposition, flag_and_attr, 0
);
}
if (handle == INVALID_HANDLE_VALUE) return QSE_NULL;
if (handle == INVALID_HANDLE_VALUE) return -1;
/* some special check */
if (GetFileType(handle) == FILE_TYPE_UNKNOWN)
{
CloseHandle (handle);
return QSE_NULL;
return -1;
}
/* TODO: support more features on WIN32 - TEMPORARY, DELETE_ON_CLOSE */
@ -186,7 +186,7 @@ qse_fio_t* qse_fio_init (
#else
qse_mchar_t path_mb[CCHMAXPATH];
if (qse_wcstombs_strict (path,
path_mb, QSE_COUNTOF(path_mb)) == -1) return QSE_NULL;
path_mb, QSE_COUNTOF(path_mb)) == -1) return -1;
#endif
zero.ulLo = 0;
@ -253,7 +253,7 @@ qse_fio_t* qse_fio_init (
0L
);
if (ret != NO_ERROR) return QSE_NULL;
if (ret != NO_ERROR) return -1;
}
#elif defined(__DOS__)
@ -272,7 +272,7 @@ qse_fio_t* qse_fio_init (
#else
qse_mchar_t path_mb[_MAX_PATH];
if (qse_wcstombs_strict (path,
path_mb, QSE_COUNTOF(path_mb)) == -1) return QSE_NULL;
path_mb, QSE_COUNTOF(path_mb)) == -1) return -1;
#endif
if (flags & QSE_FIO_APPEND)
@ -303,7 +303,7 @@ qse_fio_t* qse_fio_init (
oflags,
permission
);
if (handle <= -1) return QSE_NULL;
if (handle <= -1) return -1;
}
#else
@ -321,7 +321,7 @@ qse_fio_t* qse_fio_init (
#else
qse_mchar_t path_mb[PATH_MAX + 1];
if (qse_wcstombs_strict (path,
path_mb, QSE_COUNTOF(path_mb)) == -1) return QSE_NULL;
path_mb, QSE_COUNTOF(path_mb)) == -1) return -1;
#endif
/*
* rwa -> RDWR | APPEND
@ -358,7 +358,7 @@ qse_fio_t* qse_fio_init (
handle = QSE_OPEN (path_mb, desired_access, mode);
}
if (handle == -1) return QSE_NULL;
if (handle == -1) return -1;
#endif
@ -369,8 +369,8 @@ qse_fio_t* qse_fio_init (
tio = qse_tio_open (fio->mmgr, 0);
if (tio == QSE_NULL) QSE_THROW_ERR (tio);
if (qse_tio_attachin (tio, fio_input, fio) == -1 ||
qse_tio_attachout (tio, fio_output, fio) == -1)
if (qse_tio_attachin (tio, fio_input, fio) <= -1 ||
qse_tio_attachout (tio, fio_output, fio) <= -1)
{
qse_tio_close (tio);
QSE_THROW_ERR (tio);
@ -387,7 +387,7 @@ qse_fio_t* qse_fio_init (
#else
QSE_CLOSE (handle);
#endif
return QSE_NULL;
return -1;
}
fio->tio = tio;
@ -395,7 +395,7 @@ qse_fio_t* qse_fio_init (
fio->handle = handle;
return fio;
return 0;
}
void qse_fio_fini (qse_fio_t* fio)
@ -436,15 +436,17 @@ qse_fio_off_t qse_fio_seek (
QSE_ASSERT (QSE_SIZEOF(offset) <= QSE_SIZEOF(x.QuadPart));
/* SetFilePointerEx is not available on Windows NT 4.
* So let's use SetFilePointerEx */
#if 0
x.QuadPart = offset;
if (SetFilePointerEx (fio->handle, x, &y, seek_map[origin]) == FALSE)
{
return (qse_fio_off_t)-1;
}
return (qse_fio_off_t)y.QuadPart;
#endif
/*
x.QuadPart = offset;
x.LowPart = SetFilePointer (
fio->handle, x.LowPart, &x.HighPart, seek_map[origin]);
@ -452,9 +454,8 @@ qse_fio_off_t qse_fio_seek (
{
return (qse_fio_off_t)-1;
}
return (qse_fio_off_t)x.QuadPart;
*/
#elif defined(__OS2__)
static int seek_map[] =
{
@ -518,11 +519,15 @@ qse_fio_off_t qse_fio_seek (
int qse_fio_truncate (qse_fio_t* fio, qse_fio_off_t size)
{
#if defined(_WIN32)
#if 0
LARGE_INTEGER x;
x.QuadPart = size;
if (SetFilePointerEx(fio->handle,x,NULL,FILE_BEGIN) == FALSE ||
SetEndOfFile(fio->handle) == FALSE) return -1;
#endif
if (qse_fio_seek (fio, size, QSE_FIO_BEGIN) == (qse_fio_off_t)-1) return -1;
if (SetEndOfFile(fio->handle) == FALSE) return -1;
return 0;
#elif defined(__OS2__)
@ -637,7 +642,6 @@ qse_ssize_t qse_fio_flush (qse_fio_t* fio)
return qse_tio_flush (fio->tio);
}
#if defined(_WIN32)
static int get_devname_from_handle (

View File

@ -42,7 +42,7 @@ qse_fma_t* qse_fma_open (
fma = (qse_fma_t*) QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(*fma) + xtnsize);
if (fma == QSE_NULL) return QSE_NULL;
if (qse_fma_init (fma, mmgr, blksize, maxblks, maxcnks) == QSE_NULL)
if (qse_fma_init (fma, mmgr, blksize, maxblks, maxcnks) <= -1)
{
QSE_MMGR_FREE (mmgr, fma);
return QSE_NULL;
@ -57,7 +57,7 @@ void qse_fma_close (qse_fma_t* fma)
QSE_MMGR_FREE (fma->mmgr, fma);
}
qse_fma_t* qse_fma_init (
int qse_fma_init (
qse_fma_t* fma, qse_mmgr_t* mmgr,
qse_size_t blksize, qse_size_t maxblks, qse_size_t maxcnks)
{
@ -74,7 +74,7 @@ qse_fma_t* qse_fma_init (
fma->maxblks = maxblks;
fma->maxcnks = maxcnks;
return fma;
return 0;
}
void qse_fma_fini (qse_fma_t* fma)

View File

@ -1,5 +1,5 @@
/*
* $Id: htb.c 492 2011-06-15 16:00:36Z hyunghwan.chung $
* $Id: htb.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -274,7 +274,7 @@ htb_t* qse_htb_open (
htb = (htb_t*) QSE_MMGR_ALLOC (mmgr, SIZEOF(htb_t) + xtnsize);
if (htb == QSE_NULL) return QSE_NULL;
if (qse_htb_init (htb, mmgr, capa, factor, kscale, vscale) == QSE_NULL)
if (qse_htb_init (htb, mmgr, capa, factor, kscale, vscale) <= -1)
{
QSE_MMGR_FREE (mmgr, htb);
return QSE_NULL;
@ -289,7 +289,7 @@ void qse_htb_close (htb_t* htb)
QSE_MMGR_FREE (htb->mmgr, htb);
}
htb_t* qse_htb_init (
int qse_htb_init (
htb_t* htb, mmgr_t* mmgr, size_t capa,
int factor, int kscale, int vscale)
{
@ -310,10 +310,10 @@ htb_t* qse_htb_init (
htb->mmgr = mmgr;
htb->bucket = QSE_MMGR_ALLOC (mmgr, capa*SIZEOF(pair_t*));
if (htb->bucket == QSE_NULL) return QSE_NULL;
if (htb->bucket == QSE_NULL) return -1;
/*for (i = 0; i < capa; i++) htb->bucket[i] = QSE_NULL;*/
QSE_MEMSET (htb->bucket, 0, capa*SIZEOF(pair_t*));
QSE_MEMSET (htb->bucket, 0, capa * SIZEOF(pair_t*));
htb->factor = factor;
htb->scale[QSE_HTB_KEY] = (kscale < 1)? 1: kscale;
@ -325,7 +325,7 @@ htb_t* qse_htb_init (
if (htb->capa > 0 && htb->threshold <= 0) htb->threshold = 1;
htb->mancbs = &mancbs[0];
return htb;
return 0;
}
void qse_htb_fini (htb_t* htb)

View File

@ -1,5 +1,5 @@
/*
* $Id: lda.c 479 2011-05-24 15:14:58Z hyunghwan.chung $
* $Id: lda.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -111,7 +111,7 @@ lda_t* qse_lda_open (mmgr_t* mmgr, size_t ext, size_t capa)
lda = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(lda_t) + ext);
if (lda == QSE_NULL) return QSE_NULL;
if (qse_lda_init (lda, mmgr, capa) == QSE_NULL)
if (qse_lda_init (lda, mmgr, capa) <= -1)
{
QSE_MMGR_FREE (mmgr, lda);
return QSE_NULL;
@ -126,7 +126,7 @@ void qse_lda_close (lda_t* lda)
QSE_MMGR_FREE (lda->mmgr, lda);
}
lda_t* qse_lda_init (lda_t* lda, mmgr_t* mmgr, size_t capa)
int qse_lda_init (lda_t* lda, mmgr_t* mmgr, size_t capa)
{
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
@ -140,8 +140,7 @@ lda_t* qse_lda_init (lda_t* lda, mmgr_t* mmgr, size_t capa)
lda->copier = QSE_LDA_COPIER_SIMPLE;
lda->comper = default_comparator;
if (qse_lda_setcapa (lda, capa) == QSE_NULL) return QSE_NULL;
return lda;
return (qse_lda_setcapa (lda, capa) == QSE_NULL)? -1: 0;
}
void qse_lda_fini (lda_t* lda)

View File

@ -26,7 +26,8 @@
int qse_runmain (
int argc, qse_achar_t* argv[], qse_runmain_handler_t handler)
{
setlocale (LC_ALL, ""); /* TODO: remove dependency on setlocale */
/* TODO: remove dependency on setlocale */
setlocale (LC_ALL, "");
#if (defined(QSE_ACHAR_IS_MCHAR) && defined(QSE_CHAR_IS_MCHAR)) || \
(defined(QSE_ACHAR_IS_WCHAR) && defined(QSE_CHAR_IS_WCHAR))

View File

@ -1,5 +1,5 @@
/*
* $Id: mem.h 441 2011-04-22 14:28:43Z hyunghwan.chung $
* $Id: mem.h 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -24,22 +24,22 @@
#include <qse/cmn/mem.h>
#ifdef MINIMIZE_PLATFORM_DEPENDENCY
# define QSE_MEMCPY(dst,src,len) qse_memcpy(dst,src,len)
# define QSE_MEMCMP(p1,p2,len) qse_memcmp(p1,p2,len)
# define QSE_MEMSET(dst,val,len) qse_memset(dst,val,len)
# define QSE_MEMBYTE(s,val,len) qse_membyte(s,val,len)
# define QSE_MEMRBYTE(s,val,len) qse_memrbyte(s,val,len)
# define QSE_MEMMEM(hs,hl,nd,nl) qse_memmem(hs,hl,nd,nl)
# define QSE_MEMCPY(dst,src,len) qse_memcpy(dst,src,len)
# define QSE_MEMCMP(p1,p2,len) qse_memcmp(p1,p2,len)
# define QSE_MEMSET(dst,val,len) qse_memset(dst,val,len)
# define QSE_MEMBYTE(s,val,len) qse_membyte(s,val,len)
# define QSE_MEMRBYTE(s,val,len) qse_memrbyte(s,val,len)
# define QSE_MEMMEM(hs,hl,nd,nl) qse_memmem(hs,hl,nd,nl)
# define QSE_MEMRMEM(hs,hl,nd,nl) qse_memrmem(hs,hl,nd,nl)
#else
# include <string.h>
# define QSE_MEMCPY(dst,src,len) memcpy(dst,src,len)
# define QSE_MEMCMP(p1,p2,len) memcmp(p1,p2,len)
# define QSE_MEMSET(dst,val,len) memset(dst,val,len)
# define QSE_MEMBYTE(s,val,len) memchr(s,val,len)
# define QSE_MEMRBYTE(s,val,len) memrchr(s,val,len)
# define QSE_MEMMEM(hs,hl,nd,nl) memmem(hs,hl,nd,nl)
# define QSE_MEMRMEM(hs,hl,nd,nl) memrmem(hs,hl,nd,nl)
# define QSE_MEMCPY(dst,src,len) memcpy(dst,src,len)
# define QSE_MEMCMP(p1,p2,len) memcmp(p1,p2,len)
# define QSE_MEMSET(dst,val,len) memset(dst,val,len)
# define QSE_MEMBYTE(s,val,len) memchr(s,val,len)
# define QSE_MEMRBYTE(s,val,len) memrchr(s,val,len)
# define QSE_MEMMEM(hs,hl,nd,nl) memmem(hs,hl,nd,nl)
# define QSE_MEMRMEM(hs,hl,nd,nl) qse_memrmem(hs,hl,nd,nl)
#endif
#define QSE_MALLOC(mmgr,size) QSE_MMGR_ALLOC(mmgr,size)

View File

@ -9,7 +9,7 @@ QSE_IMPLEMENT_COMMON_FUNCTIONS (oht)
static QSE_INLINE_ALWAYS qse_size_t default_hasher (
qse_oht_t* oht, const void* data)
{
size_t h = 5381;
qse_size_t h = 5381;
const qse_byte_t* p = (const qse_byte_t*)data;
const qse_byte_t* bound = p + oht->scale;
while (p < bound) h = ((h << 5) + h) + *p++;
@ -61,7 +61,7 @@ qse_oht_t* qse_oht_open (
oht = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_oht_t) + xtnsize);
if (oht == QSE_NULL) return QSE_NULL;
if (qse_oht_init (oht, mmgr, scale, capa, limit) == QSE_NULL)
if (qse_oht_init (oht, mmgr, scale, capa, limit) <= -1)
{
QSE_MMGR_FREE (mmgr, oht);
return QSE_NULL;
@ -76,7 +76,7 @@ void qse_oht_close (qse_oht_t* oht)
QSE_MMGR_FREE (oht->mmgr, oht);
}
qse_oht_t* qse_oht_init (
int qse_oht_init (
qse_oht_t* oht, qse_mmgr_t* mmgr,
int scale, qse_size_t capa, qse_size_t limit)
{
@ -99,17 +99,17 @@ qse_oht_t* qse_oht_init (
oht->copier = default_copier;*/
oht->mark = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_oht_mark_t) * capa);
if (!oht->mark) return QSE_NULL;
if (!oht->mark) return -1;
oht->data = QSE_MMGR_ALLOC (mmgr, scale * capa);
if (!oht->data)
{
QSE_MMGR_FREE (mmgr, oht->mark);
return QSE_NULL;
return -1;
}
for (i = 0; i < capa; i++) oht->mark[i] = QSE_OHT_EMPTY;
return oht;
return 0;
}
void qse_oht_fini (qse_oht_t* oht)

View File

@ -1,5 +1,5 @@
/*
* $Id: pio.c 543 2011-08-12 16:35:34Z hyunghwan.chung $
* $Id: pio.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -62,7 +62,7 @@ qse_pio_t* qse_pio_open (
pio = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_pio_t) + ext);
if (pio == QSE_NULL) return QSE_NULL;
if (qse_pio_init (pio, mmgr, cmd, env, oflags) == QSE_NULL)
if (qse_pio_init (pio, mmgr, cmd, env, oflags) <= -1)
{
QSE_MMGR_FREE (mmgr, pio);
return QSE_NULL;
@ -77,7 +77,7 @@ void qse_pio_close (qse_pio_t* pio)
QSE_MMGR_FREE (pio->mmgr, pio);
}
qse_pio_t* qse_pio_init (
int qse_pio_init (
qse_pio_t* pio, qse_mmgr_t* mmgr, const qse_char_t* cmd,
qse_env_t* env, int oflags)
{
@ -183,7 +183,11 @@ qse_pio_t* qse_pio_init (
maxidx = 5;
}
if (maxidx == -1) goto oops;
if (maxidx == -1)
{
pio->errnum = QSE_PIO_EINVAL;
goto oops;
}
if ((oflags & QSE_PIO_INTONUL) ||
(oflags & QSE_PIO_OUTTONUL) ||
@ -255,7 +259,11 @@ qse_pio_t* qse_pio_init (
{
const qse_mchar_t* mbs = (const qse_mchar_t*)cmd;
qse_size_t ll = qse_mbstowcslen (mbs, &reqlen);
if (mbs[ll] != QSE_MT('\0')) goto oops; /* illegal sequence */
if (mbs[ll] != QSE_MT('\0'))
{
pio->errnum = QSE_PIO_EINVAL;
goto oops; /* illegal sequence */
}
}
else
{
@ -270,7 +278,11 @@ qse_pio_t* qse_pio_init (
dupcmd = QSE_MMGR_ALLOC (
mmgr, (11 + reqlen) * QSE_SIZEOF(*dupcmd)
);
if (dupcmd == QSE_NULL) goto oops;
if (dupcmd == QSE_NULL)
{
pio->errnum = QSE_PIO_ENOMEM;
goto oops;
}
qse_strcpy (dupcmd, QSE_T("cmd.exe /c "));
@ -302,7 +314,11 @@ qse_pio_t* qse_pio_init (
#if defined(QSE_CHAR_IS_WCHAR)
}
#endif
if (dupcmd == QSE_NULL) goto oops;
if (dupcmd == QSE_NULL)
{
pio->errnum = QSE_PIO_ENOMEM;
goto oops;
}
}
x = CreateProcess (
@ -403,7 +419,11 @@ qse_pio_t* qse_pio_init (
maxidx = 5;
}
if (maxidx == -1) goto oops;
if (maxidx == -1)
{
pio->errnum = QSE_PIO_EINVAL;
goto oops;
}
if ((oflags & QSE_PIO_INTONUL) ||
(oflags & QSE_PIO_OUTTONUL) ||
@ -513,12 +533,20 @@ qse_pio_t* qse_pio_init (
else
{
n = qse_wcstombslen (cmd, &mn);
if (cmd[n] != QSE_WT('\0')) goto oops; /* illegal sequence found */
if (cmd[n] != QSE_WT('\0'))
{
pio->errnum = QSE_PIO_EINVAL;
goto oops; /* illegal sequence found */
}
}
#endif
cmd_line = QSE_MMGR_ALLOC (
mmgr, ((11+mn+1+1) * QSE_SIZEOF(*cmd_line)));
if (cmd_line == QSE_NULL) goto oops;
if (cmd_line == QSE_NULL)
{
pio->errnum = QSE_PIO_ENOMEM;
goto oops;
}
qse_mbscpy (cmd_line, QSE_MT("cmd.exe")); /* cmd.exe\0/c */
qse_mbscpy (&cmd_line[8], QSE_MT("/c "));
@ -547,24 +575,40 @@ qse_pio_t* qse_pio_init (
#ifdef QSE_CHAR_IS_MCHAR
mn = qse_strlen(cmd);
cmd_line = qse_strdup2 (cmd, QSE_T(" "), pio->mmgr);
if (cmd_line == QSE_NULL) goto oops;
if (cmd_line == QSE_NULL)
{
pio->errnum = QSE_PIO_ENOMEM;
goto oops;
}
#else
if (oflags & QSE_PIO_MBSCMD)
{
mn = qse_mbslen((const qse_mchar_t*)cmd);
cmd_line = qse_mbsdup2 ((const qse_mchar_t*)cmd, QSE_MT(" "), pio->mmgr);
if (cmd_line == QSE_NULL) goto oops;
if (cmd_line == QSE_NULL)
{
pio->errnum = QSE_PIO_ENOMEM;
goto oops;
}
}
else
{
qse_size_t n;
n = qse_wcstombslen (cmd, &mn);
if (cmd[n] != QSE_T('\0')) goto oops; /* illegal sequence in cmd */
if (cmd[n] != QSE_T('\0'))
{
pio->errnum = QSE_PIO_EINVAL;
goto oops; /* illegal sequence in cmd */
}
mn = mn + 1;
cmd_line = QSE_MMGR_ALLOC (pio->mmgr, mn * QSE_SIZEOF(qse_char_t));
if (cmd_line == QSE_NULL) goto oops;
if (cmd_line == QSE_NULL)
{
pio->errnum = QSE_PIO_ENOMEM;
goto oops;
}
qse_wcstombs (cmd, cmd_line, &mn);
}
@ -611,7 +655,7 @@ qse_pio_t* qse_pio_init (
#elif defined(__DOS__)
/* DOS not multi-processed. can't support pio */
return QSE_NULL;
return -1;
#else
@ -635,7 +679,11 @@ qse_pio_t* qse_pio_init (
maxidx = 5;
}
if (maxidx == -1) goto oops;
if (maxidx == -1)
{
pio->errnum = QSE_PIO_EINVAL;
goto oops;
}
pid = QSE_FORK();
if (pid <= -1) goto oops;
@ -956,7 +1004,11 @@ qse_pio_t* qse_pio_init (
int r;
tio[i] = qse_tio_open (pio->mmgr, 0);
if (tio[i] == QSE_NULL) goto oops;
if (tio[i] == QSE_NULL)
{
pio->errnum = QSE_PIO_ENOMEM;
goto oops;
}
r = (i == QSE_PIO_IN)?
qse_tio_attachout (tio[i], pio_output, &pio->pin[i]):
@ -969,9 +1021,11 @@ qse_pio_t* qse_pio_init (
}
pio->option = 0;
return pio;
return 0;
oops:
if (pio->errnum == QSE_PIO_ENOERR)
pio->errnum = QSE_PIO_ESUBSYS;
#if defined(_WIN32)
if (windevnul != INVALID_HANDLE_VALUE) CloseHandle (windevnul);
@ -1019,7 +1073,7 @@ oops:
}
#endif
return QSE_NULL;
return -1;
}
void qse_pio_fini (qse_pio_t* pio)
@ -1054,6 +1108,7 @@ const qse_char_t* qse_pio_geterrmsg (qse_pio_t* pio)
{
QSE_T("no error"),
QSE_T("out of memory"),
QSE_T("invalid parameter"),
QSE_T("no handle available"),
QSE_T("child process not valid"),
QSE_T("interruped"),

View File

@ -56,7 +56,7 @@ qse_pma_t* qse_pma_open (qse_mmgr_t* mmgr, qse_size_t xtnsize)
pma = (qse_pma_t*)QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(*pma) + xtnsize);
if (pma == QSE_NULL) return QSE_NULL;
if (qse_pma_init (pma, mmgr) == QSE_NULL)
if (qse_pma_init (pma, mmgr) <= -1)
{
QSE_MMGR_FREE (mmgr, pma);
return QSE_NULL;
@ -71,14 +71,14 @@ void qse_pma_close (qse_pma_t* pma)
QSE_MMGR_FREE (pma->mmgr, pma);
}
qse_pma_t* qse_pma_init (qse_pma_t* pma, qse_mmgr_t* mmgr)
int qse_pma_init (qse_pma_t* pma, qse_mmgr_t* mmgr)
{
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
QSE_MEMSET (pma, 0, QSE_SIZEOF(*pma));
pma->mmgr = mmgr;
return pma;
return 0;
}
/* Frees the memory allocator and all memory allocated with it. */

View File

@ -214,7 +214,7 @@ rbt_t* qse_rbt_open (mmgr_t* mmgr, size_t xtnsize, int kscale, int vscale)
rbt = (rbt_t*) QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(rbt_t) + xtnsize);
if (rbt == QSE_NULL) return QSE_NULL;
if (qse_rbt_init (rbt, mmgr, kscale, vscale) == QSE_NULL)
if (qse_rbt_init (rbt, mmgr, kscale, vscale) <= -1)
{
QSE_MMGR_FREE (mmgr, rbt);
return QSE_NULL;
@ -229,7 +229,7 @@ void qse_rbt_close (rbt_t* rbt)
QSE_MMGR_FREE (rbt->mmgr, rbt);
}
rbt_t* qse_rbt_init (rbt_t* rbt, mmgr_t* mmgr, int kscale, int vscale)
int qse_rbt_init (rbt_t* rbt, mmgr_t* mmgr, int kscale, int vscale)
{
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
@ -252,7 +252,7 @@ rbt_t* qse_rbt_init (rbt_t* rbt, mmgr_t* mmgr, int kscale, int vscale)
/* root is set to nil initially */
rbt->root = &rbt->nil;
return rbt;
return 0;
}
void qse_rbt_fini (rbt_t* rbt)

View File

@ -1,5 +1,5 @@
/*
* $Id: rex.c 554 2011-08-22 05:26:26Z hyunghwan.chung $
* $Id: rex.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -118,7 +118,7 @@ struct cand_t
QSE_IMPLEMENT_COMMON_FUNCTIONS (rex)
qse_rex_t* qse_rex_init (qse_rex_t* rex, qse_mmgr_t* mmgr, qse_rex_node_t* code)
int qse_rex_init (qse_rex_t* rex, qse_mmgr_t* mmgr, qse_rex_node_t* code)
{
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
@ -132,7 +132,7 @@ qse_rex_t* qse_rex_init (qse_rex_t* rex, qse_mmgr_t* mmgr, qse_rex_node_t* code)
* is closed, the code delegated is destroyed. */
rex->code = code;
return rex;
return 0;
}
qse_rex_t* qse_rex_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_rex_node_t* code)
@ -152,7 +152,7 @@ qse_rex_t* qse_rex_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_rex_node_t* code)
rex = (qse_rex_t*) QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_rex_t) + xtn);
if (rex == QSE_NULL) return QSE_NULL;
if (qse_rex_init (rex, mmgr, code) == QSE_NULL)
if (qse_rex_init (rex, mmgr, code) <= -1)
{
QSE_MMGR_FREE (mmgr, rex);
return QSE_NULL;
@ -1967,14 +1967,14 @@ static int comp_cand (qse_lda_t* lda,
static int init_exec_dds (exec_t* e, qse_mmgr_t* mmgr)
{
/* initializes dynamic data structures */
if (qse_lda_init (&e->cand.set[0], mmgr, 100) == QSE_NULL)
if (qse_lda_init (&e->cand.set[0], mmgr, 100) <= -1)
{
/* TOOD: set error */
e->rex->errnum = QSE_REX_ENOMEM;
return -1;
}
if (qse_lda_init (&e->cand.set[1], mmgr, 100) == QSE_NULL)
if (qse_lda_init (&e->cand.set[1], mmgr, 100) <= -1)
{
/* TOOD: set error */
e->rex->errnum = QSE_REX_ENOMEM;
qse_lda_fini (&e->cand.set[0]);
return -1;
}

View File

@ -1,5 +1,5 @@
/*
* $Id: sio.c 454 2011-05-06 15:28:27Z hyunghwan.chung $
* $Id: sio.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -176,7 +176,7 @@ qse_sio_t* qse_sio_open (
sio = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_sio_t) + xtnsize);
if (sio == QSE_NULL) return QSE_NULL;
if (qse_sio_init (sio, mmgr, file, flags) == QSE_NULL)
if (qse_sio_init (sio, mmgr, file, flags) <= -1)
{
QSE_MMGR_FREE (mmgr, sio);
return QSE_NULL;
@ -191,7 +191,7 @@ void qse_sio_close (qse_sio_t* sio)
QSE_MMGR_FREE (sio->mmgr, sio);
}
qse_sio_t* qse_sio_init (
int qse_sio_init (
qse_sio_t* sio, qse_mmgr_t* mmgr, const qse_char_t* file, int flags)
{
int mode;
@ -204,26 +204,23 @@ qse_sio_t* qse_sio_init (
mode = QSE_FIO_RUSR | QSE_FIO_WUSR |
QSE_FIO_RGRP | QSE_FIO_ROTH;
if (qse_fio_init (&sio->fio, mmgr, file, flags, mode) == QSE_NULL)
{
return QSE_NULL;
}
if (qse_fio_init (&sio->fio, mmgr, file, flags, mode) <= -1) return -1;
if (qse_tio_init(&sio->tio, mmgr) == QSE_NULL)
if (qse_tio_init(&sio->tio, mmgr) <= -1)
{
qse_fio_fini (&sio->fio);
return QSE_NULL;
return -1;
}
if (qse_tio_attachin(&sio->tio, __sio_input, sio) == -1 ||
qse_tio_attachout(&sio->tio, __sio_output, sio) == -1)
if (qse_tio_attachin(&sio->tio, __sio_input, sio) <= -1 ||
qse_tio_attachout(&sio->tio, __sio_output, sio) <= -1)
{
qse_tio_fini (&sio->tio);
qse_fio_fini (&sio->fio);
return QSE_NULL;
return -1;
}
return sio;
return 0;
}
void qse_sio_fini (qse_sio_t* sio)

View File

@ -1,5 +1,5 @@
/*
* $Id: sll.c 441 2011-04-22 14:28:43Z hyunghwan.chung $
* $Id: sll.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -117,7 +117,7 @@ sll_t* qse_sll_open (mmgr_t* mmgr, size_t ext)
sll = QSE_MMGR_ALLOC (mmgr, SIZEOF(sll_t) + ext);
if (sll == QSE_NULL) return QSE_NULL;
if (qse_sll_init (sll, mmgr) == QSE_NULL)
if (qse_sll_init (sll, mmgr) <= -1)
{
QSE_MMGR_FREE (mmgr, sll);
return QSE_NULL;
@ -132,7 +132,7 @@ void qse_sll_close (sll_t* sll)
QSE_MMGR_FREE (sll->mmgr, sll);
}
sll_t* qse_sll_init (sll_t* sll, mmgr_t* mmgr)
int qse_sll_init (sll_t* sll, mmgr_t* mmgr)
{
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
@ -145,7 +145,7 @@ sll_t* qse_sll_init (sll_t* sll, mmgr_t* mmgr)
sll->comper = default_comper;
sll->copier = QSE_SLL_COPIER_SIMPLE;
return sll;
return 0;
}
void qse_sll_fini (sll_t* sll)

View File

@ -1,5 +1,5 @@
/*
* $Id: str_beg.c 550 2011-08-14 15:59:55Z hyunghwan.chung $
* $Id: str-beg.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: str_cat.c 443 2011-04-25 14:56:05Z hyunghwan.chung $
* $Id: str-cat.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: str_chr.c 443 2011-04-25 14:56:05Z hyunghwan.chung $
* $Id: str-chr.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: str_cmp.c 443 2011-04-25 14:56:05Z hyunghwan.chung $
* $Id: str-cmp.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -116,6 +116,20 @@ int qse_mbsxncasecmp (
return (s2 < end2)? -1: 0;
}
int qse_mbszcmp (const qse_mchar_t* s1, const qse_mchar_t* s2, qse_size_t n)
{
if (n == 0) return 0;
while (*s1 == *s2)
{
if (*s1 == QSE_MT('\0') || n == 1) return 0;
s1++, s2++, n--;
}
return (*s1 > *s2)? 1: -1;
}
int qse_wcscmp (const qse_wchar_t* s1, const qse_wchar_t* s2)
{
while (*s1 == *s2)
@ -210,3 +224,16 @@ int qse_wcsxncasecmp (
return (s2 < end2)? -1: 0;
}
int qse_wcszcmp (const qse_wchar_t* s1, const qse_wchar_t* s2, qse_size_t n)
{
if (n == 0) return 0;
while (*s1 == *s2)
{
if (*s1 == QSE_WT('\0') || n == 1) return 0;
s1++, s2++, n--;
}
return (*s1 > *s2)? 1: -1;
}

View File

@ -1,5 +1,5 @@
/*
* $Id: str_cnv.c 554 2011-08-22 05:26:26Z hyunghwan.chung $
* $Id: str-cnv.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -197,12 +197,12 @@ qse_size_t qse_mbstowcs (
return 0; /* 0 byte processed */
}
for (mp = mbs; *mp != '\0'; mp++);
for (mp = mbs; *mp != QSE_MT('\0'); mp++);
mlen = qse_mbsntowcsn (mbs, mp - mbs, wcs, &wlen);
if (wlen < *wcslen)
{
/* null-terminate wcs if it is large enough. */
wcs[wlen] = L'\0';
wcs[wlen] = QSE_WT('\0');
}
/* if null-terminated properly, the input wcslen must be less than

View File

@ -1,5 +1,5 @@
/*
* $Id: str_cpy.c 443 2011-04-25 14:56:05Z hyunghwan.chung $
* $Id: str-cpy.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: str_del.c 443 2011-04-25 14:56:05Z hyunghwan.chung $
* $Id: str-del.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: str_dup.c 499 2011-06-22 16:17:35Z hyunghwan.chung $
* $Id: str-dup.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: str_dynm.c 502 2011-07-06 16:44:10Z hyunghwan.chung $
* $Id: str-dynm.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -40,7 +40,7 @@ qse_mbs_t* qse_mbs_open (qse_mmgr_t* mmgr, qse_size_t ext, qse_size_t capa)
str = (qse_mbs_t*) QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_mbs_t) + ext);
if (str == QSE_NULL) return QSE_NULL;
if (qse_mbs_init (str, mmgr, capa) == QSE_NULL)
if (qse_mbs_init (str, mmgr, capa) <= -1)
{
QSE_MMGR_FREE (mmgr, str);
return QSE_NULL;
@ -55,7 +55,7 @@ void qse_mbs_close (qse_mbs_t* str)
QSE_MMGR_FREE (str->mmgr, str);
}
qse_mbs_t* qse_mbs_init (qse_mbs_t* str, qse_mmgr_t* mmgr, qse_size_t capa)
int qse_mbs_init (qse_mbs_t* str, qse_mmgr_t* mmgr, qse_size_t capa)
{
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
@ -69,14 +69,14 @@ qse_mbs_t* qse_mbs_init (qse_mbs_t* str, qse_mmgr_t* mmgr, qse_size_t capa)
{
str->val.ptr = (qse_mchar_t*) QSE_MMGR_ALLOC (
mmgr, QSE_SIZEOF(qse_mchar_t) * (capa + 1));
if (str->val.ptr == QSE_NULL) return QSE_NULL;
if (str->val.ptr == QSE_NULL) return -1;
str->val.ptr[0] = QSE_MT('\0');
}
str->val.len = 0;
str->capa = capa;
return str;
return 0;
}
void qse_mbs_fini (qse_mbs_t* str)

View File

@ -1,5 +1,5 @@
/*
* $Id: str_dynw.c 502 2011-07-06 16:44:10Z hyunghwan.chung $
* $Id: str-dynw.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -40,7 +40,7 @@ qse_wcs_t* qse_wcs_open (qse_mmgr_t* mmgr, qse_size_t ext, qse_size_t capa)
str = (qse_wcs_t*) QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_wcs_t) + ext);
if (str == QSE_NULL) return QSE_NULL;
if (qse_wcs_init (str, mmgr, capa) == QSE_NULL)
if (qse_wcs_init (str, mmgr, capa) <= -1)
{
QSE_MMGR_FREE (mmgr, str);
return QSE_NULL;
@ -55,7 +55,7 @@ void qse_wcs_close (qse_wcs_t* str)
QSE_MMGR_FREE (str->mmgr, str);
}
qse_wcs_t* qse_wcs_init (qse_wcs_t* str, qse_mmgr_t* mmgr, qse_size_t capa)
int qse_wcs_init (qse_wcs_t* str, qse_mmgr_t* mmgr, qse_size_t capa)
{
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
@ -69,14 +69,14 @@ qse_wcs_t* qse_wcs_init (qse_wcs_t* str, qse_mmgr_t* mmgr, qse_size_t capa)
{
str->val.ptr = (qse_wchar_t*) QSE_MMGR_ALLOC (
mmgr, QSE_SIZEOF(qse_wchar_t) * (capa + 1));
if (str->val.ptr == QSE_NULL) return QSE_NULL;
if (str->val.ptr == QSE_NULL) return -1;
str->val.ptr[0] = QSE_WT('\0');
}
str->val.len = 0;
str->capa = capa;
return str;
return 0;
}
void qse_wcs_fini (qse_wcs_t* str)

View File

@ -1,5 +1,5 @@
/*
* $Id: str_end.c 443 2011-04-25 14:56:05Z hyunghwan.chung $
* $Id: str-end.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: str_excl.c 443 2011-04-25 14:56:05Z hyunghwan.chung $
* $Id: str-excl.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: str_fcpy.c 443 2011-04-25 14:56:05Z hyunghwan.chung $
* $Id: str-fcpy.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: str_incl.c 443 2011-04-25 14:56:05Z hyunghwan.chung $
* $Id: str-incl.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: str_len.c 443 2011-04-25 14:56:05Z hyunghwan.chung $
* $Id: str-len.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: str_pac.c 443 2011-04-25 14:56:05Z hyunghwan.chung $
* $Id: str-pac.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: str_pbrk.c 443 2011-04-25 14:56:05Z hyunghwan.chung $
* $Id: str-pbrk.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: str_put.c 443 2011-04-25 14:56:05Z hyunghwan.chung $
* $Id: str-put.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: str_rev.c 443 2011-04-25 14:56:05Z hyunghwan.chung $
* $Id: str-rev.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: str_rot.c 443 2011-04-25 14:56:05Z hyunghwan.chung $
* $Id: str-rot.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: str_set.c 443 2011-04-25 14:56:05Z hyunghwan.chung $
* $Id: str-set.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: str_spl.c 443 2011-04-25 14:56:05Z hyunghwan.chung $
* $Id: str-spl.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: str_spn.c 443 2011-04-25 14:56:05Z hyunghwan.chung $
* $Id: str-spn.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: str_str.c 443 2011-04-25 14:56:05Z hyunghwan.chung $
* $Id: str-str.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: str_subst.c 443 2011-04-25 14:56:05Z hyunghwan.chung $
* $Id: str-subst.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: str_tok.c 443 2011-04-25 14:56:05Z hyunghwan.chung $
* $Id: str-tok.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: str_trm.c 443 2011-04-25 14:56:05Z hyunghwan.chung $
* $Id: str-trm.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: str_word.c 443 2011-04-25 14:56:05Z hyunghwan.chung $
* $Id: str-word.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: tio_get.c 554 2011-08-22 05:26:26Z hyunghwan.chung $
* $Id: tio-get.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: tio_put.c 554 2011-08-22 05:26:26Z hyunghwan.chung $
* $Id: tio-put.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.

View File

@ -1,5 +1,5 @@
/*
* $Id: tio.c 441 2011-04-22 14:28:43Z hyunghwan.chung $
* $Id: tio.c 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -23,7 +23,7 @@
QSE_IMPLEMENT_COMMON_FUNCTIONS (tio)
qse_tio_t* qse_tio_open (qse_mmgr_t* mmgr, qse_size_t ext)
qse_tio_t* qse_tio_open (qse_mmgr_t* mmgr, qse_size_t xtnsize)
{
qse_tio_t* tio;
@ -37,10 +37,10 @@ qse_tio_t* qse_tio_open (qse_mmgr_t* mmgr, qse_size_t ext)
if (mmgr == QSE_NULL) return QSE_NULL;
}
tio = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_tio_t) + ext);
tio = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_tio_t) + xtnsize);
if (tio == QSE_NULL) return QSE_NULL;
if (qse_tio_init (tio, mmgr) == QSE_NULL)
if (qse_tio_init (tio, mmgr) <= -1)
{
QSE_MMGR_FREE (mmgr, tio);
return QSE_NULL;
@ -56,7 +56,7 @@ int qse_tio_close (qse_tio_t* tio)
return n;
}
qse_tio_t* qse_tio_init (qse_tio_t* tio, qse_mmgr_t* mmgr)
int qse_tio_init (qse_tio_t* tio, qse_mmgr_t* mmgr)
{
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
@ -70,15 +70,15 @@ qse_tio_t* qse_tio_init (qse_tio_t* tio, qse_mmgr_t* mmgr)
tio->output_func = QSE_NULL;
tio->output_arg = QSE_NULL;
tio->input_status = 0;
tio->inbuf_curp = 0;
tio->inbuf_len = 0;
tio->outbuf_len = 0;
tio->input_status = 0;
tio->inbuf_curp = 0;
tio->inbuf_len = 0;
tio->outbuf_len = 0;
*/
tio->errnum = QSE_TIO_ENOERR;
return tio;
return 0;
}
int qse_tio_fini (qse_tio_t* tio)
@ -135,9 +135,9 @@ int qse_tio_attachin (qse_tio_t* tio, qse_tio_io_t input, void* arg)
tio->input_func = input;
tio->input_arg = arg;
tio->input_status = 0;
tio->inbuf_curp = 0;
tio->inbuf_len = 0;
tio->input_status = 0;
tio->inbuf_curp = 0;
tio->inbuf_len = 0;
return 0;
}

267
qse/lib/cmn/tre-ast.c Normal file
View File

@ -0,0 +1,267 @@
/*
* $Id$
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
QSE is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
QSE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
*/
/*
tre-ast.c - Abstract syntax tree (AST) routines
This is the license, copyright notice, and disclaimer for TRE, a regex
matching package (library and tools) with support for approximate
matching.
Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "tre-ast.h"
tre_ast_node_t *
tre_ast_new_node(tre_mem_t mem, tre_ast_type_t type, size_t size)
{
tre_ast_node_t *node;
node = tre_mem_calloc(mem, sizeof(*node));
if (!node)
return NULL;
node->obj = tre_mem_calloc(mem, size);
if (!node->obj)
return NULL;
node->type = type;
node->nullable = -1;
node->submatch_id = -1;
return node;
}
tre_ast_node_t *
tre_ast_new_literal(tre_mem_t mem, int code_min, int code_max, int position)
{
tre_ast_node_t *node;
tre_literal_t *lit;
node = tre_ast_new_node(mem, LITERAL, sizeof(tre_literal_t));
if (!node)
return NULL;
lit = node->obj;
lit->code_min = code_min;
lit->code_max = code_max;
lit->position = position;
return node;
}
tre_ast_node_t *
tre_ast_new_iter(tre_mem_t mem, tre_ast_node_t *arg, int min, int max,
int minimal)
{
tre_ast_node_t *node;
tre_iteration_t *iter;
node = tre_ast_new_node(mem, ITERATION, sizeof(tre_iteration_t));
if (!node)
return NULL;
iter = node->obj;
iter->arg = arg;
iter->min = min;
iter->max = max;
iter->minimal = minimal;
node->num_submatches = arg->num_submatches;
return node;
}
tre_ast_node_t *
tre_ast_new_union(tre_mem_t mem, tre_ast_node_t *left, tre_ast_node_t *right)
{
tre_ast_node_t *node;
node = tre_ast_new_node(mem, UNION, sizeof(tre_union_t));
if (node == NULL)
return NULL;
((tre_union_t *)node->obj)->left = left;
((tre_union_t *)node->obj)->right = right;
node->num_submatches = left->num_submatches + right->num_submatches;
return node;
}
tre_ast_node_t *
tre_ast_new_catenation(tre_mem_t mem, tre_ast_node_t *left,
tre_ast_node_t *right)
{
tre_ast_node_t *node;
node = tre_ast_new_node(mem, CATENATION, sizeof(tre_catenation_t));
if (node == NULL)
return NULL;
((tre_catenation_t *)node->obj)->left = left;
((tre_catenation_t *)node->obj)->right = right;
node->num_submatches = left->num_submatches + right->num_submatches;
return node;
}
#ifdef TRE_DEBUG
static void
tre_findent(FILE *stream, int i)
{
while (i-- > 0)
fputc(' ', stream);
}
void
tre_print_params(int *params)
{
int i;
if (params)
{
DPRINT(("params ["));
for (i = 0; i < TRE_PARAM_LAST; i++)
{
if (params[i] == TRE_PARAM_UNSET)
DPRINT(("unset"));
else if (params[i] == TRE_PARAM_DEFAULT)
DPRINT(("default"));
else
DPRINT(("%d", params[i]));
if (i < TRE_PARAM_LAST - 1)
DPRINT((", "));
}
DPRINT(("]"));
}
}
static void
tre_do_print(FILE *stream, tre_ast_node_t *ast, int indent)
{
int code_min, code_max, pos;
int num_tags = ast->num_tags;
tre_literal_t *lit;
tre_iteration_t *iter;
tre_findent(stream, indent);
switch (ast->type)
{
case LITERAL:
lit = ast->obj;
code_min = lit->code_min;
code_max = lit->code_max;
pos = lit->position;
if (IS_EMPTY(lit))
{
fprintf(stream, "literal empty\n");
}
else if (IS_ASSERTION(lit))
{
int i;
char *assertions[] = { "bol", "eol", "ctype", "!ctype",
"bow", "eow", "wb", "!wb"
};
if (code_max >= ASSERT_LAST << 1)
assert(0);
fprintf(stream, "assertions: ");
for (i = 0; (1 << i) <= ASSERT_LAST; i++)
if (code_max & (1 << i))
fprintf(stream, "%s ", assertions[i]);
fprintf(stream, "\n");
}
else if (IS_TAG(lit))
{
fprintf(stream, "tag %d\n", code_max);
}
else if (IS_BACKREF(lit))
{
fprintf(stream, "backref %d, pos %d\n", code_max, pos);
}
else if (IS_PARAMETER(lit))
{
tre_print_params(lit->u.params);
fprintf(stream, "\n");
}
else
{
fprintf(stream, "literal (%c, %c) (%d, %d), pos %d, sub %d, "
"%d tags\n", code_min, code_max, code_min, code_max, pos,
ast->submatch_id, num_tags);
}
break;
case ITERATION:
iter = ast->obj;
fprintf(stream, "iteration {%d, %d}, sub %d, %d tags, %s\n",
iter->min, iter->max, ast->submatch_id, num_tags,
iter->minimal ? "minimal" : "greedy");
tre_do_print(stream, iter->arg, indent + 2);
break;
case UNION:
fprintf(stream, "union, sub %d, %d tags\n", ast->submatch_id, num_tags);
tre_do_print(stream, ((tre_union_t *)ast->obj)->left, indent + 2);
tre_do_print(stream, ((tre_union_t *)ast->obj)->right, indent + 2);
break;
case CATENATION:
fprintf(stream, "catenation, sub %d, %d tags\n", ast->submatch_id,
num_tags);
tre_do_print(stream, ((tre_catenation_t *)ast->obj)->left, indent + 2);
tre_do_print(stream, ((tre_catenation_t *)ast->obj)->right, indent + 2);
break;
default:
assert(0);
break;
}
}
static void
tre_ast_fprint(FILE *stream, tre_ast_node_t *ast)
{
tre_do_print(stream, ast, 0);
}
void
tre_ast_print(tre_ast_node_t *tree)
{
printf("AST:\n");
tre_ast_fprint(stdout, tree);
}
#endif /* TRE_DEBUG */
/* EOF */

170
qse/lib/cmn/tre-ast.h Normal file
View File

@ -0,0 +1,170 @@
/*
* $Id$
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
QSE is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
QSE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
*/
/*
tre-ast.h - Abstract syntax tree (AST) definitions
This is the license, copyright notice, and disclaimer for TRE, a regex
matching package (library and tools) with support for approximate
matching.
Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _QSE_LIB_CMN_TRE_AST_H_
#define _QSE_LIB_CMN_TRE_AST_H_
#include "tre.h"
#include "tre-compile.h"
/* The different AST node types. */
typedef enum
{
LITERAL,
CATENATION,
ITERATION,
UNION
} tre_ast_type_t;
/* Special subtypes of TRE_LITERAL. */
#define EMPTY -1 /* Empty leaf (denotes empty string). */
#define ASSERTION -2 /* Assertion leaf. */
#define TAG -3 /* Tag leaf. */
#define BACKREF -4 /* Back reference leaf. */
#define PARAMETER -5 /* Parameter. */
#define IS_SPECIAL(x) ((x)->code_min < 0)
#define IS_EMPTY(x) ((x)->code_min == EMPTY)
#define IS_ASSERTION(x) ((x)->code_min == ASSERTION)
#define IS_TAG(x) ((x)->code_min == TAG)
#define IS_BACKREF(x) ((x)->code_min == BACKREF)
#define IS_PARAMETER(x) ((x)->code_min == PARAMETER)
/* A generic AST node. All AST nodes consist of this node on the top
level with `obj' pointing to the actual content. */
typedef struct
{
tre_ast_type_t type; /* Type of the node. */
void *obj; /* Pointer to actual node. */
int nullable;
int submatch_id;
int num_submatches;
int num_tags;
tre_pos_and_tags_t *firstpos;
tre_pos_and_tags_t *lastpos;
} tre_ast_node_t;
/* A "literal" node. These are created for assertions, back references,
tags, matching parameter settings, and all expressions that match one
character. */
typedef struct
{
long code_min;
long code_max;
int position;
union
{
tre_ctype_t class;
int *params;
} u;
tre_ctype_t *neg_classes;
} tre_literal_t;
/* A "catenation" node. These are created when two regexps are concatenated.
If there are more than one subexpressions in sequence, the `left' part
holds all but the last, and `right' part holds the last subexpression
(catenation is left associative). */
typedef struct
{
tre_ast_node_t *left;
tre_ast_node_t *right;
} tre_catenation_t;
/* An "iteration" node. These are created for the "*", "+", "?", and "{m,n}"
operators. */
typedef struct
{
/* Subexpression to match. */
tre_ast_node_t *arg;
/* Minimum number of consecutive matches. */
int min;
/* Maximum number of consecutive matches. */
int max;
/* If 0, match as many characters as possible, if 1 match as few as
possible. Note that this does not always mean the same thing as
matching as many/few repetitions as possible. */
unsigned int minimal:1;
/* Approximate matching parameters (or NULL). */
int *params;
} tre_iteration_t;
/* An "union" node. These are created for the "|" operator. */
typedef struct
{
tre_ast_node_t *left;
tre_ast_node_t *right;
} tre_union_t;
tre_ast_node_t* tre_ast_new_node(tre_mem_t mem, tre_ast_type_t type, size_t size);
tre_ast_node_t* tre_ast_new_literal(tre_mem_t mem, int code_min, int code_max, int position);
tre_ast_node_t* tre_ast_new_iter(tre_mem_t mem, tre_ast_node_t *arg, int min, int max, int minimal);
tre_ast_node_t* tre_ast_new_union(tre_mem_t mem, tre_ast_node_t *left, tre_ast_node_t *right);
tre_ast_node_t* tre_ast_new_catenation(tre_mem_t mem, tre_ast_node_t *left, tre_ast_node_t *right);
#ifdef TRE_DEBUG
void tre_ast_print(tre_ast_node_t *tree);
/* XXX - rethink AST printing API */
void tre_print_params(int *params);
#endif /* TRE_DEBUG */
#endif /* TRE_AST_H */
/* EOF */

2276
qse/lib/cmn/tre-compile.c Normal file

File diff suppressed because it is too large Load Diff

75
qse/lib/cmn/tre-compile.h Normal file
View File

@ -0,0 +1,75 @@
/*
* $Id$
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
QSE is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
QSE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
*/
/*
tre-compile.h: Regex compilation definitions
This is the license, copyright notice, and disclaimer for TRE, a regex
matching package (library and tools) with support for approximate
matching.
Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _QSE_LIB_CMN_TRE_COMPILE_H_
#define _QSE_LIB_CMN_TRE_COMPILE_H_
typedef struct
{
int position;
int code_min;
int code_max;
int *tags;
int assertions;
tre_ctype_t class;
tre_ctype_t *neg_classes;
int backref;
int *params;
} tre_pos_and_tags_t;
#endif /* TRE_COMPILE_H */
/* EOF */

View File

@ -0,0 +1,658 @@
/*
* $Id$
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
QSE is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
QSE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
*/
/*
tre-match-backtrack.c - TRE backtracking regex matching engine
This is the license, copyright notice, and disclaimer for TRE, a regex
matching package (library and tools) with support for approximate
matching.
Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
This matcher is for regexps that use back referencing. Regexp matching
with back referencing is an NP-complete problem on the number of back
references. The easiest way to match them is to use a backtracking
routine which basically goes through all possible paths in the TNFA
and chooses the one which results in the best (leftmost and longest)
match. This can be spectacularly expensive and may run out of stack
space, but there really is no better known generic algorithm. Quoting
Henry Spencer from comp.compilers:
<URL: http://compilers.iecc.com/comparch/article/93-03-102>
POSIX.2 REs require longest match, which is really exciting to
implement since the obsolete ("basic") variant also includes
\<digit>. I haven't found a better way of tackling this than doing
a preliminary match using a DFA (or simulation) on a modified RE
that just replicates subREs for \<digit>, and then doing a
backtracking match to determine whether the subRE matches were
right. This can be rather slow, but I console myself with the
thought that people who use \<digit> deserve very slow execution.
(Pun unintentional but very appropriate.)
*/
#include "tre.h"
#include "tre-match-utils.h"
typedef struct
{
int pos;
const char *str_byte;
#ifdef TRE_WCHAR
const qse_wchar_t *str_wide;
#endif /* TRE_WCHAR */
tre_tnfa_transition_t *state;
int state_id;
int next_c;
int *tags;
#ifdef TRE_MBSTATE
qse_mbstate_t mbstate;
#endif /* TRE_MBSTATE */
} tre_backtrack_item_t;
typedef struct tre_backtrack_struct
{
tre_backtrack_item_t item;
struct tre_backtrack_struct *prev;
struct tre_backtrack_struct *next;
} *tre_backtrack_t;
#ifdef TRE_WCHAR
#define BT_STACK_WIDE_IN(_str_wide) stack->item.str_wide = (_str_wide)
#define BT_STACK_WIDE_OUT (str_wide) = stack->item.str_wide
#else /* !TRE_WCHAR */
#define BT_STACK_WIDE_IN(_str_wide)
#define BT_STACK_WIDE_OUT
#endif /* !TRE_WCHAR */
#ifdef TRE_MBSTATE
#define BT_STACK_MBSTATE_IN stack->item.mbstate = (mbstate)
#define BT_STACK_MBSTATE_OUT (mbstate) = stack->item.mbstate
#else /* !TRE_MBSTATE */
#define BT_STACK_MBSTATE_IN
#define BT_STACK_MBSTATE_OUT
#endif /* !TRE_MBSTATE */
#define tre_bt_mem_new tre_mem_new
#define tre_bt_mem_alloc tre_mem_alloc
#define tre_bt_mem_destroy tre_mem_destroy
#define BT_STACK_PUSH(_mmgr, _pos, _str_byte, _str_wide, _state, _state_id, _next_c, _tags, _mbstate) \
do \
{ \
int i; \
if (!stack->next) \
{ \
tre_backtrack_t s; \
s = tre_bt_mem_alloc(mem, sizeof(*s)); \
if (!s) \
{ \
tre_bt_mem_destroy(mem); \
if (tags) \
xfree(_mmgr,tags); \
if (pmatch) \
xfree(_mmgr,pmatch); \
if (states_seen) \
xfree(_mmgr,states_seen); \
return REG_ESPACE; \
} \
s->prev = stack; \
s->next = NULL; \
s->item.tags = tre_bt_mem_alloc(mem, \
sizeof(*tags) * tnfa->num_tags); \
if (!s->item.tags) \
{ \
tre_bt_mem_destroy(mem); \
if (tags) \
xfree(_mmgr,tags); \
if (pmatch) \
xfree(_mmgr,pmatch); \
if (states_seen) \
xfree(_mmgr,states_seen); \
return REG_ESPACE; \
} \
stack->next = s; \
stack = s; \
} \
else \
stack = stack->next; \
stack->item.pos = (_pos); \
stack->item.str_byte = (_str_byte); \
BT_STACK_WIDE_IN(_str_wide); \
stack->item.state = (_state); \
stack->item.state_id = (_state_id); \
stack->item.next_c = (_next_c); \
for (i = 0; i < tnfa->num_tags; i++) \
stack->item.tags[i] = (_tags)[i]; \
BT_STACK_MBSTATE_IN; \
} \
while (/*CONSTCOND*/0)
#define BT_STACK_POP() \
do \
{ \
int i; \
assert(stack->prev); \
pos = stack->item.pos; \
if (type == STR_USER) \
str_source->rewind(pos + pos_add_next, str_source->context); \
str_byte = stack->item.str_byte; \
BT_STACK_WIDE_OUT; \
state = stack->item.state; \
next_c = stack->item.next_c; \
for (i = 0; i < tnfa->num_tags; i++) \
tags[i] = stack->item.tags[i]; \
BT_STACK_MBSTATE_OUT; \
stack = stack->prev; \
} \
while (/*CONSTCOND*/0)
#undef MIN
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
reg_errcode_t
tre_tnfa_run_backtrack(qse_mmgr_t* mmgr, const tre_tnfa_t *tnfa, const void *string,
int len, tre_str_type_t type, int *match_tags,
int eflags, int *match_end_ofs)
{
/* State variables required by GET_NEXT_WCHAR. */
tre_char_t prev_c = 0, next_c = 0;
const char *str_byte = string;
int pos = 0;
unsigned int pos_add_next = 1;
#ifdef TRE_WCHAR
const qse_wchar_t *str_wide = string;
#ifdef TRE_MBSTATE
qse_mbstate_t mbstate;
#endif /* TRE_MBSTATE */
#endif /* TRE_WCHAR */
int reg_notbol = eflags & REG_NOTBOL;
int reg_noteol = eflags & REG_NOTEOL;
int reg_newline = tnfa->cflags & REG_NEWLINE;
int str_user_end = 0;
/* These are used to remember the necessary values of the above
variables to return to the position where the current search
started from. */
int next_c_start;
const char *str_byte_start;
int pos_start = -1;
#ifdef TRE_WCHAR
const qse_wchar_t *str_wide_start;
#endif /* TRE_WCHAR */
#ifdef TRE_MBSTATE
qse_mbstate_t mbstate_start;
#endif /* TRE_MBSTATE */
/* End offset of best match so far, or -1 if no match found yet. */
int match_eo = -1;
/* Tag arrays. */
int *next_tags, *tags = NULL;
/* Current TNFA state. */
tre_tnfa_transition_t *state;
int *states_seen = NULL;
/* Memory allocator to for allocating the backtracking stack. */
tre_mem_t mem = tre_bt_mem_new(mmgr);
/* The backtracking stack. */
tre_backtrack_t stack;
tre_tnfa_transition_t *trans_i;
regmatch_t *pmatch = NULL;
int ret;
#ifdef TRE_MBSTATE
QSE_MEMSET(&mbstate, '\0', sizeof(mbstate));
#endif /* TRE_MBSTATE */
if (!mem)
return REG_ESPACE;
stack = tre_bt_mem_alloc(mem, sizeof(*stack));
if (!stack)
{
ret = REG_ESPACE;
goto error_exit;
}
stack->prev = NULL;
stack->next = NULL;
DPRINT(("tnfa_execute_backtrack, input type %d\n", type));
DPRINT(("len = %d\n", len));
if (tnfa->num_tags)
{
tags = xmalloc(mmgr,sizeof(*tags) * tnfa->num_tags);
if (!tags)
{
ret = REG_ESPACE;
goto error_exit;
}
}
if (tnfa->num_submatches)
{
pmatch = xmalloc(mmgr,sizeof(*pmatch) * tnfa->num_submatches);
if (!pmatch)
{
ret = REG_ESPACE;
goto error_exit;
}
}
if (tnfa->num_states)
{
states_seen = xmalloc(mmgr,sizeof(*states_seen) * tnfa->num_states);
if (!states_seen)
{
ret = REG_ESPACE;
goto error_exit;
}
}
retry:
{
int i;
for (i = 0; i < tnfa->num_tags; i++)
{
tags[i] = -1;
if (match_tags)
match_tags[i] = -1;
}
for (i = 0; i < tnfa->num_states; i++)
states_seen[i] = 0;
}
state = NULL;
pos = pos_start;
if (type == STR_USER)
str_source->rewind(pos + pos_add_next, str_source->context);
GET_NEXT_WCHAR();
pos_start = pos;
next_c_start = next_c;
str_byte_start = str_byte;
#ifdef TRE_WCHAR
str_wide_start = str_wide;
#endif /* TRE_WCHAR */
#ifdef TRE_MBSTATE
mbstate_start = mbstate;
#endif /* TRE_MBSTATE */
/* Handle initial states. */
next_tags = NULL;
for (trans_i = tnfa->initial; trans_i->state; trans_i++)
{
DPRINT(("> init %p, prev_c %lc\n", trans_i->state, (tre_cint_t)prev_c));
if (trans_i->assertions && CHECK_ASSERTIONS(trans_i->assertions))
{
DPRINT(("assert failed\n"));
continue;
}
if (state == NULL)
{
/* Start from this state. */
state = trans_i->state;
next_tags = trans_i->tags;
}
else
{
/* Backtrack to this state. */
DPRINT(("saving state %d for backtracking\n", trans_i->state_id));
BT_STACK_PUSH(mmgr, pos, str_byte, str_wide, trans_i->state,
trans_i->state_id, next_c, tags, mbstate);
{
int *tmp = trans_i->tags;
if (tmp)
while (*tmp >= 0)
stack->item.tags[*tmp++] = pos;
}
}
}
if (next_tags)
for (; *next_tags >= 0; next_tags++)
tags[*next_tags] = pos;
DPRINT(("entering match loop, pos %d, str_byte %p\n", pos, str_byte));
DPRINT(("pos:chr/code | state and tags\n"));
DPRINT(("-------------+------------------------------------------------\n"));
if (state == NULL)
goto backtrack;
while (/*CONSTCOND*/1)
{
tre_tnfa_transition_t *next_state;
int empty_br_match;
DPRINT(("start loop\n"));
if (state == tnfa->final)
{
DPRINT((" match found, %d %d\n", match_eo, pos));
if (match_eo < pos
|| (match_eo == pos
&& match_tags
&& tre_tag_order(tnfa->num_tags, tnfa->tag_directions,
tags, match_tags)))
{
int i;
/* This match wins the previous match. */
DPRINT((" win previous\n"));
match_eo = pos;
if (match_tags)
for (i = 0; i < tnfa->num_tags; i++)
match_tags[i] = tags[i];
}
/* Our TNFAs never have transitions leaving from the final state,
so we jump right to backtracking. */
goto backtrack;
}
#ifdef TRE_DEBUG
DPRINT(("%3d:%2lc/%05d | %p ", pos, (tre_cint_t)next_c, (int)next_c,
state));
{
int i;
for (i = 0; i < tnfa->num_tags; i++)
DPRINT(("%d%s", tags[i], i < tnfa->num_tags - 1 ? ", " : ""));
DPRINT(("\n"));
}
#endif /* TRE_DEBUG */
/* Go to the next character in the input string. */
empty_br_match = 0;
trans_i = state;
if (trans_i->state && trans_i->assertions & ASSERT_BACKREF)
{
/* This is a back reference state. All transitions leaving from
this state have the same back reference "assertion". Instead
of reading the next character, we match the back reference. */
int so, eo, bt = trans_i->u.backref;
int bt_len;
int result;
DPRINT((" should match back reference %d\n", bt));
/* Get the substring we need to match against. Remember to
turn off REG_NOSUB temporarily. */
tre_fill_pmatch(bt + 1, pmatch, tnfa->cflags & /*LINTED*/!REG_NOSUB,
tnfa, tags, pos);
so = pmatch[bt].rm_so;
eo = pmatch[bt].rm_eo;
bt_len = eo - so;
#ifdef TRE_DEBUG
{
int slen;
if (len < 0)
slen = bt_len;
else
slen = MIN(bt_len, len - pos);
if (type == STR_BYTE)
{
DPRINT((" substring (len %d) is [%d, %d[: '%.*s'\n",
bt_len, so, eo, bt_len, (char*)string + so));
DPRINT((" current string is '%.*s'\n", slen, str_byte - 1));
}
#ifdef TRE_WCHAR
else if (type == STR_WIDE)
{
DPRINT((" substring (len %d) is [%d, %d[: '%.*" STRF "'\n",
bt_len, so, eo, bt_len, (qse_wchar_t*)string + so));
DPRINT((" current string is '%.*" STRF "'\n",
slen, str_wide - 1));
}
#endif /* TRE_WCHAR */
}
#endif
if (len < 0)
{
if (type == STR_USER)
result = str_source->compare((unsigned)so, (unsigned)pos,
(unsigned)bt_len,
str_source->context);
#ifdef TRE_WCHAR
else if (type == STR_WIDE)
result = qse_wcszcmp((const qse_wchar_t*)string + so, str_wide - 1, (size_t)bt_len);
#endif /* TRE_WCHAR */
else
result = qse_mbszcmp((const char*)string + so, str_byte - 1, (size_t)bt_len);
}
else if (len - pos < bt_len)
result = 1;
#ifdef TRE_WCHAR
else if (type == STR_WIDE)
{
/*result = wmemcmp((const qse_wchar_t*)string + so, str_wide - 1, (size_t)bt_len);*/
result = qse_wcsxncmp((const qse_wchar_t*)string + so, (size_t)bt_len, str_wide - 1, (size_t)bt_len);
}
#endif /* TRE_WCHAR */
else
{
/*result = memcmp((const char*)string + so, str_byte - 1, (size_t)bt_len); */
result = qse_mbsxncmp((const char*)string + so, (size_t)bt_len, str_byte - 1, (size_t)bt_len);
}
if (result == 0)
{
/* Back reference matched. Check for infinite loop. */
if (bt_len == 0)
empty_br_match = 1;
if (empty_br_match && states_seen[trans_i->state_id])
{
DPRINT((" avoid loop\n"));
goto backtrack;
}
states_seen[trans_i->state_id] = empty_br_match;
/* Advance in input string and resync `prev_c', `next_c'
and pos. */
DPRINT((" back reference matched\n"));
str_byte += bt_len - 1;
#ifdef TRE_WCHAR
str_wide += bt_len - 1;
#endif /* TRE_WCHAR */
pos += bt_len - 1;
GET_NEXT_WCHAR();
DPRINT((" pos now %d\n", pos));
}
else
{
DPRINT((" back reference did not match\n"));
goto backtrack;
}
}
else
{
/* Check for end of string. */
if (len < 0)
{
if (type == STR_USER)
{
if (str_user_end)
goto backtrack;
}
else if (next_c == QSE_T('\0'))
goto backtrack;
}
else
{
if (pos >= len)
goto backtrack;
}
/* Read the next character. */
GET_NEXT_WCHAR();
}
next_state = NULL;
for (trans_i = state; trans_i->state; trans_i++)
{
DPRINT((" transition %d-%d (%c-%c) %d to %d\n",
trans_i->code_min, trans_i->code_max,
trans_i->code_min, trans_i->code_max,
trans_i->assertions, trans_i->state_id));
if (trans_i->code_min <= (tre_cint_t)prev_c
&& trans_i->code_max >= (tre_cint_t)prev_c)
{
if (trans_i->assertions
&& (CHECK_ASSERTIONS(trans_i->assertions)
|| CHECK_CHAR_CLASSES(trans_i, tnfa, eflags)))
{
DPRINT((" assertion failed\n"));
continue;
}
if (next_state == NULL)
{
/* First matching transition. */
DPRINT((" Next state is %d\n", trans_i->state_id));
next_state = trans_i->state;
next_tags = trans_i->tags;
}
else
{
/* Second matching transition. We may need to backtrack here
to take this transition instead of the first one, so we
push this transition in the backtracking stack so we can
jump back here if needed. */
DPRINT((" saving state %d for backtracking\n",
trans_i->state_id));
BT_STACK_PUSH(mmgr, pos, str_byte, str_wide, trans_i->state,
trans_i->state_id, next_c, tags, mbstate);
{
int *tmp;
for (tmp = trans_i->tags; tmp && *tmp >= 0; tmp++)
stack->item.tags[*tmp] = pos;
}
#if 0 /* XXX - it's important not to look at all transitions here to keep
the stack small! */
break;
#endif
}
}
}
if (next_state != NULL)
{
/* Matching transitions were found. Take the first one. */
state = next_state;
/* Update the tag values. */
if (next_tags)
while (*next_tags >= 0)
tags[*next_tags++] = pos;
}
else
{
backtrack:
/* A matching transition was not found. Try to backtrack. */
if (stack->prev)
{
DPRINT((" backtracking\n"));
if (stack->item.state->assertions && ASSERT_BACKREF)
{
DPRINT((" states_seen[%d] = 0\n",
stack->item.state_id));
states_seen[stack->item.state_id] = 0;
}
BT_STACK_POP();
}
else if (match_eo < 0)
{
/* Try starting from a later position in the input string. */
/* Check for end of string. */
if (len < 0)
{
if (next_c == QSE_T('\0'))
{
DPRINT(("end of string.\n"));
break;
}
}
else
{
if (pos >= len)
{
DPRINT(("end of string.\n"));
break;
}
}
DPRINT(("restarting from next start position\n"));
next_c = next_c_start;
#ifdef TRE_MBSTATE
mbstate = mbstate_start;
#endif /* TRE_MBSTATE */
str_byte = str_byte_start;
#ifdef TRE_WCHAR
str_wide = str_wide_start;
#endif /* TRE_WCHAR */
goto retry;
}
else
{
DPRINT(("finished\n"));
break;
}
}
}
ret = match_eo >= 0 ? REG_OK : REG_NOMATCH;
*match_end_ofs = match_eo;
error_exit:
tre_bt_mem_destroy(mem);
if (tags) xfree(mmgr,tags);
if (pmatch) xfree(mmgr,pmatch);
if (states_seen) xfree(mmgr,states_seen);
return ret;
}

View File

@ -0,0 +1,496 @@
/*
* $Id$
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
QSE is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
QSE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
*/
/*
tre-match-parallel.c - TRE parallel regex matching engine
This is the license, copyright notice, and disclaimer for TRE, a regex
matching package (library and tools) with support for approximate
matching.
Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
This algorithm searches for matches basically by reading characters
in the searched string one by one, starting at the beginning. All
matching paths in the TNFA are traversed in parallel. When two or
more paths reach the same state, exactly one is chosen according to
tag ordering rules; if returning submatches is not required it does
not matter which path is chosen.
The worst case time required for finding the leftmost and longest
match, or determining that there is no match, is always linearly
dependent on the length of the text being searched.
This algorithm cannot handle TNFAs with back referencing nodes.
See `tre-match-backtrack.c'.
*/
#include "tre.h"
#include "tre-match-utils.h"
typedef struct
{
tre_tnfa_transition_t *state;
int *tags;
} tre_tnfa_reach_t;
typedef struct
{
int pos;
int **tags;
} tre_reach_pos_t;
#ifdef TRE_DEBUG
static void
tre_print_reach(const tre_tnfa_t *tnfa, tre_tnfa_reach_t *reach, int num_tags)
{
int i;
while (reach->state != NULL)
{
DPRINT((" %p", (void *)reach->state));
if (num_tags > 0)
{
DPRINT(("/"));
for (i = 0; i < num_tags; i++)
{
DPRINT(("%d:%d", i, reach->tags[i]));
if (i < (num_tags-1))
DPRINT((","));
}
}
reach++;
}
DPRINT(("\n"));
}
#endif /* TRE_DEBUG */
reg_errcode_t
tre_tnfa_run_parallel(qse_mmgr_t* mmgr, const tre_tnfa_t *tnfa, const void *string, int len,
tre_str_type_t type, int *match_tags, int eflags,
int *match_end_ofs)
{
/* State variables required by GET_NEXT_WCHAR. */
tre_char_t prev_c = 0, next_c = 0;
const char *str_byte = string;
int pos = -1;
unsigned int pos_add_next = 1;
#ifdef TRE_WCHAR
const qse_wchar_t *str_wide = string;
#ifdef TRE_MBSTATE
qse_mbstate_t mbstate;
#endif
#endif /* TRE_WCHAR */
int reg_notbol = eflags & REG_NOTBOL;
int reg_noteol = eflags & REG_NOTEOL;
int reg_newline = tnfa->cflags & REG_NEWLINE;
int str_user_end = 0;
char *buf;
tre_tnfa_transition_t *trans_i;
tre_tnfa_reach_t *reach, *reach_next, *reach_i, *reach_next_i;
tre_reach_pos_t *reach_pos;
int *tag_i;
int num_tags, i;
int match_eo = -1; /* end offset of match (-1 if no match found yet) */
int new_match = 0;
int *tmp_tags = NULL;
int *tmp_iptr;
#ifdef TRE_MBSTATE
QSE_MEMSET(&mbstate, '\0', sizeof(mbstate));
#endif /* TRE_MBSTATE */
DPRINT(("tre_tnfa_run_parallel, input type %d\n", type));
if (!match_tags)
num_tags = 0;
else
num_tags = tnfa->num_tags;
/* Allocate memory for temporary data required for matching. This needs to
be done for every matching operation to be thread safe. This allocates
everything in a single large block from the stack frame using alloca()
or with malloc() if alloca is unavailable. */
{
int tbytes, rbytes, pbytes, xbytes, total_bytes;
char *tmp_buf;
/* Compute the length of the block we need. */
tbytes = sizeof(*tmp_tags) * num_tags;
rbytes = sizeof(*reach_next) * (tnfa->num_states + 1);
pbytes = sizeof(*reach_pos) * tnfa->num_states;
xbytes = sizeof(int) * num_tags;
total_bytes =
(sizeof(long) - 1) * 4 /* for alignment paddings */
+ (rbytes + xbytes * tnfa->num_states) * 2 + tbytes + pbytes;
/* Allocate the memory. */
buf = xmalloc(mmgr, (unsigned)total_bytes);
if (buf == NULL) return REG_ESPACE;
QSE_MEMSET(buf, 0, (size_t)total_bytes);
/* Get the various pointers within tmp_buf (properly aligned). */
tmp_tags = (void *)buf;
tmp_buf = buf + tbytes;
tmp_buf += ALIGN(tmp_buf, long);
reach_next = (void *)tmp_buf;
tmp_buf += rbytes;
tmp_buf += ALIGN(tmp_buf, long);
reach = (void *)tmp_buf;
tmp_buf += rbytes;
tmp_buf += ALIGN(tmp_buf, long);
reach_pos = (void *)tmp_buf;
tmp_buf += pbytes;
tmp_buf += ALIGN(tmp_buf, long);
for (i = 0; i < tnfa->num_states; i++)
{
reach[i].tags = (void *)tmp_buf;
tmp_buf += xbytes;
reach_next[i].tags = (void *)tmp_buf;
tmp_buf += xbytes;
}
}
for (i = 0; i < tnfa->num_states; i++)
reach_pos[i].pos = -1;
/* If only one character can start a match, find it first. */
if (tnfa->first_char >= 0 && type == STR_BYTE && str_byte)
{
const char *orig_str = str_byte;
int first = tnfa->first_char;
if (len >= 0)
str_byte = QSE_MEMBYTE(orig_str, first, (size_t)len);
else
str_byte = qse_mbschr(orig_str, first);
if (str_byte == NULL)
{
if (buf) xfree(mmgr, buf);
return REG_NOMATCH;
}
DPRINT(("skipped %lu chars\n", (unsigned long)(str_byte - orig_str)));
if (str_byte >= orig_str + 1)
prev_c = (unsigned char)*(str_byte - 1);
next_c = (unsigned char)*str_byte;
pos = str_byte - orig_str;
if (len < 0 || pos < len)
str_byte++;
}
else
{
GET_NEXT_WCHAR();
pos = 0;
}
#if 0
/* Skip over characters that cannot possibly be the first character
of a match. */
if (tnfa->firstpos_chars != NULL)
{
char *chars = tnfa->firstpos_chars;
if (len < 0)
{
const char *orig_str = str_byte;
/* XXX - use strpbrk() and wcspbrk() because they might be
optimized for the target architecture. Try also strcspn()
and wcscspn() and compare the speeds. */
while (next_c != QSE_T('\0') && !chars[next_c])
{
next_c = *str_byte++;
}
prev_c = *(str_byte - 2);
pos += str_byte - orig_str;
DPRINT(("skipped %d chars\n", str_byte - orig_str));
}
else
{
while (pos <= len && !chars[next_c])
{
prev_c = next_c;
next_c = (unsigned char)(*str_byte++);
pos++;
}
}
}
#endif
DPRINT(("length: %d\n", len));
DPRINT(("pos:chr/code | states and tags\n"));
DPRINT(("-------------+------------------------------------------------\n"));
reach_next_i = reach_next;
while (/*CONSTCOND*/1)
{
/* If no match found yet, add the initial states to `reach_next'. */
if (match_eo < 0)
{
DPRINT((" init >"));
trans_i = tnfa->initial;
while (trans_i->state != NULL)
{
if (reach_pos[trans_i->state_id].pos < pos)
{
if (trans_i->assertions
&& CHECK_ASSERTIONS(trans_i->assertions))
{
DPRINT(("assertion failed\n"));
trans_i++;
continue;
}
DPRINT((" %p", (void *)trans_i->state));
reach_next_i->state = trans_i->state;
for (i = 0; i < num_tags; i++)
reach_next_i->tags[i] = -1;
tag_i = trans_i->tags;
if (tag_i)
while (*tag_i >= 0)
{
if (*tag_i < num_tags)
reach_next_i->tags[*tag_i] = pos;
tag_i++;
}
if (reach_next_i->state == tnfa->final)
{
DPRINT((" found empty match\n"));
match_eo = pos;
new_match = 1;
for (i = 0; i < num_tags; i++)
match_tags[i] = reach_next_i->tags[i];
}
reach_pos[trans_i->state_id].pos = pos;
reach_pos[trans_i->state_id].tags = &reach_next_i->tags;
reach_next_i++;
}
trans_i++;
}
DPRINT(("\n"));
reach_next_i->state = NULL;
}
else
{
if (num_tags == 0 || reach_next_i == reach_next)
/* We have found a match. */
break;
}
/* Check for end of string. */
if (len < 0)
{
if (type == STR_USER)
{
if (str_user_end)
break;
}
else if (next_c == QSE_T('\0'))
break;
}
else
{
if (pos >= len)
break;
}
GET_NEXT_WCHAR();
#ifdef TRE_DEBUG
DPRINT(("%3d:%2lc/%05d |", pos - 1, (tre_cint_t)prev_c, (int)prev_c));
tre_print_reach(tnfa, reach_next, num_tags);
DPRINT(("%3d:%2lc/%05d |", pos, (tre_cint_t)next_c, (int)next_c));
tre_print_reach(tnfa, reach_next, num_tags);
#endif /* TRE_DEBUG */
/* Swap `reach' and `reach_next'. */
reach_i = reach;
reach = reach_next;
reach_next = reach_i;
/* For each state in `reach', weed out states that don't fulfill the
minimal matching conditions. */
if (tnfa->num_minimals && new_match)
{
new_match = 0;
reach_next_i = reach_next;
for (reach_i = reach; reach_i->state; reach_i++)
{
int skip = 0;
for (i = 0; tnfa->minimal_tags[i] >= 0; i += 2)
{
int end = tnfa->minimal_tags[i];
int start = tnfa->minimal_tags[i + 1];
DPRINT((" Minimal start %d, end %d\n", start, end));
if (end >= num_tags)
{
DPRINT((" Throwing %p out.\n", reach_i->state));
skip = 1;
break;
}
else if (reach_i->tags[start] == match_tags[start]
&& reach_i->tags[end] < match_tags[end])
{
DPRINT((" Throwing %p out because t%d < %d\n",
reach_i->state, end, match_tags[end]));
skip = 1;
break;
}
}
if (!skip)
{
reach_next_i->state = reach_i->state;
tmp_iptr = reach_next_i->tags;
reach_next_i->tags = reach_i->tags;
reach_i->tags = tmp_iptr;
reach_next_i++;
}
}
reach_next_i->state = NULL;
/* Swap `reach' and `reach_next'. */
reach_i = reach;
reach = reach_next;
reach_next = reach_i;
}
/* For each state in `reach' see if there is a transition leaving with
the current input symbol to a state not yet in `reach_next', and
add the destination states to `reach_next'. */
reach_next_i = reach_next;
for (reach_i = reach; reach_i->state; reach_i++)
{
for (trans_i = reach_i->state; trans_i->state; trans_i++)
{
/* Does this transition match the input symbol? */
if (trans_i->code_min <= (tre_cint_t)prev_c &&
trans_i->code_max >= (tre_cint_t)prev_c)
{
if (trans_i->assertions
&& (CHECK_ASSERTIONS(trans_i->assertions)
|| CHECK_CHAR_CLASSES(trans_i, tnfa, eflags)))
{
DPRINT(("assertion failed\n"));
continue;
}
/* Compute the tags after this transition. */
for (i = 0; i < num_tags; i++)
tmp_tags[i] = reach_i->tags[i];
tag_i = trans_i->tags;
if (tag_i != NULL)
while (*tag_i >= 0)
{
if (*tag_i < num_tags)
tmp_tags[*tag_i] = pos;
tag_i++;
}
if (reach_pos[trans_i->state_id].pos < pos)
{
/* Found an unvisited node. */
reach_next_i->state = trans_i->state;
tmp_iptr = reach_next_i->tags;
reach_next_i->tags = tmp_tags;
tmp_tags = tmp_iptr;
reach_pos[trans_i->state_id].pos = pos;
reach_pos[trans_i->state_id].tags = &reach_next_i->tags;
if (reach_next_i->state == tnfa->final
&& (match_eo == -1
|| (num_tags > 0
&& reach_next_i->tags[0] <= match_tags[0])))
{
DPRINT((" found match %p\n", trans_i->state));
match_eo = pos;
new_match = 1;
for (i = 0; i < num_tags; i++)
match_tags[i] = reach_next_i->tags[i];
}
reach_next_i++;
}
else
{
assert(reach_pos[trans_i->state_id].pos == pos);
/* Another path has also reached this state. We choose
the winner by examining the tag values for both
paths. */
if (tre_tag_order(num_tags, tnfa->tag_directions,
tmp_tags,
*reach_pos[trans_i->state_id].tags))
{
/* The new path wins. */
tmp_iptr = *reach_pos[trans_i->state_id].tags;
*reach_pos[trans_i->state_id].tags = tmp_tags;
if (trans_i->state == tnfa->final)
{
DPRINT((" found better match\n"));
match_eo = pos;
new_match = 1;
for (i = 0; i < num_tags; i++)
match_tags[i] = tmp_tags[i];
}
tmp_tags = tmp_iptr;
}
}
}
}
}
reach_next_i->state = NULL;
}
DPRINT(("match end offset = %d\n", match_eo));
if (buf) xfree(mmgr, buf);
*match_end_ofs = match_eo;
return match_eo >= 0 ? REG_OK : REG_NOMATCH;
}
/* EOF */

View File

@ -0,0 +1,261 @@
/*
* $Id$
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
QSE is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
QSE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
*/
/*
tre-match-utils.h - TRE matcher helper definitions
This is the license, copyright notice, and disclaimer for TRE, a regex
matching package (library and tools) with support for approximate
matching.
Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define str_source ((const tre_str_source*)string)
#ifdef TRE_WCHAR
#ifdef TRE_MULTIBYTE
/* Wide character and multibyte support. */
#define GET_NEXT_WCHAR() \
do { \
prev_c = next_c; \
if (type == STR_BYTE) \
{ \
pos++; \
if (len >= 0 && pos >= len) \
next_c = '\0'; \
else \
next_c = (unsigned char)(*str_byte++); \
} \
else if (type == STR_WIDE) \
{ \
pos++; \
if (len >= 0 && pos >= len) \
next_c = QSE_T('\0'); \
else \
next_c = *str_wide++; \
} \
else if (type == STR_MBS) \
{ \
pos += pos_add_next; \
if (str_byte == NULL) \
next_c = QSE_T('\0'); \
else \
{ \
size_t w; \
int max; \
if (len >= 0) \
max = len - pos; \
else \
max = 32; \
if (max <= 0) \
{ \
next_c = QSE_T('\0'); \
pos_add_next = 1; \
} \
else \
{ \
w = qse_mbrtowc(str_byte, (size_t)max, &next_c, &mbstate); \
if (w <= 0 || w > max) \
return REG_NOMATCH; \
if (next_c == QSE_T('\0') && len >= 0) \
{ \
pos_add_next = 1; \
next_c = 0; \
str_byte++; \
} \
else \
{ \
pos_add_next = w; \
str_byte += w; \
} \
} \
} \
} \
else if (type == STR_USER) \
{ \
pos += pos_add_next; \
str_user_end = str_source->get_next_char(&next_c, &pos_add_next, \
str_source->context); \
} \
} while(/*CONSTCOND*/0)
#else /* !TRE_MULTIBYTE */
/* Wide character support, no multibyte support. */
#define GET_NEXT_WCHAR() \
do { \
prev_c = next_c; \
if (type == STR_BYTE) \
{ \
pos++; \
if (len >= 0 && pos >= len) \
next_c = '\0'; \
else \
next_c = (unsigned char)(*str_byte++); \
} \
else if (type == STR_WIDE) \
{ \
pos++; \
if (len >= 0 && pos >= len) \
next_c = QSE_T('\0'); \
else \
next_c = *str_wide++; \
} \
else if (type == STR_USER) \
{ \
pos += pos_add_next; \
str_user_end = str_source->get_next_char(&next_c, &pos_add_next, \
str_source->context); \
} \
} while(/*CONSTCOND*/0)
#endif /* !TRE_MULTIBYTE */
#else /* !TRE_WCHAR */
/* No wide character or multibyte support. */
#define GET_NEXT_WCHAR() \
do { \
prev_c = next_c; \
if (type == STR_BYTE) \
{ \
pos++; \
if (len >= 0 && pos >= len) \
next_c = '\0'; \
else \
next_c = (unsigned char)(*str_byte++); \
} \
else if (type == STR_USER) \
{ \
pos += pos_add_next; \
str_user_end = str_source->get_next_char(&next_c, &pos_add_next, \
str_source->context); \
} \
} while(/*CONSTCOND*/0)
#endif /* !TRE_WCHAR */
#define IS_WORD_CHAR(c) ((c) == QSE_T('_') || tre_isalnum(c))
#define CHECK_ASSERTIONS(assertions) \
(((assertions & ASSERT_AT_BOL) \
&& (pos > 0 || reg_notbol) \
&& (prev_c != QSE_T('\n') || !reg_newline)) \
|| ((assertions & ASSERT_AT_EOL) \
&& (next_c != QSE_T('\0') || reg_noteol) \
&& (next_c != QSE_T('\n') || !reg_newline)) \
|| ((assertions & ASSERT_AT_BOW) \
&& (IS_WORD_CHAR(prev_c) || !IS_WORD_CHAR(next_c))) \
|| ((assertions & ASSERT_AT_EOW) \
&& (!IS_WORD_CHAR(prev_c) || IS_WORD_CHAR(next_c))) \
|| ((assertions & ASSERT_AT_WB) \
&& (pos != 0 && next_c != QSE_T('\0') \
&& IS_WORD_CHAR(prev_c) == IS_WORD_CHAR(next_c))) \
|| ((assertions & ASSERT_AT_WB_NEG) \
&& (pos == 0 || next_c == QSE_T('\0') \
|| IS_WORD_CHAR(prev_c) != IS_WORD_CHAR(next_c))))
#define CHECK_CHAR_CLASSES(trans_i, tnfa, eflags) \
(((trans_i->assertions & ASSERT_CHAR_CLASS) \
&& !(tnfa->cflags & REG_ICASE) \
&& !tre_isctype((tre_cint_t)prev_c, trans_i->u.class)) \
|| ((trans_i->assertions & ASSERT_CHAR_CLASS) \
&& (tnfa->cflags & REG_ICASE) \
&& !tre_isctype(tre_tolower((tre_cint_t)prev_c),trans_i->u.class) \
&& !tre_isctype(tre_toupper((tre_cint_t)prev_c),trans_i->u.class)) \
|| ((trans_i->assertions & ASSERT_CHAR_CLASS_NEG) \
&& tre_neg_char_classes_match(trans_i->neg_classes,(tre_cint_t)prev_c,\
tnfa->cflags & REG_ICASE)))
/* Returns 1 if `t1' wins `t2', 0 otherwise. */
QSE_INLINE static int
tre_tag_order(int num_tags, tre_tag_direction_t *tag_directions,
int *t1, int *t2)
{
int i;
for (i = 0; i < num_tags; i++)
{
if (tag_directions[i] == TRE_TAG_MINIMIZE)
{
if (t1[i] < t2[i])
return 1;
if (t1[i] > t2[i])
return 0;
}
else
{
if (t1[i] > t2[i])
return 1;
if (t1[i] < t2[i])
return 0;
}
}
/* assert(0);*/
return 0;
}
QSE_INLINE static int
tre_neg_char_classes_match(tre_ctype_t *classes, tre_cint_t wc, int icase)
{
DPRINT(("neg_char_classes_test: %p, %d, %d\n", classes, wc, icase));
while (*classes != (tre_ctype_t)0)
if ((!icase && tre_isctype(wc, *classes))
|| (icase && (tre_isctype(tre_toupper(wc), *classes)
|| tre_isctype(tre_tolower(wc), *classes))))
return 1; /* Match. */
else
classes++;
return 0; /* No match. */
}

1837
qse/lib/cmn/tre-parse.c Normal file

File diff suppressed because it is too large Load Diff

96
qse/lib/cmn/tre-parse.h Normal file
View File

@ -0,0 +1,96 @@
/*
* $Id$
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
QSE is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
QSE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
*/
/*
tre-parse.c - Regexp parser definitions
This is the license, copyright notice, and disclaimer for TRE, a regex
matching package (library and tools) with support for approximate
matching.
Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _QSE_LIB_CMN_TRE_PARSE_H_
#define _QSE_LIB_CMN_TRE_PARSE_H_
/* Parse context. */
typedef struct
{
/* Memory allocator. The AST is allocated using this. */
tre_mem_t mem;
/* Stack used for keeping track of regexp syntax. */
tre_stack_t *stack;
/* The parse result. */
tre_ast_node_t *result;
/* The regexp to parse and its length. */
const tre_char_t *re;
/* The first character of the entire regexp. */
const tre_char_t *re_start;
/* The first character after the end of the regexp. */
const tre_char_t *re_end;
int len;
/* Current submatch ID. */
int submatch_id;
/* Current position (number of literal). */
int position;
/* The highest back reference or -1 if none seen so far. */
int max_backref;
/* This flag is set if the regexp uses approximate matching. */
int have_approx;
/* Compilation flags. */
int cflags;
/* If this flag is set the top-level submatch is not captured. */
int nofirstsub;
/* The currently set approximate matching parameters. */
int params[TRE_PARAM_LAST];
} tre_parse_ctx_t;
/* Parses a wide character regexp pattern into a syntax tree. This parser
handles both syntaxes (BRE and ERE), including the TRE extensions. */
reg_errcode_t tre_parse(tre_parse_ctx_t *ctx);
#endif /* TRE_PARSE_H */
/* EOF */

167
qse/lib/cmn/tre-stack.c Normal file
View File

@ -0,0 +1,167 @@
/*
* $Id$
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
QSE is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
QSE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
*/
/*
tre-stack.c - Simple stack implementation
This is the license, copyright notice, and disclaimer for TRE, a regex
matching package (library and tools) with support for approximate
matching.
Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "tre.h"
#include "tre-stack.h"
union tre_stack_item
{
void *voidptr_value;
int int_value;
};
struct tre_stack_rec
{
qse_mmgr_t* mmgr;
int size;
int max_size;
int increment;
int ptr;
union tre_stack_item *stack;
};
tre_stack_t* tre_stack_new(qse_mmgr_t* mmgr, int size, int max_size, int increment)
{
tre_stack_t *s;
s = xmalloc(mmgr, sizeof(*s));
if (s != NULL)
{
s->stack = xmalloc(mmgr, sizeof(*s->stack) * size);
if (s->stack == NULL)
{
xfree(mmgr, s);
return NULL;
}
s->size = size;
s->max_size = max_size;
s->increment = increment;
s->ptr = 0;
s->mmgr = mmgr;
}
return s;
}
void
tre_stack_destroy(tre_stack_t *s)
{
xfree(s->mmgr,s->stack);
xfree(s->mmgr,s);
}
int
tre_stack_num_objects(tre_stack_t *s)
{
return s->ptr;
}
static reg_errcode_t
tre_stack_push(tre_stack_t *s, union tre_stack_item value)
{
if (s->ptr < s->size)
{
s->stack[s->ptr] = value;
s->ptr++;
}
else
{
if (s->size >= s->max_size)
{
DPRINT(("tre_stack_push: stack full\n"));
return REG_ESPACE;
}
else
{
union tre_stack_item *new_buffer;
int new_size;
DPRINT(("tre_stack_push: trying to realloc more space\n"));
new_size = s->size + s->increment;
if (new_size > s->max_size)
new_size = s->max_size;
new_buffer = xrealloc(s->mmgr, s->stack, sizeof(*new_buffer) * new_size);
if (new_buffer == NULL)
{
DPRINT(("tre_stack_push: realloc failed.\n"));
return REG_ESPACE;
}
DPRINT(("tre_stack_push: realloc succeeded.\n"));
assert(new_size > s->size);
s->size = new_size;
s->stack = new_buffer;
tre_stack_push(s, value);
}
}
return REG_OK;
}
#define define_pushf(typetag, type) \
declare_pushf(typetag, type) { \
union tre_stack_item item; \
item.typetag ## _value = value; \
return tre_stack_push(s, item); \
}
define_pushf(int, int)
define_pushf(voidptr, void *)
#define define_popf(typetag, type) \
declare_popf(typetag, type) { \
return s->stack[--s->ptr].typetag ## _value; \
}
define_popf(int, int)
define_popf(voidptr, void *)
/* EOF */

122
qse/lib/cmn/tre-stack.h Normal file
View File

@ -0,0 +1,122 @@
/*
* $Id$
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
QSE is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
QSE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
*/
/*
tre-stack.h: Stack definitions
This is the license, copyright notice, and disclaimer for TRE, a regex
matching package (library and tools) with support for approximate
matching.
Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _QSE_LIB_CMN_TRE_STACK_H_
#define _QSE_LIB_CMN_TRE_STACK_H_
#include "tre.h"
typedef struct tre_stack_rec tre_stack_t;
/* Creates a new stack object. `size' is initial size in bytes, `max_size'
is maximum size, and `increment' specifies how much more space will be
allocated with realloc() if all space gets used up. Returns the stack
object or NULL if out of memory. */
tre_stack_t *
tre_stack_new(qse_mmgr_t* mmgr, int size, int max_size, int increment);
/* Frees the stack object. */
void
tre_stack_destroy(tre_stack_t *s);
/* Returns the current number of objects in the stack. */
int
tre_stack_num_objects(tre_stack_t *s);
/* Each tre_stack_push_*(tre_stack_t *s, <type> value) function pushes
`value' on top of stack `s'. Returns REG_ESPACE if out of memory.
This tries to realloc() more space before failing if maximum size
has not yet been reached. Returns REG_OK if successful. */
#define declare_pushf(typetag, type) \
reg_errcode_t tre_stack_push_ ## typetag(tre_stack_t *s, type value)
declare_pushf(voidptr, void *);
declare_pushf(int, int);
/* Each tre_stack_pop_*(tre_stack_t *s) function pops the topmost
element off of stack `s' and returns it. The stack must not be
empty. */
#define declare_popf(typetag, type) \
type tre_stack_pop_ ## typetag(tre_stack_t *s)
declare_popf(voidptr, void *);
declare_popf(int, int);
/* Just to save some typing. */
#define STACK_PUSH(s, typetag, value) \
do \
{ \
status = tre_stack_push_ ## typetag(s, value); \
} \
while (/*CONSTCOND*/0)
#define STACK_PUSHX(s, typetag, value) \
{ \
status = tre_stack_push_ ## typetag(s, value); \
if (status != REG_OK) \
break; \
}
#define STACK_PUSHR(s, typetag, value) \
{ \
reg_errcode_t _status; \
_status = tre_stack_push_ ## typetag(s, value); \
if (_status != REG_OK) \
return _status; \
}
#endif /* TRE_STACK_H */
/* EOF */

279
qse/lib/cmn/tre.c Normal file
View File

@ -0,0 +1,279 @@
/*
* $Id$
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
QSE is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
QSE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
*/
#include "tre.h"
#include "tre-compile.h"
#include <qse/cmn/str.h>
#if 0
QSE_IMPLEMENT_COMMON_FUNCTIONS (tre)
qse_tre_t* qse_tre_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_tre_code_t* code)
{
qse_tre_t* tre;
if (mmgr == QSE_NULL)
{
mmgr = QSE_MMGR_GETDFL();
QSE_ASSERTX (mmgr != QSE_NULL,
"Set the memory manager with QSE_MMGR_SETDFL()");
if (mmgr == QSE_NULL) return QSE_NULL;
}
tre = (qse_tre_t*) QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_tre_t) + xtn);
if (tre == QSE_NULL) return QSE_NULL;
if (qse_tre_init (tre, mmgr, code) <= -1)
{
QSE_MMGR_FREE (mmgr, tre);
return QSE_NULL;
}
return QSE_NULL;
}
void qse_tre_close (qse_tre_t* tre)
{
qse_tre_fini (tre);
QSE_MMGR_FREE (tre->mmgr, tre);
}
#endif
/*
tre_regcomp.c - TRE POSIX compatible regex compilation functions.
This software is released under a BSD-style license.
See the file LICENSE for details and copyright.
*/
int qse_tre_init (qse_tre_t* tre, qse_mmgr_t* mmgr)
{
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
QSE_MEMSET (tre, 0, QSE_SIZEOF(*tre));
tre->mmgr = mmgr;
return 0;
}
void qse_tre_fini (qse_tre_t* tre)
{
if (tre->value)
{
tre_free (tre);
tre->value = QSE_NULL;
}
}
int qse_tre_compx (qse_tre_t* tre, const qse_char_t* regex, qse_size_t n, int cflags)
{
int ret;
if (tre->value)
{
tre_free (tre);
tre->value = QSE_NULL;
}
ret = tre_compile (tre, regex, n, cflags);
if (ret > 0)
{
tre->value = QSE_NULL; /* just to make sure */
tre->errnum = ret;
return -1;
}
return 0;
}
int qse_tre_comp (qse_tre_t* tre, const qse_char_t* regex, int cflags)
{
return qse_tre_compx (tre, regex, (regex? qse_strlen(regex):0), cflags);
}
/* Fills the POSIX.2 regmatch_t array according to the TNFA tag and match
endpoint values. */
void tre_fill_pmatch(size_t nmatch, regmatch_t pmatch[], int cflags,
const tre_tnfa_t *tnfa, int *tags, int match_eo)
{
tre_submatch_data_t *submatch_data;
unsigned int i, j;
int *parents;
i = 0;
if (match_eo >= 0 && !(cflags & REG_NOSUB))
{
/* Construct submatch offsets from the tags. */
DPRINT(("end tag = t%d = %d\n", tnfa->end_tag, match_eo));
submatch_data = tnfa->submatch_data;
while (i < tnfa->num_submatches && i < nmatch)
{
if (submatch_data[i].so_tag == tnfa->end_tag)
pmatch[i].rm_so = match_eo;
else
pmatch[i].rm_so = tags[submatch_data[i].so_tag];
if (submatch_data[i].eo_tag == tnfa->end_tag)
pmatch[i].rm_eo = match_eo;
else
pmatch[i].rm_eo = tags[submatch_data[i].eo_tag];
/* If either of the endpoints were not used, this submatch
was not part of the match. */
if (pmatch[i].rm_so == -1 || pmatch[i].rm_eo == -1)
pmatch[i].rm_so = pmatch[i].rm_eo = -1;
DPRINT(("pmatch[%d] = {t%d = %d, t%d = %d}\n", i,
submatch_data[i].so_tag, pmatch[i].rm_so,
submatch_data[i].eo_tag, pmatch[i].rm_eo));
i++;
}
/* Reset all submatches that are not within all of their parent
submatches. */
i = 0;
while (i < tnfa->num_submatches && i < nmatch)
{
if (pmatch[i].rm_eo == -1)
assert(pmatch[i].rm_so == -1);
assert(pmatch[i].rm_so <= pmatch[i].rm_eo);
parents = submatch_data[i].parents;
if (parents != QSE_NULL)
for (j = 0; parents[j] >= 0; j++)
{
DPRINT(("pmatch[%d] parent %d\n", i, parents[j]));
if (pmatch[i].rm_so < pmatch[parents[j]].rm_so
|| pmatch[i].rm_eo > pmatch[parents[j]].rm_eo)
pmatch[i].rm_so = pmatch[i].rm_eo = -1;
}
i++;
}
}
while (i < nmatch)
{
pmatch[i].rm_so = -1;
pmatch[i].rm_eo = -1;
i++;
}
}
/*
Wrapper functions for POSIX compatible regexp matching.
*/
int tre_have_backrefs(const regex_t *preg)
{
tre_tnfa_t *tnfa = (void *)preg->TRE_REGEX_T_FIELD;
return tnfa->have_backrefs;
}
static int tre_match(
const regex_t* preg, const void *string, qse_size_t len,
tre_str_type_t type, qse_size_t nmatch, regmatch_t pmatch[],
int eflags)
{
tre_tnfa_t *tnfa = (void *)preg->TRE_REGEX_T_FIELD;
reg_errcode_t status;
int *tags = QSE_NULL, eo;
if (tnfa->num_tags > 0 && nmatch > 0)
{
tags = xmalloc (preg->mmgr, sizeof(*tags) * tnfa->num_tags);
if (tags == QSE_NULL) return REG_ESPACE;
}
/* Dispatch to the appropriate matcher. */
if (tnfa->have_backrefs || eflags & REG_BACKTRACKING_MATCHER)
{
/* The regex has back references, use the backtracking matcher. */
if (type == STR_USER)
{
const tre_str_source *source = string;
if (source->rewind == QSE_NULL || source->compare == QSE_NULL)
/* The backtracking matcher requires rewind and compare
capabilities from the input stream. */
return REG_BADPAT;
}
status = tre_tnfa_run_backtrack (
preg->mmgr, tnfa, string, (int)len, type,
tags, eflags, &eo);
}
else
{
/* Exact matching, no back references, use the parallel matcher. */
status = tre_tnfa_run_parallel (
preg->mmgr, tnfa, string, (int)len, type,
tags, eflags, &eo);
}
if (status == REG_OK)
/* A match was found, so fill the submatch registers. */
tre_fill_pmatch(nmatch, pmatch, tnfa->cflags, tnfa, tags, eo);
if (tags) xfree (preg->mmgr, tags);
return status;
}
int qse_tre_execx (
qse_tre_t* tre, const qse_char_t *str, qse_size_t len,
qse_size_t nmatch, regmatch_t pmatch[], int eflags)
{
int ret;
if (tre->value == QSE_NULL)
{
/* regular expression is bad as none is compiled yet */
tre->errnum = QSE_TRE_EBADPAT;
return -1;
}
#ifdef QSE_CHAR_IS_WCHAR
ret = tre_match (tre, str, len, STR_WIDE, nmatch, pmatch, eflags);
#else
ret = tre_match (tre, str, len, STR_BYTE, nmatch, pmatch, eflags);
#endif
if (ret > 0)
{
tre->errnum = ret;
return -1;
}
return 0;
}
int qse_tre_exec (
qse_tre_t* tre, const qse_char_t* str,
qse_size_t nmatch, regmatch_t pmatch[], int eflags)
{
return qse_tre_execx (tre, str, (unsigned)-1, nmatch, pmatch, eflags);
}
#if 0
int qse_tre_execsrc (
const regex_t *preg, const tre_str_source *str,
qse_size_t nmatch, regmatch_t pmatch[], int eflags)
{
return tre_match (preg, str, (unsigned)-1, STR_USER, nmatch, pmatch, eflags);
}
#endif

354
qse/lib/cmn/tre.h Normal file
View File

@ -0,0 +1,354 @@
/*
* $Id$
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
QSE is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
QSE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
*/
/*
tre-internal.h - TRE internal definitions
This is the license, copyright notice, and disclaimer for TRE, a regex
matching package (library and tools) with support for approximate
matching.
Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _QSE_LIB_CMN_TRE_H_
#define _QSE_LIB_CMN_TRE_H_
#include <qse/cmn/tre.h>
#ifdef QSE_CHAR_IS_WCHAR
# define TRE_WCHAR
/*
# define TRE_MULTIBYTE
# define TRE_MBSTATE
*/
#endif
#define TRE_REGEX_T_FIELD value
#define assert QSE_ASSERT
#define NULL QSE_NULL
#include <qse/cmn/chr.h>
#include <qse/cmn/str.h>
#include <qse/cmn/pma.h>
#include "mem.h"
#define tre_islower(c) QSE_ISLOWER(c)
#define tre_isupper(c) QSE_ISUPPER(c)
#define tre_isalpha(c) QSE_ISALPHA(c)
#define tre_isdigit(c) QSE_ISDIGIT(c)
#define tre_isxdigit(c) QSE_ISXDIGIT(c)
#define tre_isalnum(c) QSE_ISALNUM(c)
#define tre_isspace(c) QSE_ISSPACE(c)
#define tre_isprint(c) QSE_ISPRINT(c)
#define tre_isgraph(c) QSE_ISGRAPH(c)
#define tre_iscntrl(c) QSE_ISCNTRL(c)
#define tre_ispunct(c) QSE_ISPUNCT(c)
#define tre_isblank(c) QSE_ISBLANK(c)
#define tre_tolower(c) QSE_TOLOWER(c)
#define tre_toupper(c) QSE_TOUPPER(c)
typedef qse_char_t tre_char_t;
typedef qse_cint_t tre_cint_t;
#define size_t qse_size_t
#define regex_t qse_tre_t
#define regmatch_t qse_tre_match_t
#define reg_errcode_t qse_tre_errnum_t
#define tre_str_source qse_tre_strsrc_t
#define REG_OK QSE_TRE_ENOERR
#define REG_ESPACE QSE_TRE_ENOMEM
#define REG_NOMATCH QSE_TRE_ENOMATCH
#define REG_BADPAT QSE_TRE_EBADPAT
#define REG_ECOLLATE QSE_TRE_ECOLLATE
#define REG_ECTYPE QSE_TRE_ECTYPE
#define REG_EESCAPE QSE_TRE_EESCAPE
#define REG_ESUBREG QSE_TRE_ESUBREG
#define REG_EBRACK QSE_TRE_EBRACK
#define REG_EPAREN QSE_TRE_EPAREN
#define REG_EBRACE QSE_TRE_EBRACE
#define REG_BADBR QSE_TRE_EBADBR
#define REG_ERANGE QSE_TRE_ERANGE
#define REG_BADRPT QSE_TRE_EBADRPT
/* The maximum number of iterations in a bound expression. */
#undef RE_DUP_MAX
#define RE_DUP_MAX 255
/* POSIX tre_regcomp() flags. */
#define REG_EXTENDED QSE_TRE_EXTENDED
#define REG_ICASE QSE_TRE_IGNORECASE
#define REG_NEWLINE QSE_TRE_NEWLINE
#define REG_NOSUB QSE_TRE_NOSUBREG
/* Extra tre_regcomp() flags. */
#define REG_LITERAL QSE_TRE_LITERAL
#define REG_RIGHT_ASSOC QSE_TRE_RIGHTASSOC
#define REG_UNGREEDY QSE_TRE_UNGREEDY
/* POSIX tre_regexec() flags. */
#define REG_NOTBOL QSE_TRE_NOTBOL
#define REG_NOTEOL QSE_TRE_NOTEOL
#define REG_BACKTRACKING_MATCHER QSE_TRE_BACKTRACKING
#define tre_strlen(c) qse_strlen(c)
typedef qse_pma_t* tre_mem_t;
#define tre_mem_new(mmgr) qse_pma_open(mmgr,0)
#define tre_mem_destroy(mem) qse_pma_close(mem)
#define tre_mem_alloc(mem,size) qse_pma_alloc(mem,size)
#define tre_mem_calloc(mem,size) qse_pma_calloc(mem,size)
#define xmalloc(mmgr,size) QSE_MMGR_ALLOC(mmgr,size)
#define xfree(mmgr,ptr) QSE_MMGR_FREE(mmgr,ptr)
#define xrealloc(mmgr,ptr,new_size) QSE_MMGR_REALLOC(mmgr, ptr, new_size)
/* tre-ast.h */
#define tre_ast_new_node qse_tre_astnewnode
#define tre_ast_new_literal qse_tre_astnewliteral
#define tre_ast_new_iter qse_tre_astnewiter
#define tre_ast_new_union qse_tre_astnewunion
#define tre_ast_new_catenation qse_tre_astnewcatenation
/* tre-parse.h */
#define tre_parse qse_tre_parse
/* tre-stack.h */
#define tre_stack_destroy qse_tre_stackfree
#define tre_stack_new qse_tre_stacknew
#define tre_stack_num_objects qse_tre_stacknumobjs
#define tre_stack_pop_int qse_tre_stackpopint
#define tre_stack_pop_voidptr qse_tre_stackpopvoidptr
#define tre_stack_push_int qse_tre_stackpushint
#define tre_stack_push_voidptr qse_tre_stackpushvoidptr
/* this tre.h */
#define tre_compile qse_tre_compile
#define tre_free qse_tre_free
#define tre_fill_pmatch qse_tre_fillpmatch
#define tre_tnfa_run_backtrack qse_tre_runbacktrack
#define tre_tnfa_run_parallel qse_tre_runparallel
#define tre_have_backrefs qse_tre_havebackrefs
/* Define the character types and functions. */
#ifdef TRE_WCHAR
# define TRE_CHAR_MAX QSE_TYPE_MAX(qse_wchar_t)
# ifdef TRE_MULTIBYTE
# define TRE_MB_CUR_MAX (qse_getmbcurmax())
# else /* !TRE_MULTIBYTE */
# define TRE_MB_CUR_MAX 1
# endif /* !TRE_MULTIBYTE */
#else /* !TRE_WCHAR */
# define TRE_CHAR_MAX 255
# define TRE_MB_CUR_MAX 1
#endif /* !TRE_WCHAR */
#define DPRINT(msg)
typedef qse_ctype_t tre_ctype_t;
#define tre_isctype(c,t) QSE_ISCTYPE(c,t)
typedef enum { STR_WIDE, STR_BYTE, STR_MBS, STR_USER } tre_str_type_t;
/* Returns number of bytes to add to (char *)ptr to make it
properly aligned for the type. */
#define ALIGN(ptr, type) \
((((long)ptr) % sizeof(type)) \
? (sizeof(type) - (((long)ptr) % sizeof(type))) \
: 0)
#undef MAX
#undef MIN
#define MAX(a, b) (((a) >= (b)) ? (a) : (b))
#define MIN(a, b) (((a) <= (b)) ? (a) : (b))
/* Define STRF to the correct printf formatter for strings. */
#ifdef TRE_WCHAR
#define STRF "ls"
#else /* !TRE_WCHAR */
#define STRF "s"
#endif /* !TRE_WCHAR */
/* TNFA transition type. A TNFA state is an array of transitions,
the terminator is a transition with NULL `state'. */
typedef struct tnfa_transition tre_tnfa_transition_t;
struct tnfa_transition
{
/* Range of accepted characters. */
tre_cint_t code_min;
tre_cint_t code_max;
/* Pointer to the destination state. */
tre_tnfa_transition_t *state;
/* ID number of the destination state. */
int state_id;
/* -1 terminated array of tags (or NULL). */
int *tags;
/* Matching parameters settings (or NULL). */
int *params;
/* Assertion bitmap. */
int assertions;
/* Assertion parameters. */
union
{
/* Character class assertion. */
tre_ctype_t class;
/* Back reference assertion. */
int backref;
} u;
/* Negative character class assertions. */
tre_ctype_t *neg_classes;
};
/* Assertions. */
#define ASSERT_AT_BOL 1 /* Beginning of line. */
#define ASSERT_AT_EOL 2 /* End of line. */
#define ASSERT_CHAR_CLASS 4 /* Character class in `class'. */
#define ASSERT_CHAR_CLASS_NEG 8 /* Character classes in `neg_classes'. */
#define ASSERT_AT_BOW 16 /* Beginning of word. */
#define ASSERT_AT_EOW 32 /* End of word. */
#define ASSERT_AT_WB 64 /* Word boundary. */
#define ASSERT_AT_WB_NEG 128 /* Not a word boundary. */
#define ASSERT_BACKREF 256 /* A back reference in `backref'. */
#define ASSERT_LAST 256
/* Tag directions. */
typedef enum
{
TRE_TAG_MINIMIZE = 0,
TRE_TAG_MAXIMIZE = 1
} tre_tag_direction_t;
/* Parameters that can be changed dynamically while matching. */
typedef enum
{
TRE_PARAM_COST_INS = 0,
TRE_PARAM_COST_DEL = 1,
TRE_PARAM_COST_SUBST = 2,
TRE_PARAM_COST_MAX = 3,
TRE_PARAM_MAX_INS = 4,
TRE_PARAM_MAX_DEL = 5,
TRE_PARAM_MAX_SUBST = 6,
TRE_PARAM_MAX_ERR = 7,
TRE_PARAM_DEPTH = 8,
TRE_PARAM_LAST = 9
} tre_param_t;
/* Unset matching parameter */
#define TRE_PARAM_UNSET -1
/* Signifies the default matching parameter value. */
#define TRE_PARAM_DEFAULT -2
/* Instructions to compute submatch register values from tag values
after a successful match. */
struct tre_submatch_data
{
/* Tag that gives the value for rm_so (submatch start offset). */
int so_tag;
/* Tag that gives the value for rm_eo (submatch end offset). */
int eo_tag;
/* List of submatches this submatch is contained in. */
int *parents;
};
typedef struct tre_submatch_data tre_submatch_data_t;
/* TNFA definition. */
typedef struct tnfa tre_tnfa_t;
struct tnfa
{
tre_tnfa_transition_t *transitions;
unsigned int num_transitions;
tre_tnfa_transition_t *initial;
tre_tnfa_transition_t *final;
tre_submatch_data_t *submatch_data;
char *firstpos_chars;
int first_char;
unsigned int num_submatches;
tre_tag_direction_t *tag_directions;
int *minimal_tags;
int num_tags;
int num_minimals;
int end_tag;
int num_states;
int cflags;
int have_backrefs;
int have_approx;
int params_depth;
};
int tre_compile (regex_t *preg, const tre_char_t *regex, size_t n, int cflags);
void tre_free (regex_t *preg);
void tre_fill_pmatch(
size_t nmatch, regmatch_t pmatch[], int cflags,
const tre_tnfa_t *tnfa, int *tags, int match_eo);
reg_errcode_t tre_tnfa_run_backtrack(
qse_mmgr_t* mmgr, const tre_tnfa_t *tnfa, const void *string,
int len, tre_str_type_t type, int *match_tags,
int eflags, int *match_end_ofs);
reg_errcode_t tre_tnfa_run_parallel(
qse_mmgr_t* mmgr, const tre_tnfa_t *tnfa, const void *string, int len,
tre_str_type_t type, int *match_tags, int eflags,
int *match_end_ofs);
#endif
/* EOF */

View File

@ -122,7 +122,7 @@ qse_xma_t* qse_xma_open (
xma = (qse_xma_t*) QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(*xma) + xtnsize);
if (xma == QSE_NULL) return QSE_NULL;
if (qse_xma_init (xma, mmgr, zonesize) == QSE_NULL)
if (qse_xma_init (xma, mmgr, zonesize) <= -1)
{
QSE_MMGR_FREE (mmgr, xma);
return QSE_NULL;
@ -137,7 +137,7 @@ void qse_xma_close (qse_xma_t* xma)
QSE_MMGR_FREE (xma->mmgr, xma);
}
qse_xma_t* qse_xma_init (qse_xma_t* xma, qse_mmgr_t* mmgr, qse_size_t zonesize)
int qse_xma_init (qse_xma_t* xma, qse_mmgr_t* mmgr, qse_size_t zonesize)
{
qse_xma_blk_t* free;
qse_size_t xfi;
@ -152,7 +152,7 @@ qse_xma_t* qse_xma_init (qse_xma_t* xma, qse_mmgr_t* mmgr, qse_size_t zonesize)
/* allocate a memory chunk to use for actual memory allocation */
free = QSE_MMGR_ALLOC (mmgr, zonesize);
if (free == QSE_NULL) return QSE_NULL;
if (free == QSE_NULL) return -1;
/* initialize the header part of the free chunk */
free->avail = 1;
@ -184,7 +184,7 @@ qse_xma_t* qse_xma_init (qse_xma_t* xma, qse_mmgr_t* mmgr, qse_size_t zonesize)
xma->stat.nused = 0;
#endif
return xma;
return 0;
}
void qse_xma_fini (qse_xma_t* xma)

View File

@ -173,7 +173,7 @@ int StdCut::StringStream::open (Data& io)
{
if (!out.inited)
{
if (qse_str_init (&out.buf, ((Cut*)io)->getMmgr(), 256) == QSE_NULL)
if (qse_str_init (&out.buf, ((Cut*)io)->getMmgr(), 256) <= -1)
{
((Cut*)io)->setError (QSE_CUT_ENOMEM);
return -1;

View File

@ -24,7 +24,7 @@
QSE_IMPLEMENT_COMMON_FUNCTIONS (cut)
static qse_cut_t* qse_cut_init (qse_cut_t* cut, qse_mmgr_t* mmgr);
static int qse_cut_init (qse_cut_t* cut, qse_mmgr_t* mmgr);
static void qse_cut_fini (qse_cut_t* cut);
#define SETERR0(cut,num) \
@ -92,7 +92,7 @@ qse_cut_t* qse_cut_open (qse_mmgr_t* mmgr, qse_size_t xtn)
cut = (qse_cut_t*) QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_cut_t) + xtn);
if (cut == QSE_NULL) return QSE_NULL;
if (qse_cut_init (cut, mmgr) == QSE_NULL)
if (qse_cut_init (cut, mmgr) <= -1)
{
QSE_MMGR_FREE (cut->mmgr, cut);
return QSE_NULL;
@ -107,7 +107,7 @@ void qse_cut_close (qse_cut_t* cut)
QSE_MMGR_FREE (cut->mmgr, cut);
}
static qse_cut_t* qse_cut_init (qse_cut_t* cut, qse_mmgr_t* mmgr)
static int qse_cut_init (qse_cut_t* cut, qse_mmgr_t* mmgr)
{
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
@ -125,13 +125,13 @@ static qse_cut_t* qse_cut_init (qse_cut_t* cut, qse_mmgr_t* mmgr)
cut->e.in.flds = cut->e.in.sflds;
if (qse_str_init (
&cut->e.in.line, QSE_MMGR(cut), DFL_LINE_CAPA) == QSE_NULL)
&cut->e.in.line, QSE_MMGR(cut), DFL_LINE_CAPA) <= -1)
{
SETERR0 (cut, QSE_CUT_ENOMEM);
return QSE_NULL;
return -1;
}
return cut;
return 0;
}
static void qse_cut_fini (qse_cut_t* cut)

View File

@ -151,7 +151,7 @@ qse_htrd_t* qse_htrd_open (qse_mmgr_t* mmgr, qse_size_t xtnsize)
);
if (htrd == QSE_NULL) return QSE_NULL;
if (qse_htrd_init (htrd, mmgr) == QSE_NULL)
if (qse_htrd_init (htrd, mmgr) <= -1)
{
QSE_MMGR_FREE (htrd->mmgr, htrd);
return QSE_NULL;
@ -166,7 +166,7 @@ void qse_htrd_close (qse_htrd_t* htrd)
QSE_MMGR_FREE (htrd->mmgr, htrd);
}
qse_htrd_t* qse_htrd_init (qse_htrd_t* htrd, qse_mmgr_t* mmgr)
int qse_htrd_init (qse_htrd_t* htrd, qse_mmgr_t* mmgr)
{
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
@ -180,17 +180,17 @@ qse_htrd_t* qse_htrd_init (qse_htrd_t* htrd, qse_mmgr_t* mmgr)
qse_mbs_init (&htrd->fed.b.raw, htrd->mmgr, 0);
qse_mbs_init (&htrd->fed.b.tra, htrd->mmgr, 0);
if (qse_htre_init (&htrd->re, mmgr) == QSE_NULL)
if (qse_htre_init (&htrd->re, mmgr) <= -1)
{
qse_mbs_fini (&htrd->fed.b.tra);
qse_mbs_fini (&htrd->fed.b.raw);
#if 0
qse_mbs_fini (&htrd->tmp.qparam);
#endif
return QSE_NULL;
return -1;
}
return htrd;
return 0;
}
void qse_htrd_fini (qse_htrd_t* htrd)

View File

@ -21,21 +21,18 @@
#include <qse/net/htre.h>
#include "../cmn/mem.h"
qse_htre_t* qse_htre_init (qse_htre_t* re, qse_mmgr_t* mmgr)
int qse_htre_init (qse_htre_t* re, qse_mmgr_t* mmgr)
{
QSE_MEMSET (re, 0, QSE_SIZEOF(*re));
re->mmgr = mmgr;
if (qse_htb_init (&re->hdrtab, mmgr, 60, 70, 1, 1) == QSE_NULL)
{
return QSE_NULL;
}
if (qse_htb_init (&re->hdrtab, mmgr, 60, 70, 1, 1) <= -1) return -1;
qse_mbs_init (&re->content, mmgr, 0);
qse_mbs_init (&re->qpath_or_smesg, mmgr, 0);
qse_mbs_init (&re->qparam, mmgr, 0);
return re;
return 0;
}
void qse_htre_fini (qse_htre_t* re)

View File

@ -72,7 +72,7 @@ qse_httpd_t* qse_httpd_open (qse_mmgr_t* mmgr, qse_size_t xtnsize)
);
if (httpd == QSE_NULL) return QSE_NULL;
if (qse_httpd_init (httpd, mmgr) == QSE_NULL)
if (qse_httpd_init (httpd, mmgr) <= -1)
{
QSE_MMGR_FREE (httpd->mmgr, httpd);
return QSE_NULL;
@ -87,7 +87,7 @@ void qse_httpd_close (qse_httpd_t* httpd)
QSE_MMGR_FREE (httpd->mmgr, httpd);
}
qse_httpd_t* qse_httpd_init (qse_httpd_t* httpd, qse_mmgr_t* mmgr)
int qse_httpd_init (qse_httpd_t* httpd, qse_mmgr_t* mmgr)
{
QSE_MEMSET (httpd, 0, QSE_SIZEOF(*httpd));
httpd->mmgr = mmgr;
@ -97,7 +97,7 @@ qse_httpd_t* qse_httpd_init (qse_httpd_t* httpd, qse_mmgr_t* mmgr)
pthread_mutex_init (&httpd->listener.mutex, QSE_NULL);
#endif
return httpd;
return 0;
}
void qse_httpd_fini (qse_httpd_t* httpd)

View File

@ -139,7 +139,7 @@ struct qse_httpd_t
extern "C" {
#endif
qse_httpd_t* qse_httpd_init (
int qse_httpd_init (
qse_httpd_t* httpd,
qse_mmgr_t* mmgr
);

Some files were not shown because too many files have changed in this diff Show More