diff --git a/hawk/lib/hawk-prv.h b/hawk/lib/hawk-prv.h index 91841d7e..65e47267 100644 --- a/hawk/lib/hawk-prv.h +++ b/hawk/lib/hawk-prv.h @@ -410,7 +410,6 @@ struct hawk_rtx_t struct { - void* brs[2]; void* rs[2]; void* fs[2]; int ignorecase; diff --git a/hawk/lib/hawk-tre.h b/hawk/lib/hawk-tre.h index 635f7933..2d36074f 100644 --- a/hawk/lib/hawk-tre.h +++ b/hawk/lib/hawk-tre.h @@ -137,6 +137,26 @@ HAWK_EXPORT int hawk_tre_exec ( hawk_gem_t* errgem ); +HAWK_EXPORT int hawk_tre_execuchars ( + hawk_tre_t* tre, + const hawk_uch_t* str, + hawk_oow_t len, + hawk_tre_match_t* pmatch, + hawk_oow_t nmatch, + int eflags, + hawk_gem_t* errgem +); + +HAWK_EXPORT int hawk_tre_execbchars ( + hawk_tre_t* tre, + const hawk_bch_t* str, + hawk_oow_t len, + hawk_tre_match_t* pmatch, + hawk_oow_t nmatch, + int eflags, + hawk_gem_t* errgem +); + #if defined(__cplusplus) } #endif diff --git a/hawk/lib/hawk.h b/hawk/lib/hawk.h index bf77335b..a537893e 100644 --- a/hawk/lib/hawk.h +++ b/hawk/lib/hawk.h @@ -1298,7 +1298,6 @@ enum hawk_gbl_id_t * but is this check really necessary??? */ - HAWK_GBL_BRS, HAWK_GBL_CONVFMT, HAWK_GBL_FILENAME, HAWK_GBL_FNR, @@ -1319,7 +1318,7 @@ enum hawk_gbl_id_t /* these are not not the actual IDs and are used internally only * Make sure you update these values properly if you add more * ID definitions, however */ - HAWK_MIN_GBL_ID = HAWK_GBL_BRS, + HAWK_MIN_GBL_ID = HAWK_GBL_CONVFMT, HAWK_MAX_GBL_ID = HAWK_GBL_SUBSEP }; typedef enum hawk_gbl_id_t hawk_gbl_id_t; diff --git a/hawk/lib/misc-prv.h b/hawk/lib/misc-prv.h index 3cd8b91c..2d538dca 100644 --- a/hawk/lib/misc-prv.h +++ b/hawk/lib/misc-prv.h @@ -83,6 +83,17 @@ int hawk_rtx_matchrex ( hawk_oocs_t* match, hawk_oocs_t submat[9] ); +int hawk_rtx_matchrexwithucs ( + hawk_rtx_t* rtx, hawk_tre_t* code, + const hawk_ucs_t* str, const hawk_ucs_t* substr, + hawk_ucs_t* match, hawk_ucs_t submat[9] +); + +int hawk_rtx_matchrexwithbcs ( + hawk_rtx_t* rtx, hawk_tre_t* code, + const hawk_bcs_t* str, const hawk_bcs_t* substr, + hawk_bcs_t* match, hawk_bcs_t submat[9] +); #if defined(__cplusplus) } diff --git a/hawk/lib/misc.c b/hawk/lib/misc.c index 2a1dcf46..958005e8 100644 --- a/hawk/lib/misc.c +++ b/hawk/lib/misc.c @@ -471,6 +471,84 @@ static int matchtre (hawk_tre_t* tre, int opt, const hawk_oocs_t* str, hawk_oocs return 1; } +static int matchtre_ucs (hawk_tre_t* tre, int opt, const hawk_ucs_t* str, hawk_ucs_t* mat, hawk_ucs_t submat[9], hawk_gem_t* errgem) +{ + int n; + /*hawk_tre_match_t match[10] = { { 0, 0 }, };*/ + hawk_tre_match_t match[10]; + + HAWK_MEMSET (match, 0, HAWK_SIZEOF(match)); + n = hawk_tre_execbchars(tre, str->ptr, str->len, match, HAWK_COUNTOF(match), opt, errgem); + if (n <= -1) + { + if (hawk_gem_geterrnum(errgem) == HAWK_EREXNOMAT) return 0; + return -1; + } + + HAWK_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 < HAWK_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; +} + +static int matchtre_bcs (hawk_tre_t* tre, int opt, const hawk_bcs_t* str, hawk_bcs_t* mat, hawk_bcs_t submat[9], hawk_gem_t* errgem) +{ + int n; + /*hawk_tre_match_t match[10] = { { 0, 0 }, };*/ + hawk_tre_match_t match[10]; + + HAWK_MEMSET (match, 0, HAWK_SIZEOF(match)); + n = hawk_tre_execbchars(tre, str->ptr, str->len, match, HAWK_COUNTOF(match), opt, errgem); + if (n <= -1) + { + if (hawk_gem_geterrnum(errgem) == HAWK_EREXNOMAT) return 0; + return -1; + } + + HAWK_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 < HAWK_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; +} + int hawk_rtx_matchval (hawk_rtx_t* rtx, hawk_val_t* val, const hawk_oocs_t* str, const hawk_oocs_t* substr, hawk_oocs_t* match, hawk_oocs_t submat[9]) { int ignorecase, x; @@ -522,3 +600,21 @@ int hawk_rtx_matchrex (hawk_rtx_t* rtx, hawk_tre_t* code, const hawk_oocs_t* str substr, match, submat, hawk_rtx_getgem(rtx) ); } + +int hawk_rtx_matchrexwithucs (hawk_rtx_t* rtx, hawk_tre_t* code, const hawk_ucs_t* str, const hawk_ucs_t* substr, hawk_ucs_t* match, hawk_ucs_t submat[9]) +{ + int opt = HAWK_TRE_BACKTRACKING; /* TODO: option... HAWK_TRE_BACKTRACKING or others??? */ + return matchtre_ucs( + code, ((str->ptr == substr->ptr)? opt: (opt | HAWK_TRE_NOTBOL)), + substr, match, submat, hawk_rtx_getgem(rtx) + ); +} + +int hawk_rtx_matchrexwithbcs (hawk_rtx_t* rtx, hawk_tre_t* code, const hawk_bcs_t* str, const hawk_bcs_t* substr, hawk_bcs_t* match, hawk_bcs_t submat[9]) +{ + int opt = HAWK_TRE_BACKTRACKING; /* TODO: option... HAWK_TRE_BACKTRACKING or others??? */ + return matchtre_bcs( + code, ((str->ptr == substr->ptr)? opt: (opt | HAWK_TRE_NOTBOL)), + substr, match, submat, hawk_rtx_getgem(rtx) + ); +} diff --git a/hawk/lib/parse-prv.h b/hawk/lib/parse-prv.h index 125076a0..f65e8514 100644 --- a/hawk/lib/parse-prv.h +++ b/hawk/lib/parse-prv.h @@ -47,6 +47,7 @@ enum hawk_kwid_t HAWK_KWID_EXIT, HAWK_KWID_FOR, HAWK_KWID_FUNCTION, + HAWK_KWID_GETBLINE, HAWK_KWID_GETLINE, HAWK_KWID_IF, HAWK_KWID_IN, diff --git a/hawk/lib/parse.c b/hawk/lib/parse.c index a7840f41..3f1f3155 100644 --- a/hawk/lib/parse.c +++ b/hawk/lib/parse.c @@ -166,6 +166,7 @@ enum tok_t TOK_PRINT, TOK_PRINTF, + TOK_GETBLINE, TOK_GETLINE, /* == end reserved words == */ @@ -297,6 +298,7 @@ static kwent_t kwtab[] = { { HAWK_T("exit"), 4 }, TOK_EXIT, 0 }, { { HAWK_T("for"), 3 }, TOK_FOR, 0 }, { { HAWK_T("function"), 8 }, TOK_FUNCTION, 0 }, + { { HAWK_T("getbline"), 8 }, TOK_GETBLINE, HAWK_RIO }, { { HAWK_T("getline"), 7 }, TOK_GETLINE, HAWK_RIO }, { { HAWK_T("if"), 2 }, TOK_IF, 0 }, { { HAWK_T("in"), 2 }, TOK_IN, 0 }, @@ -324,8 +326,6 @@ static global_t gtab[] = * this table must match the order of the hawk_gbl_id_t enumerators */ - { HAWK_T("BRS"), 3, 0 }, - /* output real-to-str conversion format for other cases than 'print' */ { HAWK_T("CONVFMT"), 7, 0 }, @@ -4865,7 +4865,7 @@ oops: return HAWK_NULL; } -static hawk_nde_t* parse_primary_getline (hawk_t* awk, const hawk_loc_t* xloc) +static hawk_nde_t* parse_primary_getline (hawk_t* awk, const hawk_loc_t* xloc, int mbs) { /* parse the statement-level getline. * getline after the pipe symbols(|,||) is parsed @@ -4875,10 +4875,11 @@ static hawk_nde_t* parse_primary_getline (hawk_t* awk, const hawk_loc_t* xloc) hawk_nde_getline_t* nde; hawk_loc_t ploc; - nde = (hawk_nde_getline_t*) hawk_callocmem (awk, HAWK_SIZEOF(*nde)); + nde = (hawk_nde_getline_t*)hawk_callocmem(awk, HAWK_SIZEOF(*nde)); if (nde == HAWK_NULL) goto oops; nde->type = HAWK_NDE_GETLINE; + nde->mbs = mbs; nde->loc = *xloc; nde->in_type = HAWK_IN_CONSOLE; @@ -4982,8 +4983,11 @@ static hawk_nde_t* parse_primary_nopipe (hawk_t* awk, const hawk_loc_t* xloc) case TOK_LPAREN: return parse_primary_lparen(awk, xloc); + case TOK_GETBLINE: + return parse_primary_getline(awk, xloc, 1); + case TOK_GETLINE: - return parse_primary_getline(awk, xloc); + return parse_primary_getline(awk, xloc, 0); default: { @@ -5020,6 +5024,7 @@ static hawk_nde_t* parse_primary (hawk_t* awk, const hawk_loc_t* xloc) do { int intype = -1; + int mbs; if (awk->opt.trait & HAWK_RIO) { @@ -5036,7 +5041,9 @@ static hawk_nde_t* parse_primary (hawk_t* awk, const hawk_loc_t* xloc) if (intype == -1) break; if (preget_token(awk) <= -1) goto oops; - if (awk->ntok.type != TOK_GETLINE) break; + if (awk->ntok.type == TOK_GETBLINE) mbs = 1; + else if (awk->ntok.type == TOK_GETLINE) mbs = 0; + else break; /* consume ntok('getline') */ get_token(awk); /* no error check needed as it's guaranteeded to succeed for preget_token() above */ @@ -5073,7 +5080,7 @@ static hawk_nde_t* parse_primary (hawk_t* awk, const hawk_loc_t* xloc) } ploc = awk->tok.loc; - var = parse_primary (awk, &ploc); + var = parse_primary(awk, &ploc); if (var == HAWK_NULL) goto oops; if (!is_var(var) && var->type != HAWK_NDE_POS) @@ -5096,6 +5103,7 @@ static hawk_nde_t* parse_primary (hawk_t* awk, const hawk_loc_t* xloc) nde->type = HAWK_NDE_GETLINE; nde->loc = *xloc; nde->var = var; + nde->mbs = mbs; nde->in_type = intype; nde->in = left; diff --git a/hawk/lib/rio.c b/hawk/lib/rio.c index 508fe905..0bcdd51f 100644 --- a/hawk/lib/rio.c +++ b/hawk/lib/rio.c @@ -160,22 +160,12 @@ static int find_rio_in ( p->in.eos = 0; */ - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENOERR); - /* request to open the stream */ x = handler(rtx, HAWK_RIO_CMD_OPEN, p, HAWK_NULL, 0); if (x <= -1) { hawk_rtx_freemem (rtx, p->name); hawk_rtx_freemem (rtx, p); - - if (hawk_rtx_geterrnum(rtx) == HAWK_ENOERR) - { - /* if the error number has not been - * set by the user handler */ - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EIOIMPL); - } - return -1; } @@ -311,11 +301,11 @@ static HAWK_INLINE int match_long_brs(hawk_rtx_t* rtx, hawk_becs_t* buf, hawk_ri hawk_bcs_t match; int ret; - HAWK_ASSERT (rtx->gbl.brs[0] != HAWK_NULL); - HAWK_ASSERT (rtx->gbl.brs[1] != HAWK_NULL); + HAWK_ASSERT (rtx->gbl.rs[0] != HAWK_NULL); + HAWK_ASSERT (rtx->gbl.rs[1] != HAWK_NULL); -/*TODO: mbs match rex */ - ret = hawk_rtx_matchrex(rtx, rtx->gbl.brs[rtx->gbl.ignorecase], HAWK_BECS_OOCS(buf), HAWK_BECS_OOCS(buf), &match, HAWK_NULL); + + ret = hawk_rtx_matchrexwithbcs(rtx, rtx->gbl.rs[rtx->gbl.ignorecase], HAWK_BECS_BCS(buf), HAWK_BECS_BCS(buf), &match, HAWK_NULL); if (ret >= 1) { if (p->in.eof) @@ -415,18 +405,9 @@ int hawk_rtx_readio (hawk_rtx_t* rtx, int in_type, const hawk_ooch_t* name, hawk break; } - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENOERR); x = handler(rtx, HAWK_RIO_CMD_READ, p, p->in.buf, HAWK_COUNTOF(p->in.buf)); if (x <= -1) { - if (hawk_rtx_geterrnum(rtx) == HAWK_ENOERR) - { - /* if the error number has not been - * set by the user handler, we set - * it here to HAWK_EIOIMPL. */ - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EIOIMPL); - } - ret = -1; break; } @@ -685,7 +666,7 @@ int hawk_rtx_readio (hawk_rtx_t* rtx, int in_type, const hawk_ooch_t* name, hawk int hawk_rtx_readiobytes (hawk_rtx_t* rtx, int in_type, const hawk_ooch_t* name, hawk_becs_t* buf) { -#if 0 +#if 1 hawk_rio_arg_t* p; hawk_rio_impl_t handler; int ret; @@ -703,7 +684,7 @@ int hawk_rtx_readiobytes (hawk_rtx_t* rtx, int in_type, const hawk_ooch_t* name, hawk_becs_clear (buf); /* get the record separator */ - brs = hawk_rtx_getgbl(rtx, HAWK_GBL_BRS); + brs = hawk_rtx_getgbl(rtx, HAWK_GBL_RS); hawk_rtx_refupval (rtx, brs); if (resolve_brs(rtx, brs, &rrs) <= -1) @@ -735,18 +716,9 @@ int hawk_rtx_readiobytes (hawk_rtx_t* rtx, int in_type, const hawk_ooch_t* name, break; } - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENOERR); x = handler(rtx, HAWK_RIO_CMD_READ_BYTES, p, p->in.buf, HAWK_COUNTOF(p->in.buf)); if (x <= -1) { - if (hawk_rtx_geterrnum(rtx) == HAWK_ENOERR) - { - /* if the error number has not been - * set by the user handler, we set - * it here to HAWK_EIOIMPL. */ - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EIOIMPL); - } - ret = -1; break; } @@ -862,9 +834,9 @@ int hawk_rtx_readiobytes (hawk_rtx_t* rtx, int in_type, const hawk_ooch_t* name, /* TODO: handle different line terminator */ /* separate by a blank line */ - if (c == HAWK_T('\n')) + if (c == '\n') { - if (pc == HAWK_T('\r') && HAWK_BECS_LEN(buf) > 0) + if (pc == '\r' && HAWK_BECS_LEN(buf) > 0) { /* shrink the line length and the record * by dropping of CR before NL */ @@ -872,7 +844,7 @@ int hawk_rtx_readiobytes (hawk_rtx_t* rtx, int in_type, const hawk_ooch_t* name, line_len--; /* we don't drop CR from the record buffer - * if we're in CRLF mode. POINT-X */ + * if we're in CRLF mode. POINT-X */ if (!(rtx->awk->opt.trait & HAWK_CRLF)) HAWK_BECS_LEN(buf) -= 1; } @@ -883,7 +855,7 @@ int hawk_rtx_readiobytes (hawk_rtx_t* rtx, int in_type, const hawk_ooch_t* name, if (rtx->awk->opt.trait & HAWK_CRLF) { - if (HAWK_BECS_LEN(buf) > 0 && HAWK_BECS_LASTCHAR(buf) == HAWK_T('\r')) + if (HAWK_BECS_LEN(buf) > 0 && HAWK_BECS_LASTCHAR(buf) == '\r') { /* drop CR not dropped in POINT-X above */ HAWK_BECS_LEN(buf) -= 1; @@ -902,7 +874,7 @@ int hawk_rtx_readiobytes (hawk_rtx_t* rtx, int in_type, const hawk_ooch_t* name, HAWK_BECS_LEN(buf) -= 1; /* drop preceding CR */ - if (HAWK_BECS_LEN(buf) > 0 && HAWK_BECS_LASTCHAR(buf) == HAWK_T('\r')) HAWK_BECS_LEN(buf) -= 1; + if (HAWK_BECS_LEN(buf) > 0 && HAWK_BECS_LASTCHAR(buf) == '\r') HAWK_BECS_LEN(buf) -= 1; } else { @@ -987,7 +959,7 @@ int hawk_rtx_readiobytes (hawk_rtx_t* rtx, int in_type, const hawk_ooch_t* name, p->in.pos = p->in.len; - n = match_long_rs(rtx, buf, p); + n = match_long_brs(rtx, buf, p); if (n != 0) { if (n <= -1) ret = -1; @@ -997,7 +969,7 @@ int hawk_rtx_readiobytes (hawk_rtx_t* rtx, int in_type, const hawk_ooch_t* name, } if (rrs.ptr && HAWK_RTX_GETVALTYPE(rtx, brs) != HAWK_VAL_MBS) hawk_rtx_freemem (rtx, rrs.ptr); - hawk_rtx_refdownval (rtx, rs); + hawk_rtx_refdownval (rtx, brs); return ret; #else @@ -1108,16 +1080,11 @@ static int prepare_for_write_io_data (hawk_rtx_t* rtx, int out_type, const hawk_ p->out.eos = 0; */ - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENOERR); n = handler(rtx, HAWK_RIO_CMD_OPEN, p, HAWK_NULL, 0); if (n <= -1) { hawk_rtx_freemem (rtx, p->name); hawk_rtx_freemem (rtx, p); - - if (hawk_rtx_geterrnum(rtx) == HAWK_ENOERR) - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EIOIMPL); - return -1; } @@ -1145,14 +1112,8 @@ int hawk_rtx_writeiostr (hawk_rtx_t* rtx, int out_type, const hawk_ooch_t* name, { hawk_ooi_t n; - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENOERR); n = wid.handler(rtx, HAWK_RIO_CMD_WRITE, wid.p, str, len); - if (n <= -1) - { - if (hawk_rtx_geterrnum(rtx) == HAWK_ENOERR) - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EIOIMPL); - return -1; - } + if (n <= -1) return -1; if (n == 0) { @@ -1178,14 +1139,8 @@ int hawk_rtx_writeiobytes (hawk_rtx_t* rtx, int out_type, const hawk_ooch_t* nam { hawk_ooi_t n; - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENOERR); n = wid.handler(rtx, HAWK_RIO_CMD_WRITE_BYTES, wid.p, str, len); - if (n <= -1) - { - if (hawk_rtx_geterrnum(rtx) == HAWK_ENOERR) - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EIOIMPL); - return -1; - } + if (n <= -1) return -1; if (n == 0) { @@ -1235,15 +1190,8 @@ int hawk_rtx_flushio (hawk_rtx_t* rtx, int out_type, const hawk_ooch_t* name) if (p->type == (io_type | io_mask) && p->mode == io_mode && (name == HAWK_NULL || hawk_comp_oocstr(p->name, name, 0) == 0)) { - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENOERR); n = handler(rtx, HAWK_RIO_CMD_FLUSH, p, HAWK_NULL, 0); - if (n <= -1) - { - if (hawk_rtx_geterrnum(rtx) == HAWK_ENOERR) - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EIOIMPL); - return -1; - } - + if (n <= -1) return -1; ok = 1; } @@ -1301,14 +1249,8 @@ int hawk_rtx_nextio_read (hawk_rtx_t* rtx, int in_type, const hawk_ooch_t* name) return 0; } - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENOERR); n = handler(rtx, HAWK_RIO_CMD_NEXT, p, HAWK_NULL, 0); - if (n <= -1) - { - if (hawk_rtx_geterrnum(rtx) == HAWK_ENOERR) - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EIOIMPL); - return -1; - } + if (n <= -1) return -1; if (n == 0) { @@ -1377,14 +1319,8 @@ int hawk_rtx_nextio_write (hawk_rtx_t* rtx, int out_type, const hawk_ooch_t* nam return 0; } - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENOERR); n = handler(rtx, HAWK_RIO_CMD_NEXT, p, HAWK_NULL, 0); - if (n <= -1) - { - if (hawk_rtx_geterrnum(rtx) == HAWK_ENOERR) - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EIOIMPL); - return -1; - } + if (n <= -1) return -1; if (n == 0) { @@ -1490,16 +1426,7 @@ int hawk_rtx_closio_write (hawk_rtx_t* rtx, int out_type, const hawk_ooch_t* nam hawk_rio_impl_t handler; handler = rtx->rio.handler[p->type & IO_MASK_CLEAR]; - if (handler) - { - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENOERR); - if (handler (rtx, HAWK_RIO_CMD_CLOSE, p, HAWK_NULL, 0) <= -1) - { - if (hawk_rtx_geterrnum(rtx) == HAWK_ENOERR) - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EIOIMPL); - return -1; - } - } + if (handler && handler(rtx, HAWK_RIO_CMD_CLOSE, p, HAWK_NULL, 0) <= -1) return -1; if (px) px->next = p->next; else rtx->rio.chain = p->next; @@ -1566,13 +1493,10 @@ int hawk_rtx_closeio (hawk_rtx_t* rtx, const hawk_ooch_t* name, const hawk_ooch_ handler = rtx->rio.handler[p->type & IO_MASK_CLEAR]; if (handler) { - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENOERR); p->rwcmode = rwcmode; if (handler(rtx, HAWK_RIO_CMD_CLOSE, p, HAWK_NULL, 0) <= -1) { /* this is not a run-time error.*/ - if (hawk_rtx_geterrnum(rtx) == HAWK_ENOERR) - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EIOIMPL); return -1; } } @@ -1622,13 +1546,10 @@ void hawk_rtx_cleario (hawk_rtx_t* rtx) if (handler) { - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENOERR); rtx->rio.chain->rwcmode = 0; n = handler(rtx, HAWK_RIO_CMD_CLOSE, rtx->rio.chain, HAWK_NULL, 0); if (n <= -1) { - if (hawk_rtx_geterrnum(rtx) == HAWK_ENOERR) - hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EIOIMPL); /* TODO: some warnings need to be shown??? */ } } diff --git a/hawk/lib/run.c b/hawk/lib/run.c index 9e8dcd67..9e8752f0 100644 --- a/hawk/lib/run.c +++ b/hawk/lib/run.c @@ -352,45 +352,6 @@ static int set_global (hawk_rtx_t* rtx, int idx, hawk_nde_var_t* var, hawk_val_t /* perform actual assignment or assignment-like operation */ switch (idx) { - case HAWK_GBL_BRS: - { - hawk_bcs_t rss; - - /* due to the expression evaluation rule, the - * regular expression can not be an assigned - * value */ - HAWK_ASSERT (vtype != HAWK_VAL_REX); - - rss.ptr = hawk_rtx_getvalbcstr(rtx, val, &rss.len); - if (!rss.ptr) return -1; - - if (rtx->gbl.brs[0]) - { - hawk_rtx_freerex (rtx, rtx->gbl.brs[0], rtx->gbl.brs[1]); - rtx->gbl.brs[0] = HAWK_NULL; - rtx->gbl.brs[1] = HAWK_NULL; - } - - if (rss.len > 1) - { - hawk_tre_t* rex, * irex; - - /* compile the regular expression */ -/* TODO: mbs buildrex */ - if (hawk_rtx_buildrex(rtx, rss.ptr, rss.len, &rex, &irex) <= -1) - { - hawk_rtx_freevalbcstr (rtx, val, rss.ptr); - return -1; - } - - rtx->gbl.brs[0] = rex; - rtx->gbl.brs[1] = irex; - } - - hawk_rtx_freevalbcstr (rtx, val, rss.ptr); - break; - } - case HAWK_GBL_CONVFMT: { hawk_oow_t i; @@ -981,8 +942,6 @@ static int init_rtx (hawk_rtx_t* rtx, hawk_t* awk, hawk_rio_cbs_t* rio) rtx->rio.chain = HAWK_NULL; } - rtx->gbl.brs[0] = HAWK_NULL; - rtx->gbl.brs[1] = HAWK_NULL; rtx->gbl.rs[0] = HAWK_NULL; rtx->gbl.rs[1] = HAWK_NULL; rtx->gbl.fs[0] = HAWK_NULL; @@ -1030,12 +989,6 @@ static void fini_rtx (hawk_rtx_t* rtx, int fini_globals) hawk_rtx_cleario (rtx); HAWK_ASSERT (rtx->rio.chain == HAWK_NULL); - if (rtx->gbl.brs[0]) - { - hawk_rtx_freerex (rtx, rtx->gbl.brs[0], rtx->gbl.brs[1]); - rtx->gbl.brs[0] = HAWK_NULL; - rtx->gbl.brs[1] = HAWK_NULL; - } if (rtx->gbl.rs[0]) { hawk_rtx_freerex (rtx, rtx->gbl.rs[0], rtx->gbl.rs[1]); @@ -6708,11 +6661,39 @@ static hawk_val_t* eval_pos (hawk_rtx_t* rtx, hawk_nde_t* nde) return v; } -static hawk_val_t* __eval_getline (hawk_rtx_t* rtx, hawk_nde_t* nde, int mbs) +static hawk_val_t* nde_to_str(hawk_rtx_t* rtx, hawk_nde_t* nde, hawk_oocs_t* dst) +{ + hawk_oow_t len; + hawk_val_t* v; + + v = eval_expression(rtx, nde); + if (!v) return HAWK_NULL; + + hawk_rtx_refupval (rtx, v); + dst->ptr = hawk_rtx_getvaloocstr(rtx, v, &dst->len); + if (!dst) + { + hawk_rtx_refdownval (rtx, v); + return HAWK_NULL; + } + + while (dst->len > 0) + { + if (dst->ptr[--dst->len] == '\0') + { + dst->len = 0; /* indicate that the name is not valid */ + break; + } + } + + return v; +} + +static hawk_val_t* __eval_getline (hawk_rtx_t* rtx, hawk_nde_t* nde) { hawk_nde_getline_t* p; hawk_val_t* v, * tmp; - hawk_ooch_t* dst; + hawk_oocs_t dst; hawk_ooecs_t* buf; int n, x; hawk_val_type_t vtype; @@ -6727,56 +6708,32 @@ static hawk_val_t* __eval_getline (hawk_rtx_t* rtx, hawk_nde_t* nde, int mbs) if (p->in) { - hawk_oow_t len; - hawk_rtx_valtostr_out_t out; - - v = eval_expression(rtx, p->in); + v = nde_to_str(rtx, p->in, &dst); if (!v) return HAWK_NULL; - hawk_rtx_refupval (rtx, v); - dst = hawk_rtx_getvaloocstr(rtx, v, &len); - if (!dst) + if (dst.len <= 0) { + hawk_rtx_freevaloocstr (rtx, v, dst.ptr); hawk_rtx_refdownval (rtx, v); - return HAWK_NULL; - } - - if (len <= 0) - { - - hawk_rtx_freevaloocstr (rtx, v, dst); - hawk_rtx_refdownval (rtx, v); - n = -1; goto skip_read; } - - while (len > 0) - { - if (dst[--len] == HAWK_T('\0')) - { - /* the input source name contains a null - * character. make getline return -1. - * unlike print & printf, it is not a hard - * error */ - hawk_rtx_freevaloocstr (rtx, v, dst); - hawk_rtx_refdownval (rtx, v); - n = -1; - goto skip_read; - } - } } - else dst = (hawk_ooch_t*)HAWK_T(""); + else + { + dst.ptr = (hawk_ooch_t*)HAWK_T(""); + dst.len = 0; + } buf = &rtx->inrec.lineg; read_console_again: hawk_ooecs_clear (&rtx->inrec.lineg); - n = hawk_rtx_readio(rtx, p->in_type, dst, buf); + n = hawk_rtx_readio(rtx, p->in_type, dst.ptr, buf); if (p->in) { - hawk_rtx_freevaloocstr (rtx, v, dst); + hawk_rtx_freevaloocstr (rtx, v, dst.ptr); hawk_rtx_refdownval (rtx, v); } @@ -6840,9 +6797,119 @@ skip_read: return tmp; } +static hawk_val_t* __eval_getbline (hawk_rtx_t* rtx, hawk_nde_t* nde) +{ + hawk_nde_getline_t* p; + hawk_val_t* v, * tmp; + hawk_oocs_t dst; + hawk_becs_t* buf; + int n, x; + hawk_val_type_t vtype; + + p = (hawk_nde_getline_t*)nde; + + HAWK_ASSERT ( + (p->in_type == HAWK_IN_PIPE && p->in != HAWK_NULL) || + (p->in_type == HAWK_IN_RWPIPE && p->in != HAWK_NULL) || + (p->in_type == HAWK_IN_FILE && p->in != HAWK_NULL) || + (p->in_type == HAWK_IN_CONSOLE && p->in == HAWK_NULL)); + + if (p->in) + { + v = nde_to_str(rtx, p->in, &dst); + if (!v) return HAWK_NULL; + + if (dst.len <= 0) + { + hawk_rtx_freevaloocstr (rtx, v, dst.ptr); + hawk_rtx_refdownval (rtx, v); + n = -1; + goto skip_read; + } + } + else + { + dst.ptr = (hawk_ooch_t*)HAWK_T(""); + dst.len = 0; + } + + buf = &rtx->inrec.linegb; +read_console_again: + hawk_becs_clear (&rtx->inrec.linegb); + + n = hawk_rtx_readiobytes(rtx, p->in_type, dst.ptr, buf); + + if (p->in) + { + hawk_rtx_freevaloocstr (rtx, v, dst.ptr); + hawk_rtx_refdownval (rtx, v); + } + + if (n <= -1) + { + /* make getline return -1 */ + n = -1; + } + else if (n > 0) + { + if (p->in_type == HAWK_IN_CONSOLE) + { + HAWK_ASSERT (p->in == HAWK_NULL); + if (rtx->nrflt.limit > 0) + { + /* record filter based on record number(NR) */ + if (((rtx->gbl.nr / rtx->nrflt.limit) % rtx->nrflt.size) != rtx->nrflt.rank) + { + if (update_fnr(rtx, rtx->gbl.fnr + 1, rtx->gbl.nr + 1) <= -1) return HAWK_NULL; + /* this jump is a bit dirty. the 'if' block below hawk_rtx_readio() + * will never be true. but this makes code confusing */ + goto read_console_again; + } + } + } + + if (p->var == HAWK_NULL) + { + /* set $0 with the input value */ + /*x = hawk_rtx_setbrec(rtx, 0, HAWK_BECS_BCS(buf)); + if (x <= -1) return HAWK_NULL;*/ +/* TODO: can i support this? */ + hawk_rtx_seterrbfmt(rtx, &nde->loc, HAWK_ENOIMPL, "getbline without a variable not supported"); + } + else + { + hawk_val_t* v; + + v = hawk_rtx_makembsvalwithbcs(rtx, HAWK_BECS_BCS(buf)); + if (v == HAWK_NULL) + { + ADJERR_LOC (rtx, &nde->loc); + return HAWK_NULL; + } + + hawk_rtx_refupval (rtx, v); + tmp = do_assignment(rtx, p->var, v); + hawk_rtx_refdownval (rtx, v); + if (tmp == HAWK_NULL) return HAWK_NULL; + } + + /* update FNR & NR if reading from console */ + if (p->in_type == HAWK_IN_CONSOLE && + update_fnr(rtx, rtx->gbl.fnr + 1, rtx->gbl.nr + 1) <= -1) + { + return HAWK_NULL; + } + } + +skip_read: + tmp = hawk_rtx_makeintval(rtx, n); + if (!tmp) ADJERR_LOC (rtx, &nde->loc); + return tmp; +} + static hawk_val_t* eval_getline (hawk_rtx_t* rtx, hawk_nde_t* nde) { - return __eval_getline(rtx, nde, 0); + return ((hawk_nde_getline_t*)nde)->mbs? __eval_getbline(rtx, nde): __eval_getline(rtx, nde); } static hawk_val_t* eval_print (hawk_rtx_t* run, hawk_nde_t* nde) @@ -6894,7 +6961,7 @@ read_again: if (hawk_rtx_clrrec (rtx, 0) == -1) return -1; buf = &rtx->inrec.line; - n = hawk_rtx_readio (rtx, HAWK_IN_CONSOLE, HAWK_T(""), buf); + n = hawk_rtx_readio(rtx, HAWK_IN_CONSOLE, HAWK_T(""), buf); if (n <= -1) { hawk_rtx_clrrec (rtx, 0); diff --git a/hawk/lib/tre.c b/hawk/lib/tre.c index 956f7362..c97cfd33 100644 --- a/hawk/lib/tre.c +++ b/hawk/lib/tre.c @@ -237,9 +237,55 @@ int hawk_tre_execx ( return 0; } + int hawk_tre_exec ( hawk_tre_t* tre, const hawk_ooch_t* str, regmatch_t* pmatch, hawk_oow_t nmatch, int eflags, hawk_gem_t* errgem) { return hawk_tre_execx(tre, str, (hawk_oow_t)-1, pmatch, nmatch, eflags, errgem); } + +int hawk_tre_execuchars ( + hawk_tre_t* tre, const hawk_uch_t* str, hawk_oow_t len, + regmatch_t* pmatch, hawk_oow_t nmatch, int eflags, hawk_gem_t* errgem) +{ + int ret; + + if (tre->TRE_REGEX_T_FIELD == HAWK_NULL) + { + /* regular expression is bad as none is compiled yet */ + hawk_gem_seterrnum ((errgem? errgem: tre->gem), HAWK_NULL, HAWK_EREXBADPAT); + return -1; + } + ret = tre_match(tre, str, len, STR_WIDE, nmatch, pmatch, eflags); + if (ret > 0) + { + hawk_gem_seterrnum ((errgem? errgem: tre->gem), HAWK_NULL, ret); + return -1; + } + + return 0; +} + +int hawk_tre_execbchars ( + hawk_tre_t* tre, const hawk_bch_t* str, hawk_oow_t len, + regmatch_t* pmatch, hawk_oow_t nmatch, int eflags, hawk_gem_t* errgem) +{ + int ret; + + if (tre->TRE_REGEX_T_FIELD == HAWK_NULL) + { + /* regular expression is bad as none is compiled yet */ + hawk_gem_seterrnum ((errgem? errgem: tre->gem), HAWK_NULL, HAWK_EREXBADPAT); + return -1; + } + ret = tre_match(tre, str, len, STR_BYTE, nmatch, pmatch, eflags); + if (ret > 0) + { + hawk_gem_seterrnum ((errgem? errgem: tre->gem), HAWK_NULL, ret); + return -1; + } + + return 0; +} + diff --git a/hawk/lib/tree-prv.h b/hawk/lib/tree-prv.h index 95d018c9..6ac64a9e 100644 --- a/hawk/lib/tree-prv.h +++ b/hawk/lib/tree-prv.h @@ -231,7 +231,8 @@ struct hawk_nde_getline_t { HAWK_NDE_HDR; hawk_nde_t* var; - int in_type; /* HAWK_GETLINE_XXX */ + int mbs; + int in_type; /* HAWK_IN_CONSOLE, HAWK_IN_FILE, etc */ hawk_nde_t* in; }; diff --git a/hawk/lib/tree.c b/hawk/lib/tree.c index 0214470c..782a40b1 100644 --- a/hawk/lib/tree.c +++ b/hawk/lib/tree.c @@ -730,7 +730,7 @@ static int print_expr (hawk_t* awk, hawk_nde_t* nde) PUT_SRCSTR (awk, HAWK_T(" ")); } - hawk_getkwname (awk, HAWK_KWID_GETLINE, &kw); + hawk_getkwname (awk, (px->mbs? HAWK_KWID_GETBLINE: HAWK_KWID_GETLINE), &kw); PUT_SRCSTRN (awk, kw.ptr, kw.len); if (px->var != HAWK_NULL) {