fixed a parser bug in awk.
- handling of idiv operators - tokenization of /=/ as a regular expression - calling QSE_AWK_FREEREX to free compiled regular expressions. switched to a new regular expression handler.
This commit is contained in:
parent
93adbf9244
commit
faea2475ac
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: rex.h 311 2009-12-09 11:35:54Z hyunghwan.chung $
|
||||
* $Id: rex.h 312 2009-12-10 13:03:54Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -27,62 +27,59 @@
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Regular Esseression Syntax
|
||||
* A regular expression is zero or more branches, separated by '|'.
|
||||
* ......
|
||||
* ......
|
||||
* Regular Expression Syntax
|
||||
*
|
||||
* Compiled form of a regular expression:
|
||||
*
|
||||
* | expression |
|
||||
* | header | branch | branch | branch |
|
||||
* | nb | el | na | bl | cmd | arg | cmd | arg | na | bl | cmd | arg | na | bl | cmd |
|
||||
*
|
||||
* - nb: the number of branches
|
||||
* - el: the length of a expression including the length of nb and el
|
||||
* - na: the number of atoms
|
||||
* - bl: the length of a branch including the length of na and bl
|
||||
* - cmd: The command and repetition info encoded together.
|
||||
*
|
||||
* Some commands require an argument to follow them but some other don't.
|
||||
* It is encoded as follows:
|
||||
* .................
|
||||
* regular expression := branch_set
|
||||
* branch_set := branch [ '|' branch ]*
|
||||
* atom := char | '.' | '^' | '$' | subgroup
|
||||
* subgroup = '(' branch_set ')'
|
||||
* bound := '?' | '*' | '+' | {n,m}
|
||||
* bounded_atom := atom bound*
|
||||
* branch := bounded_atom bounded_atom*
|
||||
*
|
||||
* Subexpressions can be nested by having the command "GROUP"
|
||||
* and a subexpression as its argument.
|
||||
* Special escaping sequence includes:
|
||||
* \uXXXX, \XX, \000, \t, \n, \r, \v, ...
|
||||
*
|
||||
* Examples:
|
||||
* a.c -> |1|6|5|ORD_CHAR(no bound)|a|ANY_CHAR(no bound)|ORD_CHAR(no bound)|c|
|
||||
* ab|xy -> |2|10|4|ORD_CHAR(no bound)|a|ORD_CHAR(no bound)|b|4|ORD_CHAR(no bound)|x|ORD_CHAR(no bound)|y|
|
||||
* A special character preceded by a backslash loses its special role and
|
||||
* matches the character itself literally.
|
||||
*
|
||||
* Some examples of compiled regular expressions are shown below.
|
||||
*
|
||||
* @code
|
||||
* ab
|
||||
* START --@ NOP --@ CHAR(a) --@ CHAR(b) --@ END
|
||||
*
|
||||
* a(bc)d
|
||||
* START --@ NOP --@ CHAR(A) --@ GROUP --@ CHAR(d) --@ END
|
||||
* u.g.head => | @
|
||||
* | | <= u.g.end
|
||||
* | +---------------------------+
|
||||
* | | <= u.ge.group
|
||||
* @ @
|
||||
* NOP -@ CHAR(b) -@ CHAR(c) -@ GROUPEND
|
||||
*
|
||||
* ab|cd
|
||||
* +--@ CHAR(a) --@ CHAR(b) --+
|
||||
* | <= u.b.left |
|
||||
* START --@ NOP --@ BRANCH --+ +--@ END
|
||||
* | <= u.b.right |
|
||||
* +--@ CHAR(c) --@ CHAR(d) --+
|
||||
* @endcode
|
||||
*
|
||||
* @todo
|
||||
* - support \\n to refer to the nth matching substring
|
||||
*/
|
||||
|
||||
#define QSE_REX_NA(code) (*(qse_size_t*)(code))
|
||||
|
||||
#define QSE_REX_LEN(code) \
|
||||
(*(qse_size_t*)((qse_byte_t*)(code)+QSE_SIZEOF(qse_size_t)))
|
||||
|
||||
enum qse_rex_option_t
|
||||
{
|
||||
QSE_REX_BUILD_NOBOUND = (1 << 1),
|
||||
QSE_REX_MATCH_IGNORECASE = (1 << 8),
|
||||
|
||||
/**< do not allow a special character at normal character position */
|
||||
/**< do not allow a special character at normal character position. */
|
||||
QSE_REX_STRICT = (1 << 0),
|
||||
|
||||
/**< do not support the {n,m} style occurrence specifier */
|
||||
/**< do not support the {n,m} style occurrence specifier. */
|
||||
QSE_REX_NOBOUND = (1 << 1),
|
||||
|
||||
#if 0
|
||||
QSE_REX_ESQ_HEX = (1 << 1), /* \xhh and \uhhhh */
|
||||
QSE_REX_ESQ_OCTAL = (1 << 2), /* \000 */
|
||||
QSE_REX_ESQ_CNTRL = (1 << 3), /* \cX where X is A to Z */
|
||||
#endif
|
||||
|
||||
/**< perform case-insensitive match */
|
||||
QSE_REX_IGNORECASE = (1 << 8)
|
||||
QSE_REX_IGNORECASE = (1 << 2)
|
||||
};
|
||||
|
||||
enum qse_rex_errnum_t
|
||||
@ -125,7 +122,8 @@ struct qse_rex_node_t
|
||||
/* for internal management. not used for startnode */
|
||||
qse_rex_node_t* link;
|
||||
|
||||
/* connect to the next node in the graph */
|
||||
/* connect to the next node in the graph.
|
||||
* it is always NULL for a branch node. */
|
||||
qse_rex_node_t* next;
|
||||
|
||||
qse_rex_node_id_t id;
|
||||
@ -206,6 +204,29 @@ void qse_rex_close (
|
||||
qse_rex_t* rex
|
||||
);
|
||||
|
||||
qse_rex_t* qse_rex_init (
|
||||
qse_rex_t* rex,
|
||||
qse_mmgr_t* mmgr,
|
||||
qse_rex_node_t* code
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_rex_fini() function finalizes a statically initialized
|
||||
* regular expression object @a rex.
|
||||
*/
|
||||
void qse_rex_fini (
|
||||
qse_rex_t* rex
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_rex_yield() function gives up the ownership of a compiled regular
|
||||
* expression. Once yielded, the compiled regular expression is not destroyed
|
||||
* when @a rex is closed or finalized.
|
||||
* @return start node of a compiled regular expression
|
||||
*/
|
||||
qse_rex_node_t* qse_rex_yield (
|
||||
qse_rex_t* rex /**< regular expression processor */
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_rex_getoption() function returns the current options.
|
||||
@ -243,6 +264,7 @@ int qse_rex_exec (
|
||||
qse_cstr_t* matstr
|
||||
);
|
||||
|
||||
|
||||
void* qse_buildrex (
|
||||
qse_mmgr_t* mmgr,
|
||||
qse_size_t depth,
|
||||
@ -270,14 +292,6 @@ void qse_freerex (
|
||||
void* code
|
||||
);
|
||||
|
||||
qse_bool_t qse_isemptyrex (
|
||||
void* code
|
||||
);
|
||||
|
||||
#if 0
|
||||
void qse_dprintrex (qse_rex_t* rex, void* rex);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: awk.h 291 2009-09-21 13:28:18Z hyunghwan.chung $
|
||||
* $Id: awk.h 312 2009-12-10 13:03:54Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -383,7 +383,6 @@ struct qse_awk_rtx_t
|
||||
|
||||
|
||||
#define QSE_AWK_FREEREX(awk,code) qse_freerex((awk)->mmgr,code)
|
||||
#define QSE_AWK_ISEMPTYREX(awk,code) qse_isemptyrex(code)
|
||||
#define QSE_AWK_BUILDREX(awk,ptn,len,errnum) \
|
||||
qse_awk_buildrex(awk,ptn,len,errnum)
|
||||
#define QSE_AWK_MATCHREX(awk,code,option,str,len,substr,sublen,match,errnum) \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: fnc.c 299 2009-10-19 13:33:40Z hyunghwan.chung $
|
||||
* $Id: fnc.c 312 2009-12-10 13:03:54Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -1118,7 +1118,7 @@ static int __substitute (qse_awk_rtx_t* run, qse_long_t max_count)
|
||||
}
|
||||
}
|
||||
|
||||
opt = (run->gbl.ignorecase)? QSE_REX_MATCH_IGNORECASE: 0;
|
||||
opt = (run->gbl.ignorecase)? QSE_REX_IGNORECASE: 0;
|
||||
|
||||
a2_end = a2_ptr + a2_len;
|
||||
cur_ptr = a2_ptr;
|
||||
@ -1331,12 +1331,28 @@ static int fnc_match (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm)
|
||||
if (nargs >= 3)
|
||||
{
|
||||
qse_awk_val_t* a2;
|
||||
qse_real_t rv;
|
||||
|
||||
a2 = qse_awk_rtx_getarg (rtx, 2);
|
||||
n = qse_awk_rtx_valtonum (rtx, a2, &start, &rv);
|
||||
if (n <= -1) return -1;
|
||||
if (n >= 1) start = (qse_long_t)rv;
|
||||
#if 0
|
||||
if (a2->type == QSE_AWK_VAL_MAP)
|
||||
{
|
||||
/* if the 3rd paramater is an array,
|
||||
* it is a placeholder to store parenthesized
|
||||
* subexpressions */
|
||||
|
||||
/* TODO: please implement this... */
|
||||
start = 0;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
qse_real_t rv;
|
||||
/* if the 3rd parameter is not an array,
|
||||
* it is treated as a match start index */
|
||||
n = qse_awk_rtx_valtonum (rtx, a2, &start, &rv);
|
||||
if (n <= -1) return -1;
|
||||
if (n >= 1) start = (qse_long_t)rv;
|
||||
}
|
||||
}
|
||||
|
||||
if (a0->type == QSE_AWK_VAL_STR)
|
||||
@ -1394,7 +1410,7 @@ static int fnc_match (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm)
|
||||
{
|
||||
n = QSE_AWK_MATCHREX (
|
||||
rtx->awk, rex,
|
||||
(rtx->gbl.ignorecase? QSE_REX_MATCH_IGNORECASE: 0),
|
||||
(rtx->gbl.ignorecase? QSE_REX_IGNORECASE: 0),
|
||||
str0+start-1, len0-start+1,/*TODO: must use str0,len0?*/
|
||||
str0+start-1, len0-start+1,
|
||||
&mat, &errnum
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: misc.c 311 2009-12-09 11:35:54Z hyunghwan.chung $
|
||||
* $Id: misc.c 312 2009-12-10 13:03:54Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -860,7 +860,7 @@ qse_char_t* qse_awk_rtx_strxntokbyrex (
|
||||
{
|
||||
n = QSE_AWK_MATCHREX (
|
||||
rtx->awk, rex,
|
||||
((rtx->gbl.ignorecase)? QSE_REX_MATCH_IGNORECASE: 0),
|
||||
((rtx->gbl.ignorecase)? QSE_REX_IGNORECASE: 0),
|
||||
str, len, ptr, left, &match, errnum);
|
||||
if (n == -1) return QSE_NULL;
|
||||
if (n == 0)
|
||||
@ -1052,7 +1052,7 @@ void* qse_awk_buildrex (
|
||||
|
||||
p = qse_buildrex (
|
||||
awk->mmgr, awk->rex.depth.max.build,
|
||||
((awk->option&QSE_AWK_REXBOUND)? 0:QSE_REX_BUILD_NOBOUND),
|
||||
((awk->option&QSE_AWK_REXBOUND)? 0:QSE_REX_NOBOUND),
|
||||
ptn, len, &err
|
||||
);
|
||||
if (p == QSE_NULL) *errnum = QSE_AWK_REXERRTOERR(err);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: parse.c 299 2009-10-19 13:33:40Z hyunghwan.chung $
|
||||
* $Id: parse.c 312 2009-12-10 13:03:54Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -4012,7 +4012,7 @@ static qse_awk_nde_t* parse_primary_nogetline (
|
||||
|
||||
return (qse_awk_nde_t*)nde;
|
||||
}
|
||||
else if (MATCH(awk,TOK_DIV))
|
||||
else if (MATCH(awk,TOK_DIV) || MATCH(awk,TOK_DIV_ASSN))
|
||||
{
|
||||
qse_awk_nde_rex_t* nde;
|
||||
qse_awk_errnum_t errnum;
|
||||
@ -4021,8 +4021,16 @@ static qse_awk_nde_t* parse_primary_nogetline (
|
||||
* of the context-sensitivity of the slash symbol.
|
||||
* if TOK_DIV is seen as a primary, it tries to compile
|
||||
* it as a regular expression */
|
||||
SET_TOKEN_TYPE (awk, &awk->tok, TOK_REX);
|
||||
qse_str_clear (awk->tok.name);
|
||||
|
||||
if (MATCH(awk,TOK_DIV_ASSN) &&
|
||||
qse_str_ccat (awk->tok.name, QSE_T('=')) == (qse_size_t)-1)
|
||||
{
|
||||
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
SET_TOKEN_TYPE (awk, &awk->tok, TOK_REX);
|
||||
if (get_rexstr (awk, &awk->tok) <= -1) return QSE_NULL;
|
||||
|
||||
QSE_ASSERT (MATCH(awk,TOK_REX));
|
||||
@ -4064,8 +4072,8 @@ static qse_awk_nde_t* parse_primary_nogetline (
|
||||
|
||||
if (get_token(awk) <= -1)
|
||||
{
|
||||
QSE_AWK_FREEREX (awk, nde->code);
|
||||
QSE_AWK_FREE (awk, nde->ptr);
|
||||
QSE_AWK_FREE (awk, nde->code);
|
||||
QSE_AWK_FREE (awk, nde);
|
||||
return QSE_NULL;
|
||||
}
|
||||
@ -4274,7 +4282,10 @@ static qse_awk_nde_t* parse_primary_nogetline (
|
||||
&awk->ptok.loc
|
||||
);
|
||||
}
|
||||
else SETERR_TOK (awk, QSE_AWK_EEXPRNR);
|
||||
else
|
||||
{
|
||||
SETERR_TOK (awk, QSE_AWK_EEXPRNR);
|
||||
}
|
||||
|
||||
return QSE_NULL;
|
||||
}
|
||||
@ -5480,10 +5491,10 @@ static int get_symbols (qse_awk_t* awk, qse_cint_t c, qse_awk_tok_t* tok)
|
||||
{ QSE_T("**"), 2, TOK_EXP, QSE_AWK_EXTRAOPS },
|
||||
{ QSE_T("*="), 2, TOK_MUL_ASSN, 0 },
|
||||
{ QSE_T("*"), 1, TOK_MUL, 0 },
|
||||
{ QSE_T("//="), 3, TOK_IDIV_ASSN, 0 },
|
||||
{ QSE_T("//"), 2, TOK_IDIV, QSE_AWK_EXTRAOPS },
|
||||
{ QSE_T("/="), 2, TOK_DIV_ASSN, QSE_AWK_EXTRAOPS },
|
||||
{ QSE_T("/="), 2, TOK_DIV_ASSN, 0 },
|
||||
{ QSE_T("/"), 1, TOK_DIV, 0 },
|
||||
{ QSE_T("\\="), 2, TOK_IDIV_ASSN, QSE_AWK_EXTRAOPS },
|
||||
{ QSE_T("\\"), 1, TOK_IDIV, QSE_AWK_EXTRAOPS },
|
||||
{ QSE_T("%="), 2, TOK_MOD_ASSN, 0 },
|
||||
{ QSE_T("%"), 1, TOK_MOD, 0 },
|
||||
{ QSE_T("~"), 1, TOK_TILDE, 0 },
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: rio.c 287 2009-09-15 10:01:02Z hyunghwan.chung $
|
||||
* $Id: rio.c 312 2009-12-10 13:03:54Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -280,7 +280,7 @@ int qse_awk_rtx_readio (
|
||||
|
||||
n = QSE_AWK_MATCHREX (
|
||||
run->awk, run->gbl.rs,
|
||||
((run->gbl.ignorecase)? QSE_REX_MATCH_IGNORECASE: 0),
|
||||
((run->gbl.ignorecase)? QSE_REX_IGNORECASE: 0),
|
||||
QSE_STR_PTR(buf), QSE_STR_LEN(buf),
|
||||
QSE_STR_PTR(buf), QSE_STR_LEN(buf),
|
||||
&match, &errnum);
|
||||
@ -374,7 +374,7 @@ int qse_awk_rtx_readio (
|
||||
|
||||
n = QSE_AWK_MATCHREX (
|
||||
run->awk, run->gbl.rs,
|
||||
((run->gbl.ignorecase)? QSE_REX_MATCH_IGNORECASE: 0),
|
||||
((run->gbl.ignorecase)? QSE_REX_IGNORECASE: 0),
|
||||
QSE_STR_PTR(buf), QSE_STR_LEN(buf),
|
||||
QSE_STR_PTR(buf), QSE_STR_LEN(buf),
|
||||
&match, &errnum);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: run.c 299 2009-10-19 13:33:40Z hyunghwan.chung $
|
||||
* $Id: run.c 312 2009-12-10 13:03:54Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -930,12 +930,12 @@ static void fini_rtx (qse_awk_rtx_t* rtx, int fini_globals)
|
||||
|
||||
if (rtx->gbl.rs != QSE_NULL)
|
||||
{
|
||||
QSE_AWK_FREE (rtx->awk, rtx->gbl.rs);
|
||||
QSE_AWK_FREEREX (rtx->awk, rtx->gbl.rs);
|
||||
rtx->gbl.rs = QSE_NULL;
|
||||
}
|
||||
if (rtx->gbl.fs != QSE_NULL)
|
||||
{
|
||||
QSE_AWK_FREE (rtx->awk, rtx->gbl.fs);
|
||||
QSE_AWK_FREEREX (rtx->awk, rtx->gbl.fs);
|
||||
rtx->gbl.fs = QSE_NULL;
|
||||
}
|
||||
|
||||
@ -3101,6 +3101,13 @@ static qse_awk_val_t* eval_expression (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
|
||||
|
||||
if (v->type == QSE_AWK_VAL_REX)
|
||||
{
|
||||
const qse_char_t* ptr;
|
||||
qse_size_t len;
|
||||
int opt = 0;
|
||||
|
||||
if (((qse_awk_rtx_t*)rtx)->gbl.ignorecase)
|
||||
opt = QSE_REX_IGNORECASE;
|
||||
|
||||
qse_awk_rtx_refupval (rtx, v);
|
||||
|
||||
if (rtx->inrec.d0->type == QSE_AWK_VAL_NIL)
|
||||
@ -3108,35 +3115,37 @@ static qse_awk_val_t* eval_expression (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
|
||||
/* the record has never been read.
|
||||
* probably, this function has been triggered
|
||||
* by the statements in the BEGIN block */
|
||||
n = QSE_AWK_ISEMPTYREX(rtx->awk,((qse_awk_val_rex_t*)v)->code)? 1: 0;
|
||||
ptr = QSE_T("");
|
||||
len = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
QSE_ASSERTX (
|
||||
rtx->inrec.d0->type == QSE_AWK_VAL_STR,
|
||||
"the internal value representing $0 should always be of the string type once it has been set/updated. it is nil initially.");
|
||||
"the internal value representing $0 should "
|
||||
"always be of the string type once it has "
|
||||
"been set/updated. it is nil initially.");
|
||||
|
||||
n = QSE_AWK_MATCHREX (
|
||||
((qse_awk_rtx_t*)rtx)->awk,
|
||||
((qse_awk_val_rex_t*)v)->code,
|
||||
((((qse_awk_rtx_t*)rtx)->gbl.ignorecase)? QSE_REX_MATCH_IGNORECASE: 0),
|
||||
((qse_awk_val_str_t*)rtx->inrec.d0)->ptr,
|
||||
((qse_awk_val_str_t*)rtx->inrec.d0)->len,
|
||||
((qse_awk_val_str_t*)rtx->inrec.d0)->ptr,
|
||||
((qse_awk_val_str_t*)rtx->inrec.d0)->len,
|
||||
QSE_NULL, &errnum);
|
||||
|
||||
if (n == -1)
|
||||
{
|
||||
qse_awk_rtx_refdownval (rtx, v);
|
||||
ptr = ((qse_awk_val_str_t*)rtx->inrec.d0)->ptr;
|
||||
len = ((qse_awk_val_str_t*)rtx->inrec.d0)->len;
|
||||
}
|
||||
|
||||
/* matchrex should never set the error number
|
||||
* whose message contains a formatting
|
||||
* character. otherwise, the following way of
|
||||
* setting the error information may not work */
|
||||
SETERR_LOC (rtx, errnum, &nde->loc);
|
||||
return QSE_NULL;
|
||||
}
|
||||
n = QSE_AWK_MATCHREX (
|
||||
((qse_awk_rtx_t*)rtx)->awk,
|
||||
((qse_awk_val_rex_t*)v)->code,
|
||||
opt, ptr, len, ptr, len,
|
||||
QSE_NULL, &errnum);
|
||||
|
||||
if (n <= -1)
|
||||
{
|
||||
qse_awk_rtx_refdownval (rtx, v);
|
||||
|
||||
/* matchrex should never set the error number
|
||||
* whose message contains a formatting
|
||||
* character. otherwise, the following way of
|
||||
* setting the error information may not work */
|
||||
SETERR_LOC (rtx, errnum, &nde->loc);
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
qse_awk_rtx_refdownval (rtx, v);
|
||||
@ -4775,7 +4784,7 @@ static qse_awk_val_t* eval_binop_match0 (
|
||||
{
|
||||
n = QSE_AWK_MATCHREX (
|
||||
rtx->awk, rex_code,
|
||||
((rtx->gbl.ignorecase)? QSE_REX_MATCH_IGNORECASE: 0),
|
||||
((rtx->gbl.ignorecase)? QSE_REX_IGNORECASE: 0),
|
||||
((qse_awk_val_str_t*)left)->ptr,
|
||||
((qse_awk_val_str_t*)left)->len,
|
||||
((qse_awk_val_str_t*)left)->ptr,
|
||||
@ -4784,7 +4793,7 @@ static qse_awk_val_t* eval_binop_match0 (
|
||||
if (n == -1)
|
||||
{
|
||||
if (right->type != QSE_AWK_VAL_REX)
|
||||
QSE_AWK_FREE (rtx->awk, rex_code);
|
||||
QSE_AWK_FREEREX (rtx->awk, rex_code);
|
||||
|
||||
SETERR_LOC (rtx, errnum, lloc);
|
||||
return QSE_NULL;
|
||||
@ -4794,7 +4803,7 @@ static qse_awk_val_t* eval_binop_match0 (
|
||||
if (res == QSE_NULL)
|
||||
{
|
||||
if (right->type != QSE_AWK_VAL_REX)
|
||||
QSE_AWK_FREE (rtx->awk, rex_code);
|
||||
QSE_AWK_FREEREX (rtx->awk, rex_code);
|
||||
|
||||
ADJERR_LOC (rtx, lloc);
|
||||
return QSE_NULL;
|
||||
@ -4808,13 +4817,13 @@ static qse_awk_val_t* eval_binop_match0 (
|
||||
if (qse_awk_rtx_valtostr (rtx, left, &out) == QSE_NULL)
|
||||
{
|
||||
if (right->type != QSE_AWK_VAL_REX)
|
||||
QSE_AWK_FREE (rtx->awk, rex_code);
|
||||
QSE_AWK_FREEREX (rtx->awk, rex_code);
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
n = QSE_AWK_MATCHREX (
|
||||
rtx->awk, rex_code,
|
||||
((rtx->gbl.ignorecase)? QSE_REX_MATCH_IGNORECASE: 0),
|
||||
((rtx->gbl.ignorecase)? QSE_REX_IGNORECASE: 0),
|
||||
out.u.cpldup.ptr, out.u.cpldup.len,
|
||||
out.u.cpldup.ptr, out.u.cpldup.len,
|
||||
QSE_NULL, &errnum);
|
||||
@ -4822,7 +4831,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_FREE (rtx->awk, rex_code);
|
||||
QSE_AWK_FREEREX (rtx->awk, rex_code);
|
||||
|
||||
SETERR_LOC (rtx, errnum, lloc);
|
||||
return QSE_NULL;
|
||||
@ -4833,7 +4842,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_FREE (rtx->awk, rex_code);
|
||||
QSE_AWK_FREEREX (rtx->awk, rex_code);
|
||||
|
||||
ADJERR_LOC (rtx, lloc);
|
||||
return QSE_NULL;
|
||||
@ -4842,7 +4851,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_FREE (rtx->awk, rex_code);
|
||||
if (right->type != QSE_AWK_VAL_REX) QSE_AWK_FREEREX (rtx->awk, rex_code);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: tree.c 299 2009-10-19 13:33:40Z hyunghwan.chung $
|
||||
* $Id: tree.c 312 2009-12-10 13:03:54Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -1229,8 +1229,8 @@ 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_FREE (awk, ((qse_awk_nde_rex_t*)p)->ptr);
|
||||
QSE_AWK_FREE (awk, ((qse_awk_nde_rex_t*)p)->code);
|
||||
QSE_AWK_FREE (awk, p);
|
||||
break;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: val.c 290 2009-09-19 04:28:49Z hyunghwan.chung $
|
||||
* $Id: val.c 312 2009-12-10 13:03:54Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -339,13 +339,9 @@ qse_awk_val_t* qse_awk_rtx_makerexval (
|
||||
/* the regular expression value holds:
|
||||
* - header
|
||||
* - a raw string plus with added a terminating '\0'
|
||||
* - a compiled regular expression
|
||||
* the total size is just large enough for all these.
|
||||
*/
|
||||
totsz = QSE_SIZEOF(qse_awk_val_rex_t) +
|
||||
(QSE_SIZEOF(*buf) * (len + 1)) +
|
||||
QSE_REX_LEN(code);
|
||||
|
||||
totsz = QSE_SIZEOF(*val) + (QSE_SIZEOF(*buf) * (len + 1));
|
||||
val = (qse_awk_val_rex_t*) QSE_AWK_ALLOC (rtx->awk, totsz);
|
||||
if (val == QSE_NULL)
|
||||
{
|
||||
@ -361,8 +357,7 @@ qse_awk_val_t* qse_awk_rtx_makerexval (
|
||||
val->ptr = (qse_char_t*)(val + 1);
|
||||
qse_strncpy (val->ptr, buf, len);
|
||||
|
||||
val->code = val->ptr + len + 1;
|
||||
QSE_MEMCPY (val->code, code, QSE_REX_LEN(code));
|
||||
val->code = code;
|
||||
|
||||
return (qse_awk_val_t*)val;
|
||||
}
|
||||
@ -551,10 +546,15 @@ void qse_awk_rtx_freeval (
|
||||
}
|
||||
else if (val->type == QSE_AWK_VAL_REX)
|
||||
{
|
||||
/*
|
||||
/* don't free ptr as it is inlined to val
|
||||
QSE_AWK_FREE (rtx->awk, ((qse_awk_val_rex_t*)val)->ptr);
|
||||
*/
|
||||
|
||||
/* 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_FREE (rtx->awk, val);
|
||||
}
|
||||
else if (val->type == QSE_AWK_VAL_MAP)
|
||||
|
@ -5,7 +5,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
lib_LTLIBRARIES = libqsecmn.la
|
||||
libqsecmn_la_SOURCES = \
|
||||
syscall.h mem.h \
|
||||
mem.c chr.c chr_cnv.c rex.c rex1.c \
|
||||
mem.c chr.c chr_cnv.c rex.c \
|
||||
str_bas.c str_cnv.c str_dyn.c str_utl.c \
|
||||
lda.c map.c sll.c dll.c opt.c \
|
||||
tio.c tio_get.c tio_put.c \
|
||||
|
@ -72,10 +72,10 @@ am__base_list = \
|
||||
am__installdirs = "$(DESTDIR)$(libdir)"
|
||||
LTLIBRARIES = $(lib_LTLIBRARIES)
|
||||
libqsecmn_la_DEPENDENCIES =
|
||||
am_libqsecmn_la_OBJECTS = mem.lo chr.lo chr_cnv.lo rex.lo rex1.lo \
|
||||
str_bas.lo str_cnv.lo str_dyn.lo str_utl.lo lda.lo map.lo \
|
||||
sll.lo dll.lo opt.lo tio.lo tio_get.lo tio_put.lo fio.lo \
|
||||
pio.lo sio.lo time.lo misc.lo assert.lo main.lo stdio.lo
|
||||
am_libqsecmn_la_OBJECTS = mem.lo chr.lo chr_cnv.lo rex.lo str_bas.lo \
|
||||
str_cnv.lo str_dyn.lo str_utl.lo lda.lo map.lo sll.lo dll.lo \
|
||||
opt.lo tio.lo tio_get.lo tio_put.lo fio.lo pio.lo sio.lo \
|
||||
time.lo misc.lo assert.lo main.lo stdio.lo
|
||||
libqsecmn_la_OBJECTS = $(am_libqsecmn_la_OBJECTS)
|
||||
libqsecmn_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
@ -240,7 +240,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
lib_LTLIBRARIES = libqsecmn.la
|
||||
libqsecmn_la_SOURCES = \
|
||||
syscall.h mem.h \
|
||||
mem.c chr.c chr_cnv.c rex.c rex1.c \
|
||||
mem.c chr.c chr_cnv.c rex.c \
|
||||
str_bas.c str_cnv.c str_dyn.c str_utl.c \
|
||||
lda.c map.c sll.c dll.c opt.c \
|
||||
tio.c tio_get.c tio_put.c \
|
||||
@ -340,7 +340,6 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pio.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rex.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rex1.Plo@am__quote@
|
||||
@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@
|
||||
|
3671
qse/lib/cmn/rex.c
3671
qse/lib/cmn/rex.c
File diff suppressed because it is too large
Load Diff
1921
qse/lib/cmn/rex1.c
1921
qse/lib/cmn/rex1.c
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sed.c 287 2009-09-15 10:01:02Z hyunghwan.chung $
|
||||
* $Id: sed.c 312 2009-12-10 13:03:54Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -377,7 +377,7 @@ static void* compile_rex (qse_sed_t* sed, qse_char_t rxend)
|
||||
code = qse_buildrex (
|
||||
sed->mmgr,
|
||||
sed->depth.rex.build,
|
||||
((sed->option&QSE_SED_REXBOUND)? 0:QSE_REX_BUILD_NOBOUND),
|
||||
((sed->option&QSE_SED_REXBOUND)? 0:QSE_REX_NOBOUND),
|
||||
QSE_STR_PTR(&sed->tmp.rex),
|
||||
QSE_STR_LEN(&sed->tmp.rex),
|
||||
QSE_NULL
|
||||
@ -891,7 +891,7 @@ static int get_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
||||
cmd->u.subst.rex = qse_buildrex (
|
||||
sed->mmgr,
|
||||
sed->depth.rex.build,
|
||||
((sed->option&QSE_SED_REXBOUND)? 0:QSE_REX_BUILD_NOBOUND),
|
||||
((sed->option&QSE_SED_REXBOUND)? 0:QSE_REX_NOBOUND),
|
||||
QSE_STR_PTR(t[0]),
|
||||
QSE_STR_LEN(t[0]),
|
||||
QSE_NULL
|
||||
@ -1832,7 +1832,7 @@ static int do_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
||||
QSE_ASSERT (cmd->type == QSE_SED_CMD_SUBSTITUTE);
|
||||
|
||||
qse_str_clear (&sed->e.txt.subst);
|
||||
if (cmd->u.subst.i) opt = QSE_REX_MATCH_IGNORECASE;
|
||||
if (cmd->u.subst.i) opt = QSE_REX_IGNORECASE;
|
||||
|
||||
str_ptr = QSE_STR_PTR(&sed->e.in.line);
|
||||
str_len = QSE_STR_LEN(&sed->e.in.line);
|
||||
|
18
qse/regress/awk/lang-042.awk
Normal file
18
qse/regress/awk/lang-042.awk
Normal file
@ -0,0 +1,18 @@
|
||||
BEGIN {
|
||||
print //;
|
||||
print /=/;
|
||||
print /.*/;
|
||||
|
||||
a=5; a /= 10; print a;
|
||||
|
||||
for (IGNORECASE=0; IGNORECASE<=1;IGNORECASE++)
|
||||
{
|
||||
print "IGNORECASE=", IGNORECASE;
|
||||
print "abc" ~ /^[[:upper:]]+$/;
|
||||
print "abc" ~ /^[[:lower:]]+$/;
|
||||
print "ABC" ~ /^[[:upper:]]+$/;
|
||||
print "ABC" ~ /^[[:lower:]]+$/;
|
||||
print "AbC" ~ /^[[:upper:]]+$/;
|
||||
print "aBc" ~ /^[[:lower:]]+$/;
|
||||
}
|
||||
}
|
@ -2046,6 +2046,46 @@ BEGIN {
|
||||
}
|
||||
|
||||
2010
|
||||
--------------------------------------------------------------------------------
|
||||
../../cmd/awk/.libs/qseawk --newline=on -o- -f lang-042.awk </dev/stdin 2>&1
|
||||
--------------------------------------------------------------------------------
|
||||
BEGIN {
|
||||
print //;
|
||||
print /=/;
|
||||
print /.*/;
|
||||
a = 5;
|
||||
a /= 10;
|
||||
print a;
|
||||
for (IGNORECASE = 0; (IGNORECASE <= 1); (IGNORECASE)++)
|
||||
{
|
||||
print "IGNORECASE=",IGNORECASE;
|
||||
print ("abc" ~ /^[[:upper:]]+$/);
|
||||
print ("abc" ~ /^[[:lower:]]+$/);
|
||||
print ("ABC" ~ /^[[:upper:]]+$/);
|
||||
print ("ABC" ~ /^[[:lower:]]+$/);
|
||||
print ("AbC" ~ /^[[:upper:]]+$/);
|
||||
print ("aBc" ~ /^[[:lower:]]+$/);
|
||||
}
|
||||
}
|
||||
|
||||
1
|
||||
0
|
||||
1
|
||||
0.5
|
||||
IGNORECASE= 0
|
||||
0
|
||||
1
|
||||
1
|
||||
0
|
||||
0
|
||||
0
|
||||
IGNORECASE= 1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
--------------------------------------------------------------------------------
|
||||
../../cmd/awk/.libs/qseawk -f quicksort.awk quicksort.dat </dev/stdin 2>&1
|
||||
--------------------------------------------------------------------------------
|
||||
|
@ -152,6 +152,7 @@ PROGS="
|
||||
lang-039.awk///--newline=on -o-
|
||||
lang-040.awk///--newline=on -o-
|
||||
lang-041.awk///--newline=on -o-
|
||||
lang-042.awk///--newline=on -o-
|
||||
|
||||
quicksort.awk/quicksort.dat//
|
||||
quicksort2.awk/quicksort2.dat//
|
||||
|
Loading…
x
Reference in New Issue
Block a user