added some code for integrating TRE into awk

This commit is contained in:
hyung-hwan 2013-04-06 13:39:56 +00:00
parent 75bf46e051
commit bad915cc55
20 changed files with 225 additions and 79 deletions

View File

@ -232,6 +232,9 @@ sequences for a double-quoted string are all supported in a regular expression.
TBD. TBD.
Octal character notation is not supported in a regular expression literal
since it conflicts with the backreference notation.
### Note ### ### Note ###
QSEAWK forms a token with the lognest valid sequences. QSEAWK forms a token with the lognest valid sequences.

View File

@ -1243,7 +1243,8 @@ enum qse_awk_errnum_t
QSE_AWK_EOFMTCHR, /**< invalid character in OFMT */ QSE_AWK_EOFMTCHR, /**< invalid character in OFMT */
/* regular expression error */ /* regular expression error */
QSE_AWK_EREXNOCOMP, /**< no regular expression compiled */ QSE_AWK_EREXBL, /**< failed to build regular expression */
QSE_AWK_EREXMA, /**< failed to match regular expression */
QSE_AWK_EREXRECUR, /**< recursion too deep */ QSE_AWK_EREXRECUR, /**< recursion too deep */
QSE_AWK_EREXRPAREN, /**< a right parenthesis is expected */ QSE_AWK_EREXRPAREN, /**< a right parenthesis is expected */
QSE_AWK_EREXRBRACK, /**< a right bracket is expected */ QSE_AWK_EREXRBRACK, /**< a right bracket is expected */

View File

@ -79,12 +79,17 @@ enum qse_tre_cflag_t
QSE_TRE_RIGHTASSOC = (1 << 5), QSE_TRE_RIGHTASSOC = (1 << 5),
QSE_TRE_UNGREEDY = (1 << 6), QSE_TRE_UNGREEDY = (1 << 6),
/* Disable {n,m} occrrence specifier
* in the QSE_TRE_EXTENDED mode.
* it doesn't affect the BRE's \{\}. */
QSE_TRE_NOBOUND = (1 << 7),
/* Enable non-standard extensions: /* Enable non-standard extensions:
* - Enable (?:text) for no submatch backreference. * - Enable (?:text) for no submatch backreference.
* - Enable perl-like (?...) extensions like (?i) * - Enable perl-like (?...) extensions like (?i)
* if QSE_TRE_EXTENDED is also set. * if QSE_TRE_EXTENDED is also set.
*/ */
QSE_TRE_NONSTDEXT = (1 << 7) QSE_TRE_NONSTDEXT = (1 << 8)
}; };
enum qse_tre_eflag_t enum qse_tre_eflag_t

View File

@ -352,10 +352,4 @@ struct qse_awk_mod_data_t
qse_awk_mod_t mod; qse_awk_mod_t mod;
}; };
#define QSE_AWK_FREEREX(awk,code) qse_freerex((awk)->mmgr,code)
#define QSE_AWK_BUILDREX(awk,ptn,len,errnum) \
qse_awk_buildrex(awk,ptn,len,errnum)
#define QSE_AWK_MATCHREX(awk,code,option,str,substr,match,errnum) \
qse_awk_matchrex(awk,code,option,str,substr,match,errnum)
#endif #endif

View File

