diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index d2602dc8..3bfb41e6 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h 291 2009-09-21 13:28:18Z hyunghwan.chung $ + * $Id: awk.h 299 2009-10-19 13:33:40Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -713,7 +713,7 @@ enum qse_awk_errnum_t QSE_AWK_EKWWHL, /**< keyword 'while' expected in place of '${0}' */ QSE_AWK_EASSIGN, /**< assignment statement expected */ QSE_AWK_EIDENT, /**< identifier expected in place of '${0}' */ - QSE_AWK_EFUNNAME, /**< '${0}' not a valid function name */ + QSE_AWK_EFUNNAM, /**< '${0}' not a valid function name */ QSE_AWK_EBLKBEG, /**< BEGIN not followed by left bracket on the same line */ QSE_AWK_EBLKEND, /**< END not followed by left bracket on the same line */ QSE_AWK_EKWRED, /**< keyword '${0}' redefined */ diff --git a/qse/lib/awk/fnc.c b/qse/lib/awk/fnc.c index 9a846679..8c0e6ff9 100644 --- a/qse/lib/awk/fnc.c +++ b/qse/lib/awk/fnc.c @@ -1,5 +1,5 @@ /* - * $Id: fnc.c 290 2009-09-19 04:28:49Z hyunghwan.chung $ + * $Id: fnc.c 299 2009-10-19 13:33:40Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -20,6 +20,8 @@ #include "awk.h" +#include + static int fnc_close (qse_awk_rtx_t*, const qse_cstr_t*); static int fnc_fflush (qse_awk_rtx_t*, const qse_cstr_t*); static int fnc_index (qse_awk_rtx_t*, const qse_cstr_t*); @@ -36,6 +38,19 @@ static int fnc_sprintf (qse_awk_rtx_t*, const qse_cstr_t*); #undef MAX #define MAX QSE_TYPE_UNSIGNED_MAX(qse_size_t) +/* Argument Specifier + * + * Each character in the specifier indicates how a parameter + * of the corresponding postion should be passed to a function. + * + * - v: value. pass it after normal evaluation. + * - r: pass a variable by reference + * - x: regular expression as it it. not evaluated as /rex/ ~ $0. + * + * If the first character of the specifer is 'R', all + * parameters are passed by reference regarless of the remaining + * chracters. + */ static qse_awk_fnc_t sys_fnc[] = { /* io functions */ @@ -46,7 +61,7 @@ static qse_awk_fnc_t sys_fnc[] = { {QSE_T("index"), 5}, 0, 0, {2, 3, QSE_NULL}, fnc_index}, { {QSE_T("substr"), 6}, 0, 0, {2, 3, QSE_NULL}, fnc_substr}, { {QSE_T("length"), 6}, 1, 0, {0, 1, QSE_NULL}, fnc_length}, - { {QSE_T("split"), 5}, 0, 0, {2, 3, QSE_T("vrv")}, fnc_split}, + { {QSE_T("split"), 5}, 0, 0, {2, 3, QSE_T("vrx")}, fnc_split}, { {QSE_T("tolower"), 7}, 0, 0, {1, 1, QSE_NULL}, fnc_tolower}, { {QSE_T("toupper"), 7}, 0, 0, {1, 1, QSE_NULL}, fnc_toupper}, { {QSE_T("gsub"), 4}, 0, 0, {2, 3, QSE_T("xvr")}, fnc_gsub}, @@ -714,7 +729,20 @@ static int fnc_split (qse_awk_rtx_t* run, const qse_cstr_t* fnm) fs_rex_free = QSE_NULL; } } - else + else if (a2->type == QSE_AWK_VAL_REX) + { + /* the third parameter is a regular expression */ + + fs_rex = ((qse_awk_val_rex_t*)a2)->code; + fs_rex_free = QSE_NULL; + + /* make the loop below to take fs_rex by + * setting fs_len greater than 1*/ + fs_ptr = QSE_NULL; + fs_free = QSE_NULL; + fs_len = 2; + } + else { if (a2->type == QSE_AWK_VAL_STR) { diff --git a/qse/lib/awk/parse.c b/qse/lib/awk/parse.c index b7a5eb2e..7522cdff 100644 --- a/qse/lib/awk/parse.c +++ b/qse/lib/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c 291 2009-09-21 13:28:18Z hyunghwan.chung $ + * $Id: parse.c 299 2009-10-19 13:33:40Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -1043,7 +1043,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk) if (!MATCH(awk,TOK_IDENT)) { /* cannot find a valid identifier for a function name */ - SETERR_TOK (awk, QSE_AWK_EFUNNAME); + SETERR_TOK (awk, QSE_AWK_EFUNNAM); return QSE_NULL; } @@ -4364,6 +4364,41 @@ static qse_awk_nde_t* parse_primary ( return left; } +static int isfnname (qse_awk_t* awk, const qse_char_t* name, qse_size_t len) +{ + if (qse_awk_getfnc (awk, name, len) != QSE_NULL) + { + /* implicit function */ + return 1; + } + + /* check if it is an awk function */ + if (awk->tree.cur_fun.ptr != QSE_NULL) + { + if (qse_strxncmp ( + awk->tree.cur_fun.ptr, awk->tree.cur_fun.len, + name, len) == 0) + { + /* the current function begin parsed */ + return 2; + } + } + + if (qse_map_search (awk->tree.funs, name, len) != QSE_NULL) + { + /* one of the functions defined previously */ + return 2; + } + + if (qse_map_search (awk->parse.funs, name, len) != QSE_NULL) + { + /* one of the function calls not resolved so far. */ + return 2; + } + + return 0; +} + static qse_awk_nde_t* parse_primary_ident ( qse_awk_t* awk, const qse_awk_loc_t* xloc) { @@ -4401,7 +4436,7 @@ static qse_awk_nde_t* parse_primary_ident ( if (fnc->dfl0) { /* handles a function that assumes () - * when () is missing */ + * when () is missing. i.e. length */ nde = parse_fncall ( awk, namedup, namelen, fnc, xloc, 1); if (nde == QSE_NULL) @@ -4435,13 +4470,24 @@ static qse_awk_nde_t* parse_primary_ident ( qse_awk_nde_var_t* nde; - if (MATCH(awk,TOK_LPAREN)) + if ((awk->option & QSE_AWK_EXPLICIT) && + !(awk->option & QSE_AWK_IMPLICIT)) { - /* a local variable is not a function */ - SETERR_ARG_LOC ( - awk, QSE_AWK_EFUNNAME, namedup, namelen, xloc); - QSE_AWK_FREE (awk, namedup); - return QSE_NULL; + /* if explicit only, the concatenation operator(.) + * must be used. so it is obvious that it is a function + * call, which is illegal for a local variable. + * if implicit, "local_var (1)" may be concatenation of + * the value of local_var and 1. + */ + if (MATCH(awk,TOK_LPAREN)) + { + /* a local variable is not a function */ + SETERR_ARG_LOC ( + awk, QSE_AWK_EFUNNAM, + namedup, namelen, xloc); + QSE_AWK_FREE (awk, namedup); + return QSE_NULL; + } } nde = (qse_awk_nde_var_t*) QSE_AWK_ALLOC ( @@ -4470,13 +4516,18 @@ static qse_awk_nde_t* parse_primary_ident ( qse_awk_nde_var_t* nde; - if (MATCH(awk,TOK_LPAREN)) + if ((awk->option & QSE_AWK_EXPLICIT) && + !(awk->option & QSE_AWK_IMPLICIT)) { - /* a parameter is not a function */ - SETERR_ARG_LOC ( - awk, QSE_AWK_EFUNNAME, namedup, namelen, xloc); - QSE_AWK_FREE (awk, namedup); - return QSE_NULL; + if (MATCH(awk,TOK_LPAREN)) + { + /* a parameter is not a function */ + SETERR_ARG_LOC ( + awk, QSE_AWK_EFUNNAM, + namedup, namelen, xloc); + QSE_AWK_FREE (awk, namedup); + return QSE_NULL; + } } nde = (qse_awk_nde_var_t*) QSE_AWK_ALLOC ( @@ -4505,13 +4556,18 @@ static qse_awk_nde_t* parse_primary_ident ( qse_awk_nde_var_t* nde; - if (MATCH(awk,TOK_LPAREN)) + if ((awk->option & QSE_AWK_EXPLICIT) && + !(awk->option & QSE_AWK_IMPLICIT)) { - /* a global variable is not a function */ - SETERR_ARG_LOC ( - awk, QSE_AWK_EFUNNAME, namedup, namelen, xloc); - QSE_AWK_FREE (awk, namedup); - return QSE_NULL; + if (MATCH(awk,TOK_LPAREN)) + { + /* a global variable is not a function */ + SETERR_ARG_LOC ( + awk, QSE_AWK_EFUNNAM, + namedup, namelen, xloc); + QSE_AWK_FREE (awk, namedup); + return QSE_NULL; + } } nde = (qse_awk_nde_var_t*) QSE_AWK_ALLOC ( @@ -4534,116 +4590,122 @@ static qse_awk_nde_t* parse_primary_ident ( return (qse_awk_nde_t*)nde; } - else if (MATCH(awk,TOK_LPAREN)) + else { - /* function call */ - qse_awk_nde_t* nde; + int fnname = isfnname (awk, namedup, namelen); - if (awk->option & QSE_AWK_IMPLICIT) + if (fnname) { - if (qse_map_search (awk->parse.named, - namedup, namelen) != QSE_NULL) + qse_awk_nde_t* nde; + + if (!MATCH(awk,TOK_LPAREN)) { - /* a function call conflicts with a named variable */ - SETERR_ARG_LOC ( - awk, QSE_AWK_EVARRED, - namedup, namelen, xloc); + /* function named appeared without () */ + if (fnname == 1) + { + SETERR_ARG_LOC ( + awk, QSE_AWK_EFNCRED, + namedup, namelen, xloc); + } + else + { + SETERR_ARG_LOC ( + awk, QSE_AWK_EFUNRED, + namedup, namelen, xloc); + } + QSE_AWK_FREE (awk, namedup); return QSE_NULL; } - } - nde = parse_fncall ( - awk, namedup, namelen, QSE_NULL, xloc, 0); - if (nde == QSE_NULL) QSE_AWK_FREE (awk, namedup); - return (qse_awk_nde_t*)nde; - } - else - { - /* named variable */ - qse_awk_nde_var_t* nde; - - nde = (qse_awk_nde_var_t*) QSE_AWK_ALLOC ( - awk, QSE_SIZEOF(qse_awk_nde_var_t)); - if (nde == QSE_NULL) - { - QSE_AWK_FREE (awk, namedup); - SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc); - return QSE_NULL; - } - - if (awk->option & QSE_AWK_IMPLICIT) - { - qse_bool_t iscur = QSE_FALSE; - - /* the name should not conflict with a function name */ - /* check if it is a builtin function */ - if (qse_awk_getfnc (awk, namedup, namelen) != QSE_NULL) - { - SETERR_ARG_LOC ( - awk, QSE_AWK_EFNCRED, - namedup, namelen, xloc); - goto exit_func; - } - - /* check if it is an AWK function */ - if (awk->tree.cur_fun.ptr != QSE_NULL) - { - iscur = (qse_strxncmp ( - awk->tree.cur_fun.ptr, - awk->tree.cur_fun.len, - namedup, namelen) == 0); - } - - if (iscur || qse_map_search (awk->tree.funs, namedup, namelen) != QSE_NULL) - { - /* the function is defined previously */ - SETERR_ARG_LOC ( - awk, QSE_AWK_EFUNRED, - namedup, namelen, xloc); - goto exit_func; - } - - if (qse_map_search ( - awk->parse.funs, - namedup, namelen) != QSE_NULL) - { - /* is it one of the function calls found so far? */ - SETERR_ARG_LOC ( - awk, QSE_AWK_EFUNRED, - namedup, namelen, xloc); - goto exit_func; - } - - nde->type = QSE_AWK_NDE_NAMED; - nde->loc = *xloc; - nde->next = QSE_NULL; - nde->id.name.ptr = namedup; - nde->id.name.len = namelen; - nde->id.idxa = (qse_size_t)-1; - nde->idx = QSE_NULL; - - /* collect unique instances of a named variable - * for reference */ - if (qse_map_upsert ( - awk->parse.named, - namedup, namelen, QSE_NULL, 0) == QSE_NULL) - { - SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc); - goto exit_func; - } + /* must be a function name */ + QSE_ASSERT (qse_map_search ( + awk->parse.named, namedup, namelen) == QSE_NULL); + nde = parse_fncall ( + awk, namedup, namelen, QSE_NULL, xloc, 0); + if (nde == QSE_NULL) QSE_AWK_FREE (awk, namedup); return (qse_awk_nde_t*)nde; } + else if (awk->option & QSE_AWK_IMPLICIT) + { + if (MATCH(awk,TOK_LPAREN) && + awk->tok.loc.lin == xloc->lin && + awk->tok.loc.col == xloc->col + namelen) + { + qse_awk_nde_t* nde; - /* undefined variable */ - SETERR_ARG_LOC (awk, QSE_AWK_EUNDEF, namedup, namelen, xloc); + /* a function call to a yet undefined function */ + if (qse_map_search (awk->parse.named, + namedup, namelen) != QSE_NULL) + { + /* a function call conflicts with a named variable */ + SETERR_ARG_LOC ( + awk, QSE_AWK_EVARRED, + namedup, namelen, xloc); + QSE_AWK_FREE (awk, namedup); + return QSE_NULL; + } - exit_func: - QSE_AWK_FREE (awk, namedup); - QSE_AWK_FREE (awk, nde); + nde = parse_fncall ( + awk, namedup, namelen, QSE_NULL, xloc, 0); + if (nde == QSE_NULL) QSE_AWK_FREE (awk, namedup); + return (qse_awk_nde_t*)nde; + } + else + { + qse_awk_nde_var_t* nde; - return QSE_NULL; + /* named variable */ + nde = (qse_awk_nde_var_t*) QSE_AWK_ALLOC ( + awk, QSE_SIZEOF(qse_awk_nde_var_t)); + if (nde == QSE_NULL) + { + QSE_AWK_FREE (awk, namedup); + SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc); + return QSE_NULL; + } + + nde->type = QSE_AWK_NDE_NAMED; + nde->loc = *xloc; + nde->next = QSE_NULL; + nde->id.name.ptr = namedup; + nde->id.name.len = namelen; + nde->id.idxa = (qse_size_t)-1; + nde->idx = QSE_NULL; + + /* collect unique instances of a named variable + * for reference */ + if (qse_map_upsert ( + awk->parse.named, + namedup, namelen, QSE_NULL, 0) == QSE_NULL) + { + SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc); + QSE_AWK_FREE (awk, nde); + return QSE_NULL; + } + + return (qse_awk_nde_t*)nde; + } + } + else + { + if (MATCH(awk,TOK_LPAREN)) + { + /* it is a function call as the name is followed + * by ( and implicit variables are disabled. */ + qse_awk_nde_t* nde; + nde = parse_fncall ( + awk, namedup, namelen, QSE_NULL, xloc, 0); + if (nde == QSE_NULL) QSE_AWK_FREE (awk, namedup); + return (qse_awk_nde_t*)nde; + } + + /* undefined variable */ + SETERR_ARG_LOC (awk, QSE_AWK_EUNDEF, namedup, namelen, xloc); + QSE_AWK_FREE (awk, namedup); + return QSE_NULL; + } } } @@ -4768,40 +4830,21 @@ static qse_awk_nde_t* parse_hashidx ( if (awk->option & QSE_AWK_IMPLICIT) { - qse_bool_t iscur = QSE_FALSE; - - /* check if it is a builtin function */ - if (qse_awk_getfnc (awk, name, namelen) != QSE_NULL) + int fnname = isfnname (awk, name, namelen); + if (fnname == 1) { SETERR_ARG_LOC ( awk, QSE_AWK_EFNCRED, name, namelen, xloc); goto exit_func; } - - /* check if it is an AWK function */ - if (awk->tree.cur_fun.ptr != QSE_NULL) + else if (fnname == 2) { - iscur = (qse_strxncmp ( - awk->tree.cur_fun.ptr, awk->tree.cur_fun.len, - name, namelen) == 0); - } - - if (iscur || qse_map_search (awk->tree.funs, name, namelen) != QSE_NULL) - { - /* the function is defined previously */ SETERR_ARG_LOC ( awk, QSE_AWK_EFUNRED, name, namelen, xloc); goto exit_func; } - if (qse_map_search ( - awk->parse.funs, name, namelen) != QSE_NULL) - { - /* is it one of the function calls found so far? */ - SETERR_ARG_LOC ( - awk, QSE_AWK_EFUNRED, name, namelen, xloc); - goto exit_func; - } + QSE_ASSERT (fnname == 0); nde->type = QSE_AWK_NDE_NAMEDIDX; nde->loc = *xloc; @@ -4817,7 +4860,6 @@ static qse_awk_nde_t* parse_hashidx ( /* undefined variable */ SETERR_ARG_LOC (awk, QSE_AWK_EUNDEF, name, namelen, xloc); - exit_func: qse_awk_clrpt (awk, idx); QSE_AWK_FREE (awk, nde); @@ -5549,7 +5591,6 @@ retry: unget_char (awk, &awk->sio.last); awk->sio.last = lc; if (get_number (awk, tok) <= -1) return -1; - } else { diff --git a/qse/lib/awk/run.c b/qse/lib/awk/run.c index ccd3bc43..e54cf0b7 100644 --- a/qse/lib/awk/run.c +++ b/qse/lib/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c 292 2009-09-23 10:19:30Z hyunghwan.chung $ + * $Id: run.c 299 2009-10-19 13:33:40Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -2285,7 +2285,13 @@ static int run_foreach (qse_awk_rtx_t* rtx, qse_awk_nde_foreach_t* nde) if (rv == QSE_NULL) return -1; qse_awk_rtx_refupval (rtx, rv); - if (rv->type != QSE_AWK_VAL_MAP) + if (rv->type == QSE_AWK_VAL_NIL) + { + /* just return without excuting the loop body */ + qse_awk_rtx_refdownval (rtx, rv); + return 0; + } + else if (rv->type != QSE_AWK_VAL_MAP) { qse_awk_rtx_refdownval (rtx, rv); SETERR_LOC (rtx, QSE_AWK_ENOTMAPIN, &test->right->loc); @@ -3100,7 +3106,7 @@ static qse_awk_val_t* eval_expression (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde) if (rtx->inrec.d0->type == QSE_AWK_VAL_NIL) { /* the record has never been read. - * probably, this functions has been triggered + * 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; } diff --git a/qse/lib/awk/tree.c b/qse/lib/awk/tree.c index 590c7b2b..2ebf0b9d 100644 --- a/qse/lib/awk/tree.c +++ b/qse/lib/awk/tree.c @@ -1,5 +1,5 @@ /* - * $Id: tree.c 287 2009-09-15 10:01:02Z hyunghwan.chung $ + * $Id: tree.c 299 2009-10-19 13:33:40Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -538,7 +538,7 @@ static int print_expr (qse_awk_t* awk, qse_awk_nde_t* nde) qse_awk_nde_call_t* px = (qse_awk_nde_call_t*)nde; PUT_SRCSTRX (awk, px->what.fnc.name.ptr, px->what.fnc.name.len); - PUT_SRCSTR (awk, QSE_T(" (")); + PUT_SRCSTR (awk, QSE_T("(")); PRINT_EXPR_LIST (awk, px->args); PUT_SRCSTR (awk, QSE_T(")")); break; @@ -549,7 +549,7 @@ static int print_expr (qse_awk_t* awk, qse_awk_nde_t* nde) qse_awk_nde_call_t* px = (qse_awk_nde_call_t*)nde; PUT_SRCSTRX (awk, px->what.fun.name.ptr, px->what.fun.name.len); - PUT_SRCSTR (awk, QSE_T(" (")); + PUT_SRCSTR (awk, QSE_T("(")); PRINT_EXPR_LIST (awk, px->args); PUT_SRCSTR (awk, QSE_T(")")); break; diff --git a/qse/lib/cmn/rex.c b/qse/lib/cmn/rex.c index b6d5c2b3..7a41b8bf 100644 --- a/qse/lib/cmn/rex.c +++ b/qse/lib/cmn/rex.c @@ -1,5 +1,5 @@ /* - * $Id: rex.c 287 2009-09-15 10:01:02Z hyunghwan.chung $ + * $Id: rex.c 299 2009-10-19 13:33:40Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -23,7 +23,7 @@ #include "mem.h" #ifdef DEBUG_REX -#include +#include #define DPUTS(x) qse_sio_puts(&qse_sio_err,x) #endif @@ -475,7 +475,6 @@ int qse_matchrex ( matcher_t matcher; match_t mat; qse_size_t offset = 0; - /*const qse_char_t* match_ptr_zero = QSE_NULL;*/ matcher.mmgr = mmgr; @@ -494,7 +493,6 @@ int qse_matchrex ( /* TODO: should it allow an offset here??? */ mat.match_ptr = substr + offset; - /*while (mat.match_ptr < matcher.match.str.end)*/ while (mat.match_ptr <= matcher.match.str.end) { if (match_pattern (&matcher, code, &mat) == QSE_NULL) @@ -505,41 +503,18 @@ int qse_matchrex ( if (mat.matched) { - /* - if (mat.match_len == 0) - { - if (match_ptr_zero == QSE_NULL) - match_ptr_zero = mat.match_ptr; - mat.match_ptr++; - continue; - } - */ - if (match != QSE_NULL) { match->ptr = mat.match_ptr; match->len = mat.match_len; } - /*match_ptr_zero = QSE_NULL;*/ break; } mat.match_ptr++; } - /* - if (match_ptr_zero != QSE_NULL) - { - if (match != QSE_NULL) - { - match->ptr = match_ptr_zero; - match->len = 0; - } - return 1; - } - */ - return (mat.matched)? 1: 0; } @@ -1364,19 +1339,11 @@ static const qse_byte_t* match_branch_body0 ( matcher_t* matcher, const qse_byte_t* base, match_t* mat) { const qse_byte_t* p; -/* match_t mat2;*/ qse_size_t match_len = 0; mat->matched = QSE_FALSE; mat->match_len = 0; -/* TODO: is mat2 necessary here ? */ -/* - mat2.match_ptr = mat->match_ptr; - mat2.branch = mat->branch; - mat2.branch_end = mat->branch_end; -*/ - p = base; while (p < mat->branch_end) @@ -1388,21 +1355,6 @@ static const qse_byte_t* match_branch_body0 ( mat->match_ptr = &mat->match_ptr[mat->match_len]; match_len += mat->match_len; -#if 0 - p = match_atom (matcher, p, &mat2); - if (p == QSE_NULL) return QSE_NULL; - - if (!mat2.matched) - { - mat->matched = QSE_FALSE; - break; /* stop matching */ - } - - mat->matched = QSE_TRUE; - mat->match_len += mat2.match_len; - - mat2.match_ptr = &mat2.match_ptr[mat2.match_len]; -#endif } if (mat->matched) mat->match_len = match_len; @@ -1494,7 +1446,6 @@ static const qse_byte_t* match_any_char ( * uses the maximum value to mean infinite. * consider the upper bound of '+' and '*'. */ lbound = (BOUND_MAX-lb >= lbound)? (lbound + lb): BOUND_MAX; - lbound = (BOUND_MAX-lb >= lbound)? (lbound + lb): BOUND_MAX; ubound = (BOUND_MAX-ub >= ubound)? (ubound + ub): BOUND_MAX; p += QSE_SIZEOF(*cp); @@ -1782,8 +1733,20 @@ static const qse_byte_t* match_group ( grp_len_capa += 256; } + grp_len[si+1] = grp_len[si] + mat2.match_len; + if (mat2.match_len == 0) + { +/* TODO: verify this.... */ + /* Advance to the next in case the match lengh is zero + * for (1*)*, 1* can match zero-length. + * A zero-length inner match results in zero-length no + * matter how many times the outer group is requested + * to match */ + break; + } + mat2.match_ptr += mat2.match_len; mat2.match_len = 0; mat2.matched = QSE_FALSE; diff --git a/qse/regress/awk/lang-039.awk b/qse/regress/awk/lang-039.awk new file mode 100644 index 00000000..1ab57839 --- /dev/null +++ b/qse/regress/awk/lang-039.awk @@ -0,0 +1,4 @@ +BEGIN { + print length 11 # this should print 011 as length is length($0); + print length (11) # this should print 2 +} diff --git a/qse/regress/awk/lang-040.awk b/qse/regress/awk/lang-040.awk new file mode 100644 index 00000000..34d79710 --- /dev/null +++ b/qse/regress/awk/lang-040.awk @@ -0,0 +1,5 @@ +BEGIN { + /* the following for statement is valid if y is nil */ + for (x in y) print x; +} + diff --git a/qse/regress/awk/lang-041.awk b/qse/regress/awk/lang-041.awk new file mode 100644 index 00000000..5501784e --- /dev/null +++ b/qse/regress/awk/lang-041.awk @@ -0,0 +1,4 @@ +BEGIN { + abc = 20; + print abc (10); # this is not a function call +} diff --git a/qse/regress/awk/regress.out b/qse/regress/awk/regress.out index 38cf420c..433ed205 100644 --- a/qse/regress/awk/regress.out +++ b/qse/regress/awk/regress.out @@ -421,7 +421,7 @@ function f (__p0) } BEGIN { - f ("hello"); + f("hello"); } hello @@ -431,11 +431,11 @@ hello function f (__p0) { print __p0; - f ("my hello"); + f("my hello"); } BEGIN { - f (10); + f(10); } 10 @@ -948,7 +948,7 @@ function fn (__p0) BEGIN { f = 50; - fn (100); + fn(100); print f; } @@ -975,7 +975,7 @@ BEGIN { } print __l0; } - a (100); + a(100); } 30 @@ -998,7 +998,7 @@ function fn () BEGIN { __g17 = 30; - print fn (); + print fn(); print __g17; } @@ -1040,7 +1040,7 @@ BEGIN { } END { - a (1000); + a(1000); } 1000 -------------------------------------------------------------------------------- @@ -1054,7 +1054,7 @@ BEGIN { } print "----------------------"; print "ARGC=",ARGC; - split ("111 22 333 555 666 777",ARGV); + split("111 22 333 555 666 777",ARGV); for (i in ARGV) { print (("ARGV[" i) "]"),ARGV[i]; @@ -1073,7 +1073,7 @@ BEGIN { printf ("ARGC [%++#10.10f] is positive\n",10124.1123); printf ("[%d], [%f], [%s]\n",10124.1123,10124.1123,10124.1123); printf ("[%-10c] [% 0*.*d]\n",65,45,48,(-(1))); - print sprintf ("abc%d %*.*d %c %s %c",10,20,30,40,"good","good",75.34); + print sprintf("abc%d %*.*d %c %s %c",10,20,30,40,"good","good",75.34); } ARGC= 6 @@ -1108,7 +1108,7 @@ BEGIN { a[4,5,6] = 30; for (i in a) { - n = split (i,k,SUBSEP); + n = split(i,k,SUBSEP); for (j = 1; (j <= n); (j)++) { print k[j]; @@ -1372,8 +1372,8 @@ ERROR: CODE 15 LINE 3 COLUMN 50 - block nested too deeply ../../cmd/awk/.libs/qseawk --newline=on -o- -f lang-016.awk &1 -------------------------------------------------------------------------------- BEGIN { - printf "[[[[[%s]]]]\n",sprintf ("abc %s abc",sprintf ("def %s %s",sprintf ("%s %s %s","xyz",1.2342,"xyz"),sprintf ("ttt %s tttt",123.12))); - printf "[[[[%s]]]]\n",sprintf ("ttt %s tttt",123.12); + printf "[[[[[%s]]]]\n",sprintf("abc %s abc",sprintf("def %s %s",sprintf("%s %s %s","xyz",1.2342,"xyz"),sprintf("ttt %s tttt",123.12))); + printf "[[[[%s]]]]\n",sprintf("ttt %s tttt",123.12); } [[[[[abc def xyz 1.2342 xyz ttt 123.12 tttt abc]]]] @@ -1389,7 +1389,7 @@ function gety () function getx () { if ((x == 2)) - error (); + error(); return (x)++; } @@ -1397,10 +1397,10 @@ function main () { x = 0; y = 0; - print (getx () + gety ()); - print (getx () + gety ()); - print (getx () + gety ()); - print (getx () + gety ()); + print (getx() + gety()); + print (getx() + gety()); + print (getx() + gety()); + print (getx() + gety()); return 999; } @@ -1410,7 +1410,7 @@ function error () } BEGIN { - main (); + main(); } END { @@ -1440,7 +1440,7 @@ function gety () function getx () { if ((x == 2)) - error (); + error(); return (x)++; } @@ -1448,10 +1448,10 @@ function main () { x = 0; y = 0; - print (getx () + gety ()); - print (getx () + gety ()); - print (getx () + gety ()); - print (getx () + gety ()); + print (getx() + gety()); + print (getx() + gety()); + print (getx() + gety()); + print (getx() + gety()); return 999; } @@ -1461,7 +1461,7 @@ function error () } BEGIN { - main (); + main(); } END { @@ -1601,18 +1601,18 @@ BEGIN { ../../cmd/awk/.libs/qseawk --newline=on -o- -f lang-031.awk &1 -------------------------------------------------------------------------------- BEGIN { - print match ("hhhheeeo",/e+/); + print match("hhhheeeo",/e+/); print RSTART,RLENGTH; - print match ("heeeo",/e/); + print match("heeeo",/e/); print RSTART,RLENGTH; - print match ("heeeo",/t/); + print match("heeeo",/t/); print RSTART,RLENGTH; print "--------------------------"; - print match ("hhhheeeo","e+"); + print match("hhhheeeo","e+"); print RSTART,RLENGTH; - print match ("heeeo","e"); + print match("heeeo","e"); print RSTART,RLENGTH; - print match ("heeeo","t"); + print match("heeeo","t"); print RSTART,RLENGTH; print "--------------------------"; } @@ -1674,7 +1674,7 @@ BEGIN { print "13" || "sort"; print "12" || "sort"; print "11" || "sort"; - close ("sort","r"); + close("sort","r"); print "-----"; while ((("sort" || getline x) > 0)) print "xx:",x; @@ -1699,7 +1699,7 @@ BEGIN { first = 0; continue; } - n = split (x,f,","); + n = split(x,f,","); if ((n < 3)) continue; if ((f[3] == "")) @@ -1723,13 +1723,13 @@ BEGIN { { if ((($1 == "option") && ($2 == "agent.circuit-id"))) { - pos = index ($0,"agent.circuit-id "); - len = length ($0); - last = substr ($0,len,1); + pos = index($0,"agent.circuit-id "); + len = length($0); + last = substr($0,len,1); adj = 0; if ((last != ";")) (adj)++; - cid = substr ($0,(pos + 17),(length ($0) - ((pos + 17) + adj))); + cid = substr($0,(pos + 17),(length($0) - ((pos + 17) + adj))); for (suffix = 0; (suffix < max_cid_vars); (suffix)++) { val = tab[cid,suffix]; @@ -1996,18 +1996,18 @@ dif cccc BEGIN { xstr = "abcdefabcdefabcdef"; xsub = "abc"; - xlen = length (xsub); + xlen = length(xsub); i = 1; - while ((i = index (xstr,xsub,i) > 0)) + while ((i = index(xstr,xsub,i) > 0)) { - print i,substr (xstr,i,xlen); + print i,substr(xstr,i,xlen); i += xlen; } print "----------------"; i = 1; - while ((match (xstr,xsub,i) > 0)) + while ((match(xstr,xsub,i) > 0)) { - print RSTART,substr (xstr,RSTART,RLENGTH); + print RSTART,substr(xstr,RSTART,RLENGTH); i = (RSTART + RLENGTH); } } @@ -2019,6 +2019,33 @@ BEGIN { 1 abc 7 abc 13 abc +-------------------------------------------------------------------------------- + ../../cmd/awk/.libs/qseawk --newline=on -o- -f lang-039.awk &1 +-------------------------------------------------------------------------------- +BEGIN { + print (length() 11); + print length(11); +} + +011 +2 +-------------------------------------------------------------------------------- + ../../cmd/awk/.libs/qseawk --newline=on -o- -f lang-040.awk &1 +-------------------------------------------------------------------------------- +BEGIN { + for (x in y) + print x; +} + +-------------------------------------------------------------------------------- + ../../cmd/awk/.libs/qseawk --newline=on -o- -f lang-041.awk &1 +-------------------------------------------------------------------------------- +BEGIN { + abc = 20; + print (abc 10); +} + +2010 -------------------------------------------------------------------------------- ../../cmd/awk/.libs/qseawk -f quicksort.awk quicksort.dat &1 -------------------------------------------------------------------------------- diff --git a/qse/regress/awk/regress.sh b/qse/regress/awk/regress.sh index d2b5855e..e0373226 100755 --- a/qse/regress/awk/regress.sh +++ b/qse/regress/awk/regress.sh @@ -149,6 +149,9 @@ PROGS=" lang-036.awk/lang-036.dat//--newline=on -o- lang-037.awk/lang-037.dat//--newline=on -o- lang-038.awk///--newline=on -o- + lang-039.awk///--newline=on -o- + lang-040.awk///--newline=on -o- + lang-041.awk///--newline=on -o- quicksort.awk/quicksort.dat// quicksort2.awk/quicksort2.dat//