added the global variable STRIPRECSPC.

fixed how to set rtx->gbl.ignorecase for IGNORECASE in set_global()
This commit is contained in:
hyung-hwan 2019-02-04 12:20:16 +00:00
parent 3fdddccde3
commit 98f726e2cc
6 changed files with 56 additions and 17 deletions

View File

@ -1365,6 +1365,7 @@ enum qse_awk_gbl_id_t
QSE_AWK_GBL_RLENGTH, QSE_AWK_GBL_RLENGTH,
QSE_AWK_GBL_RS, QSE_AWK_GBL_RS,
QSE_AWK_GBL_RSTART, QSE_AWK_GBL_RSTART,
QSE_AWK_GBL_STRIPRECSPC,
QSE_AWK_GBL_SUBSEP, QSE_AWK_GBL_SUBSEP,
/* these are not not the actual IDs and are used internally only /* these are not not the actual IDs and are used internally only

View File

@ -316,6 +316,7 @@ struct qse_awk_rtx_t
void* rs[2]; void* rs[2];
void* fs[2]; void* fs[2];
int ignorecase; int ignorecase;
int striprecspc;
qse_awk_int_t nr; qse_awk_int_t nr;
qse_awk_int_t fnr; qse_awk_int_t fnr;

View File

@ -926,7 +926,7 @@ qse_char_t* qse_awk_rtx_strxntokbyrex (
cursub.ptr++; cursub.ptr++;
cursub.len--; cursub.len--;
} }
else if (rtx->awk->opt.trait & QSE_AWK_STRIPRECSPC) else if (rtx->gbl.striprecspc > 0 || (rtx->gbl.striprecspc < 0 && (rtx->awk->opt.trait & QSE_AWK_STRIPRECSPC)))
{ {
/* match at the beginning of the input string */ /* match at the beginning of the input string */
if (match.ptr == substr) if (match.ptr == substr)
@ -976,7 +976,7 @@ exit_loop:
/* the match is all spaces */ /* the match is all spaces */
*errnum = QSE_AWK_ENOERR; *errnum = QSE_AWK_ENOERR;
if (rtx->awk->opt.trait & QSE_AWK_STRIPRECSPC) if (rtx->gbl.striprecspc > 0 || (rtx->gbl.striprecspc < 0 && (rtx->awk->opt.trait & QSE_AWK_STRIPRECSPC)))
{ {
/* if the match reached the last character in the input string, /* if the match reached the last character in the input string,
* it returns QSE_NULL to terminate tokenization. */ * it returns QSE_NULL to terminate tokenization. */

View File

@ -364,6 +364,15 @@ static global_t gtab[] =
{ QSE_T("RS"), 2, 0 }, { QSE_T("RS"), 2, 0 },
{ QSE_T("RSTART"), 6, 0 }, { QSE_T("RSTART"), 6, 0 },
/* it decides the field construction behavior when FS is a regular expression and
* the field splitter is composed of whitespaces only. e.g) FS="[ \t]*";
* if set to a non-zero value, remove leading spaces and trailing spaces off a record
* before field splitting.
* if set to zero, leading spaces and trailing spaces result in 1 empty field respectively.
* if not set, the behavior is dependent on the awk->opt.trait & QSE_AWK_STRIPRECSPC */
{ QSE_T("STRIPRECSPC"), 11, 0 },
{ QSE_T("SUBSEP"), 6, 0 } { QSE_T("SUBSEP"), 6, 0 }
}; };

View File

