diff --git a/qse/doc/page/awk-lang.md b/qse/doc/page/awk-lang.md index 71ede6b0..c838e646 100644 --- a/qse/doc/page/awk-lang.md +++ b/qse/doc/page/awk-lang.md @@ -232,6 +232,9 @@ sequences for a double-quoted string are all supported in a regular expression. TBD. +Octal character notation is not supported in a regular expression literal +since it conflicts with the backreference notation. + ### Note ### QSEAWK forms a token with the lognest valid sequences. diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index ac5fad32..62d143ff 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -1243,7 +1243,8 @@ enum qse_awk_errnum_t QSE_AWK_EOFMTCHR, /**< invalid character in OFMT */ /* 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_EREXRPAREN, /**< a right parenthesis is expected */ QSE_AWK_EREXRBRACK, /**< a right bracket is expected */ diff --git a/qse/include/qse/cmn/tre.h b/qse/include/qse/cmn/tre.h index 57d527cf..a14f7a3a 100644 --- a/qse/include/qse/cmn/tre.h +++ b/qse/include/qse/cmn/tre.h @@ -79,12 +79,17 @@ enum qse_tre_cflag_t QSE_TRE_RIGHTASSOC = (1 << 5), 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 (?:text) for no submatch backreference. * - Enable perl-like (?...) extensions like (?i) * if QSE_TRE_EXTENDED is also set. */ - QSE_TRE_NONSTDEXT = (1 << 7) + QSE_TRE_NONSTDEXT = (1 << 8) }; enum qse_tre_eflag_t diff --git a/qse/lib/awk/awk.h b/qse/lib/awk/awk.h index ff024d3e..5998a291 100644 --- a/qse/lib/awk/awk.h +++ b/qse/lib/awk/awk.h @@ -352,10 +352,4 @@ struct qse_awk_mod_data_t 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 diff --git a/qse/lib/awk/err.c b/qse/lib/awk/err.c index 11d0063c..a188527c 100644 --- a/qse/lib/awk/err.c +++ b/qse/lib/awk/err.c @@ -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 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("right parenthesis expected in regular expression"), QSE_T("right bracket expected in regular expression"), diff --git a/qse/lib/awk/fnc.c b/qse/lib/awk/fnc.c index 11e6cf0c..f86f6dc3 100644 --- a/qse/lib/awk/fnc.c +++ b/qse/lib/awk/fnc.c @@ -738,7 +738,7 @@ static int fnc_split (qse_awk_rtx_t* run, const qse_awk_fnc_info_t* fi) if (fs.len > 1) { - fs_rex = QSE_AWK_BUILDREX ( + fs_rex = qse_awk_buildrex ( run->awk, fs.ptr, fs.len, &errnum); 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 (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--;*/ @@ -829,7 +829,7 @@ static int fnc_split (qse_awk_rtx_t* run, const qse_awk_fnc_info_t* fi) oops: if (str_free) QSE_AWK_FREE (run->awk, str_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; } @@ -1033,7 +1033,7 @@ static int __substitute (qse_awk_rtx_t* run, qse_long_t max_count) { qse_awk_errnum_t errnum; - rex = QSE_AWK_BUILDREX ( + rex = qse_awk_buildrex ( run->awk, s0.ptr, s0.len, &errnum); 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) { - n = QSE_AWK_MATCHREX ( + n = qse_awk_matchrex ( 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) { - QSE_AWK_FREEREX (run->awk, rex_free); + qse_awk_freerex (run->awk, rex_free); rex_free = QSE_NULL; } @@ -1199,7 +1199,7 @@ static int __substitute (qse_awk_rtx_t* run, qse_long_t max_count) return 0; 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 (s2_free) QSE_AWK_FREE (run->awk, s2_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 (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?*/ tmp.ptr = str0 + start - 1; tmp.len = len0 - start + 1; - n = QSE_AWK_MATCHREX ( + n = qse_awk_matchrex ( rtx->awk, rex, (rtx->gbl.ignorecase? QSE_REX_IGNORECASE: 0), &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 (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) { diff --git a/qse/lib/awk/misc.c b/qse/lib/awk/misc.c index a313e070..0758f9f3 100644 --- a/qse/lib/awk/misc.c +++ b/qse/lib/awk/misc.c @@ -20,6 +20,14 @@ #include "awk.h" +#define USE_REX + +#if defined(USE_REX) +# include +#else +# include +#endif + void* qse_awk_allocmem (qse_awk_t* awk, qse_size_t size) { void* ptr = QSE_AWK_ALLOC (awk, size); @@ -883,7 +891,7 @@ qse_char_t* qse_awk_rtx_strxntokbyrex ( while (cursub.len > 0) { - n = QSE_AWK_MATCHREX ( + n = qse_awk_matchrex ( rtx->awk, rex, ((rtx->gbl.ignorecase)? QSE_REX_IGNORECASE: 0), &s, &cursub, &match, errnum); @@ -1061,51 +1069,162 @@ qse_char_t* qse_awk_rtx_strxnfld ( return QSE_NULL; } -#define QSE_AWK_REXERRTOERR(err) \ - ((err == QSE_REX_ENOERR)? QSE_AWK_ENOERR: \ - (err == QSE_REX_ENOMEM)? QSE_AWK_ENOMEM: \ - (err == QSE_REX_ENOCOMP)? QSE_AWK_EREXNOCOMP: \ - (err == QSE_REX_ERECUR)? QSE_AWK_EREXRECUR: \ - (err == QSE_REX_ERPAREN)? QSE_AWK_EREXRPAREN: \ - (err == QSE_REX_ERBRACK)? QSE_AWK_EREXRBRACK: \ - (err == QSE_REX_ERBRACE)? QSE_AWK_EREXRBRACE: \ - (err == QSE_REX_ECOLON)? QSE_AWK_EREXCOLON: \ - (err == QSE_REX_ECRANGE)? QSE_AWK_EREXCRANGE: \ - (err == QSE_REX_ECCLASS)? QSE_AWK_EREXCCLASS: \ - (err == QSE_REX_EBOUND)? QSE_AWK_EREXBOUND: \ - (err == QSE_REX_ESPCAWP)? QSE_AWK_EREXSPCAWP: \ - (err == QSE_REX_EPREEND)? QSE_AWK_EREXPREEND: \ - QSE_AWK_EINTERN) +static QSE_INLINE int rexerr_to_errnum (int err) +{ + switch (err) + { + case QSE_REX_ENOERR: return QSE_AWK_ENOERR; + case QSE_REX_ENOMEM: return QSE_AWK_ENOMEM; + case QSE_REX_ENOCOMP: return QSE_AWK_EREXBL; + case QSE_REX_ERECUR: return QSE_AWK_EREXRECUR; + case QSE_REX_ERPAREN: return QSE_AWK_EREXRPAREN; + case QSE_REX_ERBRACK: return QSE_AWK_EREXRBRACK; + case QSE_REX_ERBRACE: return QSE_AWK_EREXRBRACE; + case QSE_REX_ECOLON: return QSE_AWK_EREXCOLON; + case QSE_REX_ECRANGE: return QSE_AWK_EREXCRANGE; + case QSE_REX_ECCLASS: return QSE_AWK_EREXCCLASS; + 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 ( qse_awk_t* awk, const qse_char_t* ptn, qse_size_t len, qse_awk_errnum_t* errnum) { +#if defined(USE_REX) qse_rex_errnum_t err; void* p; p = qse_buildrex ( 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 ); - if (p == QSE_NULL) *errnum = QSE_AWK_REXERRTOERR(err); + if (p == QSE_NULL) *errnum = rexerr_to_errnum(err); 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 ( qse_awk_t* awk, void* code, int option, const qse_cstr_t* str, const qse_cstr_t* substr, qse_cstr_t* match, qse_awk_errnum_t* errnum) { +#if defined(USE_REX) int x; qse_rex_errnum_t err; x = qse_matchrex ( awk->mmgr, awk->opt.depth.s.rex_match, code, option, str, substr, match, &err); - if (x <= -1) *errnum = QSE_AWK_REXERRTOERR(err); + if (x <= -1) *errnum = rexerr_to_errnum(err); 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) diff --git a/qse/lib/awk/misc.h b/qse/lib/awk/misc.h index 04f8a54b..49a78563 100644 --- a/qse/lib/awk/misc.h +++ b/qse/lib/awk/misc.h @@ -76,6 +76,8 @@ int qse_awk_matchrex ( qse_cstr_t* match, qse_awk_errnum_t* errnum ); +void qse_awk_freerex (qse_awk_t* awk, void* code); + int qse_awk_sprintflt ( qse_awk_t* awk, qse_char_t* buf, diff --git a/qse/lib/awk/parse.c b/qse/lib/awk/parse.c index 268ac6eb..f717cb3f 100644 --- a/qse/lib/awk/parse.c +++ b/qse/lib/awk/parse.c @@ -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)); if (nde->str.ptr == QSE_NULL) goto oops; - nde->code = QSE_AWK_BUILDREX (awk, - QSE_STR_PTR(awk->tok.name), QSE_STR_LEN(awk->tok.name), - &errnum); + nde->code = qse_awk_buildrex ( + awk, QSE_STR_PTR(awk->tok.name), QSE_STR_LEN(awk->tok.name), &errnum); if (nde->code == QSE_NULL) { 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: 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); QSE_AWK_FREE (awk, nde); 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('v')) c = QSE_T('\v'); 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; digit_count = 1; c_acc = c - QSE_T('0'); diff --git a/qse/lib/awk/rio.c b/qse/lib/awk/rio.c index bf0049a9..fd074e8e 100644 --- a/qse/lib/awk/rio.c +++ b/qse/lib/awk/rio.c @@ -225,7 +225,7 @@ static QSE_INLINE int match_long_rs ( QSE_ASSERT (run->gbl.rs != QSE_NULL); - ret = QSE_AWK_MATCHREX ( + ret = qse_awk_matchrex ( run->awk, run->gbl.rs, ((run->gbl.ignorecase)? QSE_REX_IGNORECASE: 0), QSE_STR_CSTR(buf), QSE_STR_CSTR(buf), diff --git a/qse/lib/awk/run.c b/qse/lib/awk/run.c index cff58f38..d015b6fe 100644 --- a/qse/lib/awk/run.c +++ b/qse/lib/awk/run.c @@ -422,7 +422,7 @@ static int set_global ( void* rex; qse_awk_errnum_t errnum; - rex = QSE_AWK_BUILDREX ( + rex = qse_awk_buildrex ( rtx->awk, fs_ptr, fs_len, &errnum); if (rex == QSE_NULL) { @@ -433,7 +433,7 @@ static int set_global ( } 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; } @@ -571,7 +571,7 @@ static int set_global ( 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; } @@ -581,7 +581,7 @@ static int set_global ( qse_awk_errnum_t errnum; /* compile the regular expression */ - rex = QSE_AWK_BUILDREX ( + rex = qse_awk_buildrex ( rtx->awk, rss.ptr, rss.len, &errnum); if (rex == QSE_NULL) { @@ -1007,12 +1007,12 @@ static void fini_rtx (qse_awk_rtx_t* rtx, int fini_globals) 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; } 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; } @@ -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; } - n = QSE_AWK_MATCHREX ( + n = qse_awk_matchrex ( ((qse_awk_rtx_t*)rtx)->awk, ((qse_awk_val_rex_t*)v)->code, 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) { - rex_code = QSE_AWK_BUILDREX ( + rex_code = qse_awk_buildrex ( rtx->awk, ((qse_awk_val_str_t*)right)->val.ptr, ((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; 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); if (rex_code == QSE_NULL) { @@ -4883,7 +4883,7 @@ static qse_awk_val_t* eval_binop_match0 ( if (left->type == QSE_AWK_VAL_STR) { - n = QSE_AWK_MATCHREX ( + n = qse_awk_matchrex ( rtx->awk, rex_code, ((rtx->gbl.ignorecase)? QSE_REX_IGNORECASE: 0), 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 (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); return QSE_NULL; @@ -4902,7 +4902,7 @@ static qse_awk_val_t* eval_binop_match0 ( if (res == QSE_NULL) { 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); 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 (right->type != QSE_AWK_VAL_REX) - QSE_AWK_FREEREX (rtx->awk, rex_code); + qse_awk_freerex (rtx->awk, rex_code); return QSE_NULL; } - n = QSE_AWK_MATCHREX ( + n = qse_awk_matchrex ( rtx->awk, rex_code, ((rtx->gbl.ignorecase)? QSE_REX_IGNORECASE: 0), 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); 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); return QSE_NULL; @@ -4942,7 +4942,7 @@ static qse_awk_val_t* eval_binop_match0 ( { QSE_AWK_FREE (rtx->awk, out.u.cpldup.ptr); 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); return QSE_NULL; @@ -4951,7 +4951,7 @@ static qse_awk_val_t* eval_binop_match0 ( 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; } diff --git a/qse/lib/awk/tree.c b/qse/lib/awk/tree.c index 8c7493cd..28df3381 100644 --- a/qse/lib/awk/tree.c +++ b/qse/lib/awk/tree.c @@ -1305,7 +1305,7 @@ void qse_awk_clrpt (qse_awk_t* awk, qse_awk_nde_t* tree) 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, p); break; diff --git a/qse/lib/awk/val.c b/qse/lib/awk/val.c index 2d04e689..79fb52eb 100644 --- a/qse/lib/awk/val.c +++ b/qse/lib/awk/val.c @@ -832,7 +832,7 @@ void qse_awk_rtx_freeval ( /* code is just a pointer to a regular expression stored * 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); diff --git a/qse/lib/cmn/tre-compile.c b/qse/lib/cmn/tre-compile.c index 849ed64b..53dc3f8e 100644 --- a/qse/lib/cmn/tre-compile.c +++ b/qse/lib/cmn/tre-compile.c @@ -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) { for (i = 0; p1->neg_classes[i] != (tre_ctype_t)0; i++); - trans->neg_classes = - xmalloc(mmgr,sizeof(*trans->neg_classes) * (i + 1)); - if (trans->neg_classes == NULL) - return REG_ESPACE; + trans->neg_classes = xmalloc(mmgr,sizeof(*trans->neg_classes) * (i + 1)); + if (trans->neg_classes == NULL) return REG_ESPACE; for (i = 0; p1->neg_classes[i] != (tre_ctype_t)0; i++) trans->neg_classes[i] = p1->neg_classes[i]; trans->neg_classes[i] = (tre_ctype_t)0; diff --git a/qse/lib/cmn/tre-match-backtrack.c b/qse/lib/cmn/tre-match-backtrack.c index ddf55803..37d4367d 100644 --- a/qse/lib/cmn/tre-match-backtrack.c +++ b/qse/lib/cmn/tre-match-backtrack.c @@ -400,7 +400,7 @@ retry: /* 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) + 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 @@ -593,8 +593,7 @@ backtrack: DPRINT((" backtracking\n")); if (stack->item.state->assertions && ASSERT_BACKREF) { - DPRINT((" states_seen[%d] = 0\n", - stack->item.state_id)); + DPRINT((" states_seen[%d] = 0\n", stack->item.state_id)); states_seen[stack->item.state_id] = 0; } diff --git a/qse/lib/cmn/tre-parse.c b/qse/lib/cmn/tre-parse.c index dbc3c54d..9ad387db 100644 --- a/qse/lib/cmn/tre-parse.c +++ b/qse/lib/cmn/tre-parse.c @@ -1174,14 +1174,16 @@ parse_star: goto parse_star; } } - else break; + break; /* END QSE */ case CHAR_LBRACE: /* "{" is literal without REG_EXTENDED */ - if (!(ctx->cflags & REG_EXTENDED)) - break; + if (!(ctx->cflags & REG_EXTENDED)) break; + /* QSE */ + if (ctx->cflags & REG_NOBOUND) break; + /* END QSE */ parse_brace: DPRINT(("tre_parse: bound: '%.*" STRF "'\n", @@ -1194,6 +1196,7 @@ parse_brace: STACK_PUSHX(stack, int, PARSE_POSTFIX); break; } + break; case PARSE_ATOM: @@ -1686,7 +1689,10 @@ parse_literal: || *ctx->re == CHAR_STAR || (ctx->cflags & REG_EXTENDED && (*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_QUESTIONMARK)) /* Test for "\)" in BRE mode. */ diff --git a/qse/lib/cmn/tre.c b/qse/lib/cmn/tre.c index a0f01519..1e2afdff 100644 --- a/qse/lib/cmn/tre.c +++ b/qse/lib/cmn/tre.c @@ -202,7 +202,7 @@ static int tre_match( } /* 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. */ if (type == STR_USER) diff --git a/qse/lib/cmn/tre.h b/qse/lib/cmn/tre.h index e4155860..8d5bb03b 100644 --- a/qse/lib/cmn/tre.h +++ b/qse/lib/cmn/tre.h @@ -208,6 +208,7 @@ typedef qse_cint_t tre_cint_t; #define REG_LITERAL QSE_TRE_LITERAL #define REG_RIGHT_ASSOC QSE_TRE_RIGHTASSOC #define REG_UNGREEDY QSE_TRE_UNGREEDY +#define REG_NOBOUND QSE_TRE_NOBOUND #define REG_NONSTDEXT QSE_TRE_NONSTDEXT /* POSIX tre_regexec() flags. */ diff --git a/qse/lib/http/httpd-dir.c b/qse/lib/http/httpd-dir.c index cc3d6aa5..75833301 100644 --- a/qse/lib/http/httpd-dir.c +++ b/qse/lib/http/httpd-dir.c @@ -536,6 +536,21 @@ static QSE_INLINE int task_main_getdir ( ); 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 */ x = entask_directory_segment (httpd, client, x, dir->handle, dir); if (x) return 0; diff --git a/qse/lib/http/httpd-file.c b/qse/lib/http/httpd-file.c index 53c0c670..08f4161f 100644 --- a/qse/lib/http/httpd-file.c +++ b/qse/lib/http/httpd-file.c @@ -605,7 +605,9 @@ qse_httpd_task_t* qse_httpd_entaskfile ( task.init = task_init_getfile; task.main = task_main_getfile; - break; + + task.ctx = &data; + return qse_httpd_entask (httpd, client, pred, &task, xtnsize); case QSE_HTTP_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.main = task_main_putfile; task.fini = task_fini_putfile; - break; + task.ctx = &data; + return qse_httpd_entask (httpd, client, pred, &task, xtnsize); 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); }