@ -141,7 +141,8 @@ const qse_char_t* qse_awk_dflerrstr (const qse_awk_t* awk, qse_awk_errnum_t errn
QSE_T("invalid character in CONVFMT"), QSE_T("invalid character in CONVFMT"),
QSE_T("invalid character in OFMT"), QSE_T("invalid character in OFMT"),
QSE_T("no regular expression compiled"), QSE_T("failed to build regular expression"),
QSE_T("failed to match regular expression"),
QSE_T("recursion too deep in regular expression"), QSE_T("recursion too deep in regular expression"),
QSE_T("right parenthesis expected in regular expression"), QSE_T("right parenthesis expected in regular expression"),
QSE_T("right bracket expected in regular expression"), QSE_T("right bracket expected in regular expression"),

View File

@ -738,7 +738,7 @@ static int fnc_split (qse_awk_rtx_t* run, const qse_awk_fnc_info_t* fi)
if (fs.len > 1) if (fs.len > 1)
{ {
fs_rex = QSE_AWK_BUILDREX ( fs_rex = qse_awk_buildrex (
run->awk, fs.ptr, fs.len, &errnum); run->awk, fs.ptr, fs.len, &errnum);
if (fs_rex == QSE_NULL) if (fs_rex == QSE_NULL)
{ {
@ -816,7 +816,7 @@ static int fnc_split (qse_awk_rtx_t* run, const qse_awk_fnc_info_t* fi)
if (str_free) QSE_AWK_FREE (run->awk, str_free); if (str_free) QSE_AWK_FREE (run->awk, str_free);
if (fs_free) QSE_AWK_FREE (run->awk, fs_free); if (fs_free) QSE_AWK_FREE (run->awk, fs_free);
if (fs_rex_free) QSE_AWK_FREEREX (run->awk, fs_rex_free); if (fs_rex_free) qse_awk_freerex (run->awk, fs_rex_free);
/*nflds--;*/ /*nflds--;*/
@ -829,7 +829,7 @@ static int fnc_split (qse_awk_rtx_t* run, const qse_awk_fnc_info_t* fi)
oops: oops:
if (str_free) QSE_AWK_FREE (run->awk, str_free); if (str_free) QSE_AWK_FREE (run->awk, str_free);
if (fs_free) QSE_AWK_FREE (run->awk, fs_free); if (fs_free) QSE_AWK_FREE (run->awk, fs_free);
if (fs_rex_free) QSE_AWK_FREEREX (run->awk, fs_rex_free); if (fs_rex_free) qse_awk_freerex (run->awk, fs_rex_free);
return -1; return -1;
} }
@ -1033,7 +1033,7 @@ static int __substitute (qse_awk_rtx_t* run, qse_long_t max_count)
{ {
qse_awk_errnum_t errnum; qse_awk_errnum_t errnum;
rex = QSE_AWK_BUILDREX ( rex = qse_awk_buildrex (
run->awk, s0.ptr, s0.len, &errnum); run->awk, s0.ptr, s0.len, &errnum);
if (rex == QSE_NULL) if (rex == QSE_NULL)
{ {
@ -1064,7 +1064,7 @@ static int __substitute (qse_awk_rtx_t* run, qse_long_t max_count)
if (max_count == 0 || sub_count < max_count) if (max_count == 0 || sub_count < max_count)
{ {
n = QSE_AWK_MATCHREX ( n = qse_awk_matchrex (
run->awk, rex, opt, &s2, &cur, &mat, &errnum run->awk, rex, opt, &s2, &cur, &mat, &errnum
); );
} }
@ -1153,7 +1153,7 @@ static int __substitute (qse_awk_rtx_t* run, qse_long_t max_count)
if (rex_free) if (rex_free)
{ {
QSE_AWK_FREEREX (run->awk, rex_free); qse_awk_freerex (run->awk, rex_free);
rex_free = QSE_NULL; rex_free = QSE_NULL;
} }
@ -1199,7 +1199,7 @@ static int __substitute (qse_awk_rtx_t* run, qse_long_t max_count)
return 0; return 0;
oops: oops:
if (rex_free) QSE_AWK_FREEREX (run->awk, rex_free); if (rex_free) qse_awk_freerex (run->awk, rex_free);
if (new_inited) qse_str_fini (&new); if (new_inited) qse_str_fini (&new);
if (s2_free) QSE_AWK_FREE (run->awk, s2_free); if (s2_free) QSE_AWK_FREE (run->awk, s2_free);
if (s1_free) QSE_AWK_FREE (run->awk, s1_free); if (s1_free) QSE_AWK_FREE (run->awk, s1_free);
@ -1295,7 +1295,7 @@ static int fnc_match (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
} }
} }
rex = QSE_AWK_BUILDREX (rtx->awk, str1, len1, &errnum); rex = qse_awk_buildrex (rtx->awk, str1, len1, &errnum);
if (rex == QSE_NULL) if (rex == QSE_NULL)
{ {
if (a0->type != QSE_AWK_VAL_STR) if (a0->type != QSE_AWK_VAL_STR)
@ -1318,7 +1318,7 @@ static int fnc_match (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
/*TODO: must use str0,len0?*/ /*TODO: must use str0,len0?*/
tmp.ptr = str0 + start - 1; tmp.ptr = str0 + start - 1;
tmp.len = len0 - start + 1; tmp.len = len0 - start + 1;
n = QSE_AWK_MATCHREX ( n = qse_awk_matchrex (
rtx->awk, rex, rtx->awk, rex,
(rtx->gbl.ignorecase? QSE_REX_IGNORECASE: 0), (rtx->gbl.ignorecase? QSE_REX_IGNORECASE: 0),
&tmp, &tmp, &mat, &errnum &tmp, &tmp, &mat, &errnum
@ -1326,7 +1326,7 @@ static int fnc_match (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
} }
if (a0->type != QSE_AWK_VAL_STR) QSE_AWK_FREE (rtx->awk, str0); if (a0->type != QSE_AWK_VAL_STR) QSE_AWK_FREE (rtx->awk, str0);
if (a1->type != QSE_AWK_VAL_REX) QSE_AWK_FREEREX (rtx->awk, rex); if (a1->type != QSE_AWK_VAL_REX) qse_awk_freerex (rtx->awk, rex);
if (n <= -1) if (n <= -1)
{ {

View File

@ -20,6 +20,14 @@
#include "awk.h" #include "awk.h"
#define USE_REX
#if defined(USE_REX)
# include <qse/cmn/rex.h>
#else
# include <qse/cmn/tre.h>
#endif
void* qse_awk_allocmem (qse_awk_t* awk, qse_size_t size) void* qse_awk_allocmem (qse_awk_t* awk, qse_size_t size)
{ {
void* ptr = QSE_AWK_ALLOC (awk, size); void* ptr = QSE_AWK_ALLOC (awk, size);
@ -883,7 +891,7 @@ qse_char_t* qse_awk_rtx_strxntokbyrex (
while (cursub.len > 0) while (cursub.len > 0)
{ {
n = QSE_AWK_MATCHREX ( n = qse_awk_matchrex (
rtx->awk, rex, rtx->awk, rex,
((rtx->gbl.ignorecase)? QSE_REX_IGNORECASE: 0), ((rtx->gbl.ignorecase)? QSE_REX_IGNORECASE: 0),
&s, &cursub, &match, errnum); &s, &cursub, &match, errnum);
@ -1061,51 +1069,162 @@ qse_char_t* qse_awk_rtx_strxnfld (
return QSE_NULL; return QSE_NULL;
} }
#define QSE_AWK_REXERRTOERR(err) \ static QSE_INLINE int rexerr_to_errnum (int err)
((err == QSE_REX_ENOERR)? QSE_AWK_ENOERR: \ {
(err == QSE_REX_ENOMEM)? QSE_AWK_ENOMEM: \ switch (err)
(err == QSE_REX_ENOCOMP)? QSE_AWK_EREXNOCOMP: \ {
(err == QSE_REX_ERECUR)? QSE_AWK_EREXRECUR: \ case QSE_REX_ENOERR: return QSE_AWK_ENOERR;
(err == QSE_REX_ERPAREN)? QSE_AWK_EREXRPAREN: \ case QSE_REX_ENOMEM: return QSE_AWK_ENOMEM;
(err == QSE_REX_ERBRACK)? QSE_AWK_EREXRBRACK: \ case QSE_REX_ENOCOMP: return QSE_AWK_EREXBL;
(err == QSE_REX_ERBRACE)? QSE_AWK_EREXRBRACE: \ case QSE_REX_ERECUR: return QSE_AWK_EREXRECUR;
(err == QSE_REX_ECOLON)? QSE_AWK_EREXCOLON: \ case QSE_REX_ERPAREN: return QSE_AWK_EREXRPAREN;
(err == QSE_REX_ECRANGE)? QSE_AWK_EREXCRANGE: \ case QSE_REX_ERBRACK: return QSE_AWK_EREXRBRACK;
(err == QSE_REX_ECCLASS)? QSE_AWK_EREXCCLASS: \ case QSE_REX_ERBRACE: return QSE_AWK_EREXRBRACE;
(err == QSE_REX_EBOUND)? QSE_AWK_EREXBOUND: \ case QSE_REX_ECOLON: return QSE_AWK_EREXCOLON;
(err == QSE_REX_ESPCAWP)? QSE_AWK_EREXSPCAWP: \ case QSE_REX_ECRANGE: return QSE_AWK_EREXCRANGE;
(err == QSE_REX_EPREEND)? QSE_AWK_EREXPREEND: \ case QSE_REX_ECCLASS: return QSE_AWK_EREXCCLASS;
QSE_AWK_EINTERN) case QSE_REX_EBOUND: return QSE_AWK_EREXBOUND;
case QSE_REX_ESPCAWP: return QSE_AWK_EREXSPCAWP;
case QSE_REX_EPREEND: return QSE_AWK_EREXPREEND;
default: return QSE_AWK_EINTERN;
}
}
void* qse_awk_buildrex ( void* qse_awk_buildrex (
qse_awk_t* awk, const qse_char_t* ptn, qse_awk_t* awk, const qse_char_t* ptn,
qse_size_t len, qse_awk_errnum_t* errnum) qse_size_t len, qse_awk_errnum_t* errnum)
{ {
#if defined(USE_REX)
qse_rex_errnum_t err; qse_rex_errnum_t err;
void* p; void* p;
p = qse_buildrex ( p = qse_buildrex (
awk->mmgr, awk->opt.depth.s.rex_build, awk->mmgr, awk->opt.depth.s.rex_build,
((awk->opt.trait&QSE_AWK_REXBOUND)? 0: QSE_REX_NOBOUND), ((awk->opt.trait & QSE_AWK_REXBOUND)? 0: QSE_REX_NOBOUND),
ptn, len, &err ptn, len, &err
); );
if (p == QSE_NULL) *errnum = QSE_AWK_REXERRTOERR(err); if (p == QSE_NULL) *errnum = rexerr_to_errnum(err);
return p; return p;
#else
qse_tre_t* tre;
int opt = QSE_TRE_EXTENDED;
tre = qse_tre_open (awk->mmgr, 0);
if (tre == QSE_NULL)
{
*errnum = QSE_AWK_ENOMEM;
return QSE_NULL;
}
/* ignorecase is a compile option for TRE */
#if 0 /* TODO */
if (ignorecase) opt |= QSE_TRE_IGNORECASE;
#endif
if (!(awk->opt.trait & QSE_AWK_REXBOUND)) opt |= QSE_TRE_NOBOUND;
if (qse_tre_compx (tre, ptn, len, QSE_NULL, opt) <= -1)
{
#if 0 /* TODO */
if (QSE_TRE_ERRNUM(tre) == QSE_TRE_ENOMEM) *errnum = QSE_AWK_ENOMEM;
else
SETERR1 (awk, QSE_AWK_EREXBL, str->ptr, str->len, loc);
#endif
*errnum = (QSE_TRE_ERRNUM(tre) == QSE_TRE_ENOMEM)?
QSE_AWK_ENOMEM: QSE_AWK_EREXBL;
qse_tre_close (tre);
return QSE_NULL;
}
return tre;
#endif
} }
#if !defined(USE_REX)
static int matchtre (
qse_awk_t* awk, qse_tre_t* tre, int opt,
const qse_cstr_t* str, qse_cstr_t* mat,
qse_cstr_t submat[9], qse_awk_errnum_t* errnum)
{
int n;
qse_tre_match_t match[10] = { { 0, 0 }, };
n = qse_tre_execx (tre, str->ptr, str->len, match, QSE_COUNTOF(match), opt);
if (n <= -1)
{
if (QSE_TRE_ERRNUM(tre) == QSE_TRE_ENOMATCH) return 0;
#if 0 /* TODO: */
*errnum = (QSE_TRE_ERRNUM(tre) == QSE_TRE_ENOMEM)?
QSE_AWK_ENOMEM: QSE_AWK_EREXMA;
SETERR0 (sed, errnum, loc);
#endif
*errnum = (QSE_TRE_ERRNUM(tre) == QSE_TRE_ENOMEM)?
QSE_AWK_ENOMEM: QSE_AWK_EREXMA;
return -1;
}
QSE_ASSERT (match[0].rm_so != -1);
if (mat)
{
mat->ptr = &str->ptr[match[0].rm_so];
mat->len = match[0].rm_eo - match[0].rm_so;
}
if (submat)
{
int i;
/* you must intialize submat before you pass into this
* function because it can abort filling */
for (i = 1; i < QSE_COUNTOF(match); i++)
{
if (match[i].rm_so != -1)
{
submat[i-1].ptr = &str->ptr[match[i].rm_so];
submat[i-1].len = match[i].rm_eo - match[i].rm_so;
}
}
}
return 1;
}
#endif
int qse_awk_matchrex ( int qse_awk_matchrex (
qse_awk_t* awk, void* code, int option, qse_awk_t* awk, void* code, int option,
const qse_cstr_t* str, const qse_cstr_t* substr, const qse_cstr_t* str, const qse_cstr_t* substr,
qse_cstr_t* match, qse_awk_errnum_t* errnum) qse_cstr_t* match, qse_awk_errnum_t* errnum)
{ {
#if defined(USE_REX)
int x; int x;
qse_rex_errnum_t err; qse_rex_errnum_t err;
x = qse_matchrex ( x = qse_matchrex (
awk->mmgr, awk->opt.depth.s.rex_match, awk->mmgr, awk->opt.depth.s.rex_match,
code, option, str, substr, match, &err); code, option, str, substr, match, &err);
if (x <= -1) *errnum = QSE_AWK_REXERRTOERR(err); if (x <= -1) *errnum = rexerr_to_errnum(err);
return x; return x;
#else
int x;
int opt = QSE_TRE_BACKTRACKING; /* TODO: option... QSE_TRE_BACKTRACKING ??? */
x = matchtre (
awk, code,
((str->ptr == substr->ptr)? opt: (opt | QSE_TRE_NOTBOL)),
substr, match, QSE_NULL, errnum
);
return x;
#endif
}
void qse_awk_freerex (qse_awk_t* awk, void* code)
{
#if defined(USE_REX)
qse_freerex((awk)->mmgr,code);
#else
qse_tre_close (code);
#endif
} }
void* qse_awk_rtx_allocmem (qse_awk_rtx_t* rtx, qse_size_t size) void* qse_awk_rtx_allocmem (qse_awk_rtx_t* rtx, qse_size_t size)

View File

@ -76,6 +76,8 @@ int qse_awk_matchrex (
qse_cstr_t* match, qse_awk_errnum_t* errnum qse_cstr_t* match, qse_awk_errnum_t* errnum
); );
void qse_awk_freerex (qse_awk_t* awk, void* code);
int qse_awk_sprintflt ( int qse_awk_sprintflt (
qse_awk_t* awk, qse_awk_t* awk,
qse_char_t* buf, qse_char_t* buf,

View File

@ -4340,9 +4340,8 @@ static qse_awk_nde_t* parse_primary_rex (qse_awk_t* awk, const qse_awk_loc_t* x
nde->str.ptr = qse_awk_cstrdup (awk, QSE_STR_CSTR(awk->tok.name)); nde->str.ptr = qse_awk_cstrdup (awk, QSE_STR_CSTR(awk->tok.name));
if (nde->str.ptr == QSE_NULL) goto oops; if (nde->str.ptr == QSE_NULL) goto oops;
nde->code = QSE_AWK_BUILDREX (awk, nde->code = qse_awk_buildrex (
QSE_STR_PTR(awk->tok.name), QSE_STR_LEN(awk->tok.name), awk, QSE_STR_PTR(awk->tok.name), QSE_STR_LEN(awk->tok.name), &errnum);
&errnum);
if (nde->code == QSE_NULL) if (nde->code == QSE_NULL)
{ {
SETERR_LOC (awk, errnum, xloc); SETERR_LOC (awk, errnum, xloc);
@ -4355,7 +4354,7 @@ static qse_awk_nde_t* parse_primary_rex (qse_awk_t* awk, const qse_awk_loc_t* x
oops: oops:
QSE_ASSERT (nde != QSE_NULL); QSE_ASSERT (nde != QSE_NULL);
if (nde->code) QSE_AWK_FREEREX (awk, nde->code); if (nde->code) qse_awk_freerex (awk, nde->code);
if (nde->str.ptr) QSE_AWK_FREE (awk, nde->str.ptr); if (nde->str.ptr) QSE_AWK_FREE (awk, nde->str.ptr);
QSE_AWK_FREE (awk, nde); QSE_AWK_FREE (awk, nde);
return QSE_NULL; return QSE_NULL;
@ -5609,8 +5608,10 @@ static int get_string (
else if (c == QSE_T('b')) c = QSE_T('\b'); else if (c == QSE_T('b')) c = QSE_T('\b');
else if (c == QSE_T('v')) c = QSE_T('\v'); else if (c == QSE_T('v')) c = QSE_T('\v');
else if (c == QSE_T('a')) c = QSE_T('\a'); else if (c == QSE_T('a')) c = QSE_T('\a');
else if (c >= QSE_T('0') && c <= QSE_T('7')) else if (c >= QSE_T('0') && c <= QSE_T('7') && end_char != QSE_T('/'))
{ {
/* i don't support the octal notation for a regular expression.
* it conflicts with the backreference notation between \1 and \7 inclusive. */
escaped = 3; escaped = 3;
digit_count = 1; digit_count = 1;
c_acc = c - QSE_T('0'); c_acc = c - QSE_T('0');

View File

@ -225,7 +225,7 @@ static QSE_INLINE int match_long_rs (
QSE_ASSERT (run->gbl.rs != QSE_NULL); QSE_ASSERT (run->gbl.rs != QSE_NULL);
ret = QSE_AWK_MATCHREX ( ret = qse_awk_matchrex (
run->awk, run->gbl.rs, run->awk, run->gbl.rs,
((run->gbl.ignorecase)? QSE_REX_IGNORECASE: 0), ((run->gbl.ignorecase)? QSE_REX_IGNORECASE: 0),
QSE_STR_CSTR(buf), QSE_STR_CSTR(buf), QSE_STR_CSTR(buf), QSE_STR_CSTR(buf),

View File

@ -422,7 +422,7 @@ static int set_global (
void* rex; void* rex;
qse_awk_errnum_t errnum; qse_awk_errnum_t errnum;
rex = QSE_AWK_BUILDREX ( rex = qse_awk_buildrex (
rtx->awk, fs_ptr, fs_len, &errnum); rtx->awk, fs_ptr, fs_len, &errnum);
if (rex == QSE_NULL) if (rex == QSE_NULL)
{ {
@ -433,7 +433,7 @@ static int set_global (
} }
if (rtx->gbl.fs != QSE_NULL) if (rtx->gbl.fs != QSE_NULL)
QSE_AWK_FREEREX (rtx->awk, rtx->gbl.fs); qse_awk_freerex (rtx->awk, rtx->gbl.fs);
rtx->gbl.fs = rex; rtx->gbl.fs = rex;
} }
@ -571,7 +571,7 @@ static int set_global (
if (rtx->gbl.rs) if (rtx->gbl.rs)
{ {
QSE_AWK_FREEREX (rtx->awk, rtx->gbl.rs); qse_awk_freerex (rtx->awk, rtx->gbl.rs);
rtx->gbl.rs = QSE_NULL; rtx->gbl.rs = QSE_NULL;
} }
@ -581,7 +581,7 @@ static int set_global (
qse_awk_errnum_t errnum; qse_awk_errnum_t errnum;
/* compile the regular expression */ /* compile the regular expression */
rex = QSE_AWK_BUILDREX ( rex = qse_awk_buildrex (
rtx->awk, rss.ptr, rss.len, &errnum); rtx->awk, rss.ptr, rss.len, &errnum);
if (rex == QSE_NULL) if (rex == QSE_NULL)
{ {
@ -1007,12 +1007,12 @@ static void fini_rtx (qse_awk_rtx_t* rtx, int fini_globals)
if (rtx->gbl.rs) if (rtx->gbl.rs)
{ {
QSE_AWK_FREEREX (rtx->awk, rtx->gbl.rs); qse_awk_freerex (rtx->awk, rtx->gbl.rs);
rtx->gbl.rs = QSE_NULL; rtx->gbl.rs = QSE_NULL;
} }
if (rtx->gbl.fs) if (rtx->gbl.fs)
{ {
QSE_AWK_FREEREX (rtx->awk, rtx->gbl.fs); qse_awk_freerex (rtx->awk, rtx->gbl.fs);
rtx->gbl.fs = QSE_NULL; rtx->gbl.fs = QSE_NULL;
} }
@ -3173,7 +3173,7 @@ static qse_awk_val_t* eval_expression (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
vs.len = ((qse_awk_val_str_t*)rtx->inrec.d0)->val.len; vs.len = ((qse_awk_val_str_t*)rtx->inrec.d0)->val.len;
} }
n = QSE_AWK_MATCHREX ( n = qse_awk_matchrex (
((qse_awk_rtx_t*)rtx)->awk, ((qse_awk_rtx_t*)rtx)->awk,
((qse_awk_val_rex_t*)v)->code, ((qse_awk_val_rex_t*)v)->code,
opt, &vs, &vs, QSE_NULL, &errnum opt, &vs, &vs, QSE_NULL, &errnum
@ -4852,7 +4852,7 @@ static qse_awk_val_t* eval_binop_match0 (
} }
else if (right->type == QSE_AWK_VAL_STR) else if (right->type == QSE_AWK_VAL_STR)
{ {
rex_code = QSE_AWK_BUILDREX ( rex_code = qse_awk_buildrex (
rtx->awk, rtx->awk,
((qse_awk_val_str_t*)right)->val.ptr, ((qse_awk_val_str_t*)right)->val.ptr,
((qse_awk_val_str_t*)right)->val.len, &errnum); ((qse_awk_val_str_t*)right)->val.len, &errnum);
@ -4869,7 +4869,7 @@ static qse_awk_val_t* eval_binop_match0 (
out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP; out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP;
if (qse_awk_rtx_valtostr (rtx, right, &out) <= -1) return QSE_NULL; if (qse_awk_rtx_valtostr (rtx, right, &out) <= -1) return QSE_NULL;
rex_code = QSE_AWK_BUILDREX ( rex_code = qse_awk_buildrex (
rtx->awk, out.u.cpldup.ptr, out.u.cpldup.len, &errnum); rtx->awk, out.u.cpldup.ptr, out.u.cpldup.len, &errnum);
if (rex_code == QSE_NULL) if (rex_code == QSE_NULL)
{ {
@ -4883,7 +4883,7 @@ static qse_awk_val_t* eval_binop_match0 (
if (left->type == QSE_AWK_VAL_STR) if (left->type == QSE_AWK_VAL_STR)
{ {
n = QSE_AWK_MATCHREX ( n = qse_awk_matchrex (
rtx->awk, rex_code, rtx->awk, rex_code,
((rtx->gbl.ignorecase)? QSE_REX_IGNORECASE: 0), ((rtx->gbl.ignorecase)? QSE_REX_IGNORECASE: 0),
xstr_to_cstr(&((qse_awk_val_str_t*)left)->val), xstr_to_cstr(&((qse_awk_val_str_t*)left)->val),
@ -4892,7 +4892,7 @@ static qse_awk_val_t* eval_binop_match0 (
if (n == -1) if (n == -1)
{ {
if (right->type != QSE_AWK_VAL_REX) if (right->type != QSE_AWK_VAL_REX)
QSE_AWK_FREEREX (rtx->awk, rex_code); qse_awk_freerex (rtx->awk, rex_code);
SETERR_LOC (rtx, errnum, lloc); SETERR_LOC (rtx, errnum, lloc);
return QSE_NULL; return QSE_NULL;
@ -4902,7 +4902,7 @@ static qse_awk_val_t* eval_binop_match0 (
if (res == QSE_NULL) if (res == QSE_NULL)
{ {
if (right->type != QSE_AWK_VAL_REX) if (right->type != QSE_AWK_VAL_REX)
QSE_AWK_FREEREX (rtx->awk, rex_code); qse_awk_freerex (rtx->awk, rex_code);
ADJERR_LOC (rtx, lloc); ADJERR_LOC (rtx, lloc);
return QSE_NULL; return QSE_NULL;
@ -4916,11 +4916,11 @@ static qse_awk_val_t* eval_binop_match0 (
if (qse_awk_rtx_valtostr (rtx, left, &out) <= -1) if (qse_awk_rtx_valtostr (rtx, left, &out) <= -1)
{ {
if (right->type != QSE_AWK_VAL_REX) if (right->type != QSE_AWK_VAL_REX)
QSE_AWK_FREEREX (rtx->awk, rex_code); qse_awk_freerex (rtx->awk, rex_code);
return QSE_NULL; return QSE_NULL;
} }
n = QSE_AWK_MATCHREX ( n = qse_awk_matchrex (
rtx->awk, rex_code, rtx->awk, rex_code,
((rtx->gbl.ignorecase)? QSE_REX_IGNORECASE: 0), ((rtx->gbl.ignorecase)? QSE_REX_IGNORECASE: 0),
xstr_to_cstr(&out.u.cpldup), xstr_to_cstr(&out.u.cpldup),
@ -4931,7 +4931,7 @@ static qse_awk_val_t* eval_binop_match0 (
{ {
QSE_AWK_FREE (rtx->awk, out.u.cpldup.ptr); QSE_AWK_FREE (rtx->awk, out.u.cpldup.ptr);
if (right->type != QSE_AWK_VAL_REX) if (right->type != QSE_AWK_VAL_REX)
QSE_AWK_FREEREX (rtx->awk, rex_code); qse_awk_freerex (rtx->awk, rex_code);
SETERR_LOC (rtx, errnum, lloc); SETERR_LOC (rtx, errnum, lloc);
return QSE_NULL; return QSE_NULL;
@ -4942,7 +4942,7 @@ static qse_awk_val_t* eval_binop_match0 (
{ {
QSE_AWK_FREE (rtx->awk, out.u.cpldup.ptr); QSE_AWK_FREE (rtx->awk, out.u.cpldup.ptr);
if (right->type != QSE_AWK_VAL_REX) if (right->type != QSE_AWK_VAL_REX)
QSE_AWK_FREEREX (rtx->awk, rex_code); qse_awk_freerex (rtx->awk, rex_code);
ADJERR_LOC (rtx, lloc); ADJERR_LOC (rtx, lloc);
return QSE_NULL; return QSE_NULL;
@ -4951,7 +4951,7 @@ static qse_awk_val_t* eval_binop_match0 (
QSE_AWK_FREE (rtx->awk, out.u.cpldup.ptr); QSE_AWK_FREE (rtx->awk, out.u.cpldup.ptr);
} }
if (right->type != QSE_AWK_VAL_REX) QSE_AWK_FREEREX (rtx->awk, rex_code); if (right->type != QSE_AWK_VAL_REX) qse_awk_freerex (rtx->awk, rex_code);
return res; return res;
} }

View File

@ -1305,7 +1305,7 @@ void qse_awk_clrpt (qse_awk_t* awk, qse_awk_nde_t* tree)
case QSE_AWK_NDE_REX: case QSE_AWK_NDE_REX:
{ {
QSE_AWK_FREEREX (awk, ((qse_awk_nde_rex_t*)p)->code); qse_awk_freerex (awk, ((qse_awk_nde_rex_t*)p)->code);
QSE_AWK_FREE (awk, ((qse_awk_nde_rex_t*)p)->str.ptr); QSE_AWK_FREE (awk, ((qse_awk_nde_rex_t*)p)->str.ptr);
QSE_AWK_FREE (awk, p); QSE_AWK_FREE (awk, p);
break; break;

View File

@ -832,7 +832,7 @@ void qse_awk_rtx_freeval (
/* code is just a pointer to a regular expression stored /* code is just a pointer to a regular expression stored
* in parse tree nodes. so don't free it. * in parse tree nodes. so don't free it.
QSE_AWK_FREEREX (rtx->awk, ((qse_awk_val_rex_t*)val)->code); qse_awk_freerex (rtx->awk, ((qse_awk_val_rex_t*)val)->code);
*/ */
QSE_AWK_FREE (rtx->awk, val); QSE_AWK_FREE (rtx->awk, val);

View File

@ -1690,10 +1690,8 @@ tre_make_trans(qse_mmgr_t* mmgr, tre_pos_and_tags_t *p1, tre_pos_and_tags_t *p2,
if (p1->neg_classes != NULL) if (p1->neg_classes != NULL)
{ {
for (i = 0; p1->neg_classes[i] != (tre_ctype_t)0; i++); for (i = 0; p1->neg_classes[i] != (tre_ctype_t)0; i++);
trans->neg_classes = trans->neg_classes = xmalloc(mmgr,sizeof(*trans->neg_classes) * (i + 1));
xmalloc(mmgr,sizeof(*trans->neg_classes) * (i + 1)); if (trans->neg_classes == NULL) return REG_ESPACE;
if (trans->neg_classes == NULL)
return REG_ESPACE;
for (i = 0; p1->neg_classes[i] != (tre_ctype_t)0; i++) for (i = 0; p1->neg_classes[i] != (tre_ctype_t)0; i++)
trans->neg_classes[i] = p1->neg_classes[i]; trans->neg_classes[i] = p1->neg_classes[i];
trans->neg_classes[i] = (tre_ctype_t)0; trans->neg_classes[i] = (tre_ctype_t)0;

View File

@ -400,7 +400,7 @@ retry:
/* Go to the next character in the input string. */ /* Go to the next character in the input string. */
empty_br_match = 0; empty_br_match = 0;
trans_i = state; trans_i = state;
if (trans_i->state && trans_i->assertions & ASSERT_BACKREF) if (trans_i->state && (trans_i->assertions & ASSERT_BACKREF))
{ {
/* This is a back reference state. All transitions leaving from /* This is a back reference state. All transitions leaving from
this state have the same back reference "assertion". Instead this state have the same back reference "assertion". Instead
@ -593,8 +593,7 @@ backtrack:
DPRINT((" backtracking\n")); DPRINT((" backtracking\n"));
if (stack->item.state->assertions && ASSERT_BACKREF) if (stack->item.state->assertions && ASSERT_BACKREF)
{ {
DPRINT((" states_seen[%d] = 0\n", DPRINT((" states_seen[%d] = 0\n", stack->item.state_id));
stack->item.state_id));
states_seen[stack->item.state_id] = 0; states_seen[stack->item.state_id] = 0;
} }

View File

@ -1174,14 +1174,16 @@ parse_star:
goto parse_star; goto parse_star;
} }
} }
else break; break;
/* END QSE */ /* END QSE */
case CHAR_LBRACE: case CHAR_LBRACE:
/* "{" is literal without REG_EXTENDED */ /* "{" is literal without REG_EXTENDED */
if (!(ctx->cflags & REG_EXTENDED)) if (!(ctx->cflags & REG_EXTENDED)) break;
break; /* QSE */
if (ctx->cflags & REG_NOBOUND) break;
/* END QSE */
parse_brace: parse_brace:
DPRINT(("tre_parse: bound: '%.*" STRF "'\n", DPRINT(("tre_parse: bound: '%.*" STRF "'\n",
@ -1194,6 +1196,7 @@ parse_brace:
STACK_PUSHX(stack, int, PARSE_POSTFIX); STACK_PUSHX(stack, int, PARSE_POSTFIX);
break; break;
} }
break; break;
case PARSE_ATOM: case PARSE_ATOM:
@ -1686,7 +1689,10 @@ parse_literal:
|| *ctx->re == CHAR_STAR || *ctx->re == CHAR_STAR
|| (ctx->cflags & REG_EXTENDED || (ctx->cflags & REG_EXTENDED
&& (*ctx->re == CHAR_PIPE && (*ctx->re == CHAR_PIPE
|| *ctx->re == CHAR_LBRACE /* QSE */
/*|| *ctx->re == CHAR_LBRACE*/
|| (*ctx->re == CHAR_LBRACE && !(ctx->cflags & REG_NOBOUND))
/* END QSE */
|| *ctx->re == CHAR_PLUS || *ctx->re == CHAR_PLUS
|| *ctx->re == CHAR_QUESTIONMARK)) || *ctx->re == CHAR_QUESTIONMARK))
/* Test for "\)" in BRE mode. */ /* Test for "\)" in BRE mode. */

View File

@ -202,7 +202,7 @@ static int tre_match(
} }
/* Dispatch to the appropriate matcher. */ /* Dispatch to the appropriate matcher. */
if (tnfa->have_backrefs || eflags & REG_BACKTRACKING_MATCHER) if (tnfa->have_backrefs || (eflags & REG_BACKTRACKING_MATCHER))
{ {
/* The regex has back references, use the backtracking matcher. */ /* The regex has back references, use the backtracking matcher. */
if (type == STR_USER) if (type == STR_USER)

View File

@ -208,6 +208,7 @@ typedef qse_cint_t tre_cint_t;
#define REG_LITERAL QSE_TRE_LITERAL #define REG_LITERAL QSE_TRE_LITERAL
#define REG_RIGHT_ASSOC QSE_TRE_RIGHTASSOC #define REG_RIGHT_ASSOC QSE_TRE_RIGHTASSOC
#define REG_UNGREEDY QSE_TRE_UNGREEDY #define REG_UNGREEDY QSE_TRE_UNGREEDY
#define REG_NOBOUND QSE_TRE_NOBOUND
#define REG_NONSTDEXT QSE_TRE_NONSTDEXT #define REG_NONSTDEXT QSE_TRE_NONSTDEXT
/* POSIX tre_regexec() flags. */ /* POSIX tre_regexec() flags. */

View File

@ -536,6 +536,21 @@ static QSE_INLINE int task_main_getdir (
); );
if (x) if (x)
{ {
#if 0
if (httpd->opt.trait & QSE_HTTPD_LOGACC)
{
qse_httpd_reqsum_t reqsum;
acc.remote = remote;
acc.qpath = qpath;
acc.status = 200;
acc.version = ...;
acc.method = ...;
httpd->opt.rcb.logacc (httpd, &reqsum);
}
#endif
/* arrange to send the actual directory contents */ /* arrange to send the actual directory contents */
x = entask_directory_segment (httpd, client, x, dir->handle, dir); x = entask_directory_segment (httpd, client, x, dir->handle, dir);
if (x) return 0; if (x) return 0;

View File

@ -605,7 +605,9 @@ qse_httpd_task_t* qse_httpd_entaskfile (
task.init = task_init_getfile; task.init = task_init_getfile;
task.main = task_main_getfile; task.main = task_main_getfile;
break;
task.ctx = &data;
return qse_httpd_entask (httpd, client, pred, &task, xtnsize);
case QSE_HTTP_PUT: case QSE_HTTP_PUT:
/* note that no partial update is supported for PUT */ /* note that no partial update is supported for PUT */
@ -614,7 +616,8 @@ qse_httpd_task_t* qse_httpd_entaskfile (
task.init = task_init_putfile; task.init = task_init_putfile;
task.main = task_main_putfile; task.main = task_main_putfile;
task.fini = task_fini_putfile; task.fini = task_fini_putfile;
break; task.ctx = &data;
return qse_httpd_entask (httpd, client, pred, &task, xtnsize);
case QSE_HTTP_DELETE: case QSE_HTTP_DELETE:
{ {
@ -637,7 +640,5 @@ qse_httpd_task_t* qse_httpd_entaskfile (
} }
task.ctx = &data;
return qse_httpd_entask (httpd, client, pred, &task, xtnsize);
} }