@ -255,11 +255,13 @@ static int split_record (qse_awk_rtx_t* rtx)
switch (how) switch (how)
{ {
case 0: case 0:
/* 1 character FS */
p = qse_awk_rtx_strxntok ( p = qse_awk_rtx_strxntok (
rtx, p, len, fs_ptr, fs_len, &tok); rtx, p, len, fs_ptr, fs_len, &tok);
break; break;
case 1: case 1:
/* 5 character FS beginning with ? */
p = qse_awk_rtx_strxnfld ( p = qse_awk_rtx_strxnfld (
rtx, p, len, rtx, p, len,
fs_ptr[1], fs_ptr[2], fs_ptr[1], fs_ptr[2],
@ -267,6 +269,7 @@ static int split_record (qse_awk_rtx_t* rtx)
break; break;
default: default:
/* all other cases */
p = qse_awk_rtx_strxntokbyrex ( p = qse_awk_rtx_strxntokbyrex (
rtx, rtx,
QSE_STR_PTR(&rtx->inrec.line), QSE_STR_PTR(&rtx->inrec.line),

View File

@ -474,8 +474,10 @@ static int set_global (
if (fs_len > 1 && !(fs_len == 5 && fs_ptr[0] == QSE_T('?'))) if (fs_len > 1 && !(fs_len == 5 && fs_ptr[0] == QSE_T('?')))
{ {
/* it's a regular expression if FS contains multiple characters.
* however, it's not a regular expression if it's 5 character
* string beginning with a question mark. */
void* rex, * irex; void* rex, * irex;
qse_awk_errnum_t errnum; qse_awk_errnum_t errnum;
if (qse_awk_buildrex (rtx->awk, fs_ptr, fs_len, &errnum, &rex, &irex) <= -1) if (qse_awk_buildrex (rtx->awk, fs_ptr, fs_len, &errnum, &rex, &irex) <= -1)
@ -499,11 +501,17 @@ static int set_global (
case QSE_AWK_GBL_IGNORECASE: case QSE_AWK_GBL_IGNORECASE:
{ {
qse_awk_val_type_t vtype = QSE_AWK_RTX_GETVALTYPE (rtx, val); qse_awk_int_t l;
rtx->gbl.ignorecase = qse_awk_flt_t r;
((vtype == QSE_AWK_VAL_INT && QSE_AWK_RTX_GETINTFROMVAL (rtx,val) != 0) || int vt;
(vtype == QSE_AWK_VAL_FLT && ((qse_awk_val_flt_t*)val)->val != 0.0) ||
(vtype == QSE_AWK_VAL_STR && ((qse_awk_val_str_t*)val)->val.len != 0))? 1: 0; vt = qse_awk_rtx_valtonum(rtx, val, &l, &r);
if (vt <= -1) return -1;
if (vt == 0)
rtx->gbl.ignorecase = ((l > 0)? 1: (l < 0)? -1: 0);
else
rtx->gbl.ignorecase = ((r > 0.0)? 1: (r < 0.0)? -1: 0);
break; break;
} }
@ -663,6 +671,22 @@ static int set_global (
break; break;
} }
case QSE_AWK_GBL_STRIPRECSPC:
{
qse_awk_int_t l;
qse_awk_flt_t r;
int vt;
vt = qse_awk_rtx_valtonum(rtx, val, &l, &r);
if (vt <= -1) return -1;
if (vt == 0)
rtx->gbl.striprecspc = ((l > 0)? 1: (l < 0)? -1: 0);
else
rtx->gbl.striprecspc = ((r > 0.0)? 1: (r < 0.0)? -1: 0);
break;
}
} }
qse_awk_rtx_refdownval (rtx, old); qse_awk_rtx_refdownval (rtx, old);
@ -1026,6 +1050,7 @@ static int init_rtx (qse_awk_rtx_t* rtx, qse_awk_t* awk, qse_awk_rio_t* rio)
rtx->gbl.fs[0] = QSE_NULL; rtx->gbl.fs[0] = QSE_NULL;
rtx->gbl.fs[1] = QSE_NULL; rtx->gbl.fs[1] = QSE_NULL;
rtx->gbl.ignorecase = 0; rtx->gbl.ignorecase = 0;
rtx->gbl.striprecspc = -1;
return 0; return 0;