diff options
-rw-r--r-- | editors/awk.c | 64 |
1 files changed, 36 insertions, 28 deletions
diff --git a/editors/awk.c b/editors/awk.c index 20672db9a..cd135ef64 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -432,7 +432,8 @@ static const char tokenlist[] ALIGN1 = | |||
432 | static const uint32_t tokeninfo[] ALIGN4 = { | 432 | static const uint32_t tokeninfo[] ALIGN4 = { |
433 | 0, | 433 | 0, |
434 | 0, | 434 | 0, |
435 | OC_REGEXP, | 435 | #define TI_REGEXP OC_REGEXP |
436 | TI_REGEXP, | ||
436 | xS|'a', xS|'w', xS|'|', | 437 | xS|'a', xS|'w', xS|'|', |
437 | OC_UNARY|xV|P(9)|'p', OC_UNARY|xV|P(9)|'m', | 438 | OC_UNARY|xV|P(9)|'p', OC_UNARY|xV|P(9)|'m', |
438 | #define TI_PREINC (OC_UNARY|xV|P(9)|'P') | 439 | #define TI_PREINC (OC_UNARY|xV|P(9)|'P') |
@@ -443,12 +444,17 @@ static const uint32_t tokeninfo[] ALIGN4 = { | |||
443 | OC_BINARY|NV|P(29)|'+', OC_BINARY|NV|P(29)|'-', OC_REPLACE|NV|P(74)|'&', OC_BINARY|NV|P(15)|'&', | 444 | OC_BINARY|NV|P(29)|'+', OC_BINARY|NV|P(29)|'-', OC_REPLACE|NV|P(74)|'&', OC_BINARY|NV|P(15)|'&', |
444 | OC_BINARY|NV|P(25)|'/', OC_BINARY|NV|P(25)|'%', OC_BINARY|NV|P(15)|'&', OC_BINARY|NV|P(25)|'*', | 445 | OC_BINARY|NV|P(25)|'/', OC_BINARY|NV|P(25)|'%', OC_BINARY|NV|P(15)|'&', OC_BINARY|NV|P(25)|'*', |
445 | OC_COMPARE|VV|P(39)|4, OC_COMPARE|VV|P(39)|3, OC_COMPARE|VV|P(39)|0, OC_COMPARE|VV|P(39)|1, | 446 | OC_COMPARE|VV|P(39)|4, OC_COMPARE|VV|P(39)|3, OC_COMPARE|VV|P(39)|0, OC_COMPARE|VV|P(39)|1, |
446 | #define TI_LESS (OC_COMPARE|VV|P(39)|2) | 447 | #define TI_LESS (OC_COMPARE|VV|P(39)|2) |
447 | TI_LESS, OC_MATCH|Sx|P(45)|'!', OC_MATCH|Sx|P(45)|'~', OC_LAND|Vx|P(55), | 448 | TI_LESS, OC_MATCH|Sx|P(45)|'!', OC_MATCH|Sx|P(45)|'~', OC_LAND|Vx|P(55), |
448 | OC_LOR|Vx|P(59), OC_TERNARY|Vx|P(64)|'?', OC_COLON|xx|P(67)|':', | 449 | #define TI_TERNARY (OC_TERNARY|Vx|P(64)|'?') |
449 | OC_IN|SV|P(49), /* TC_IN */ | 450 | #define TI_COLON (OC_COLON|xx|P(67)|':') |
450 | OC_COMMA|SS|P(80), | 451 | OC_LOR|Vx|P(59), TI_TERNARY, TI_COLON, |
451 | OC_PGETLINE|SV|P(37), | 452 | #define TI_IN (OC_IN|SV|P(49)) |
453 | TI_IN, | ||
454 | #define TI_COMMA (OC_COMMA|SS|P(80)) | ||
455 | TI_COMMA, | ||
456 | #define TI_PGETLINE (OC_PGETLINE|SV|P(37)) | ||
457 | TI_PGETLINE, | ||
452 | OC_UNARY|xV|P(19)|'+', OC_UNARY|xV|P(19)|'-', OC_UNARY|xV|P(19)|'!', | 458 | OC_UNARY|xV|P(19)|'+', OC_UNARY|xV|P(19)|'-', OC_UNARY|xV|P(19)|'!', |
453 | 0, /* ] */ | 459 | 0, /* ] */ |
454 | 0, | 460 | 0, |
@@ -456,7 +462,8 @@ static const uint32_t tokeninfo[] ALIGN4 = { | |||
456 | 0, | 462 | 0, |
457 | 0, /* \n */ | 463 | 0, /* \n */ |
458 | ST_IF, ST_DO, ST_FOR, OC_BREAK, | 464 | ST_IF, ST_DO, ST_FOR, OC_BREAK, |
459 | OC_CONTINUE, OC_DELETE|Rx, OC_PRINT, | 465 | #define TI_PRINT OC_PRINT |
466 | OC_CONTINUE, OC_DELETE|Rx, TI_PRINT, | ||
460 | OC_PRINTF, OC_NEXT, OC_NEXTFILE, | 467 | OC_PRINTF, OC_NEXT, OC_NEXTFILE, |
461 | OC_RETURN|Vx, OC_EXIT|Nx, | 468 | OC_RETURN|Vx, OC_EXIT|Nx, |
462 | ST_WHILE, | 469 | ST_WHILE, |
@@ -465,8 +472,8 @@ static const uint32_t tokeninfo[] ALIGN4 = { | |||
465 | // Highest byte bit pattern: nn s3s2s1 v3v2v1 | 472 | // Highest byte bit pattern: nn s3s2s1 v3v2v1 |
466 | // nn - min. number of args, sN - resolve Nth arg to string, vN - resolve to var | 473 | // nn - min. number of args, sN - resolve Nth arg to string, vN - resolve to var |
467 | // OC_F's are builtins with zero or one argument. | 474 | // OC_F's are builtins with zero or one argument. |
468 | // |Rx| enforces that arg is present for: system, close, cos, sin, exp, int, log, sqrt. | 475 | // |Rx| enforces that arg is present for: system, close, cos, sin, exp, int, log, sqrt |
469 | // Check for no args is present in builtins' code (not in this table): rand, systime. | 476 | // Check for no args is present in builtins' code (not in this table): rand, systime |
470 | // Have one _optional_ arg: fflush, srand, length | 477 | // Have one _optional_ arg: fflush, srand, length |
471 | #define OC_B OC_BUILTIN | 478 | #define OC_B OC_BUILTIN |
472 | #define OC_F OC_FBLTIN | 479 | #define OC_F OC_FBLTIN |
@@ -1310,7 +1317,7 @@ static node *new_node(uint32_t info) | |||
1310 | 1317 | ||
1311 | static void mk_re_node(const char *s, node *n, regex_t *re) | 1318 | static void mk_re_node(const char *s, node *n, regex_t *re) |
1312 | { | 1319 | { |
1313 | n->info = OC_REGEXP; | 1320 | n->info = TI_REGEXP; |
1314 | n->l.re = re; | 1321 | n->l.re = re; |
1315 | n->r.ire = re + 1; | 1322 | n->r.ire = re + 1; |
1316 | xregcomp(re, s, REG_EXTENDED); | 1323 | xregcomp(re, s, REG_EXTENDED); |
@@ -1360,12 +1367,13 @@ static node *parse_expr(uint32_t term_tc) | |||
1360 | * previous operators with higher priority */ | 1367 | * previous operators with higher priority */ |
1361 | vn = cn; | 1368 | vn = cn; |
1362 | while (((t_info & PRIMASK) > (vn->a.n->info & PRIMASK2)) | 1369 | while (((t_info & PRIMASK) > (vn->a.n->info & PRIMASK2)) |
1363 | || ((t_info == vn->info) && ((t_info & OPCLSMASK) == OC_COLON)) | 1370 | || ((t_info == vn->info) && t_info == TI_COLON) |
1364 | ) { | 1371 | ) { |
1365 | vn = vn->a.n; | 1372 | vn = vn->a.n; |
1366 | if (!vn->a.n) syntax_error(EMSG_UNEXP_TOKEN); | 1373 | if (!vn->a.n) syntax_error(EMSG_UNEXP_TOKEN); |
1367 | } | 1374 | } |
1368 | if ((t_info & OPCLSMASK) == OC_TERNARY) | 1375 | if (t_info == TI_TERNARY) |
1376 | //TODO: why? | ||
1369 | t_info += P(6); | 1377 | t_info += P(6); |
1370 | cn = vn->a.n->r.n = new_node(t_info); | 1378 | cn = vn->a.n->r.n = new_node(t_info); |
1371 | cn->a.n = vn->a.n; | 1379 | cn->a.n = vn->a.n; |
@@ -1378,7 +1386,7 @@ static node *parse_expr(uint32_t term_tc) | |||
1378 | // awk 'BEGIN { length("qwe") = 1 }' | 1386 | // awk 'BEGIN { length("qwe") = 1 }' |
1379 | // awk 'BEGIN { (1+1) += 3 }' | 1387 | // awk 'BEGIN { (1+1) += 3 }' |
1380 | expected_tc = TS_OPERAND | TS_UOPPRE | TC_REGEXP; | 1388 | expected_tc = TS_OPERAND | TS_UOPPRE | TC_REGEXP; |
1381 | if ((t_info & OPCLSMASK) == OC_PGETLINE) { | 1389 | if (t_info == TI_PGETLINE) { |
1382 | /* it's a pipe */ | 1390 | /* it's a pipe */ |
1383 | next_token(TC_GETLINE); | 1391 | next_token(TC_GETLINE); |
1384 | /* give maximum priority to this pipe */ | 1392 | /* give maximum priority to this pipe */ |
@@ -1630,7 +1638,7 @@ static void chain_group(void) | |||
1630 | next_token(TC_LPAREN); | 1638 | next_token(TC_LPAREN); |
1631 | n2 = parse_expr(TC_SEMICOL | TC_RPAREN); | 1639 | n2 = parse_expr(TC_SEMICOL | TC_RPAREN); |
1632 | if (t_tclass & TC_RPAREN) { /* for-in */ | 1640 | if (t_tclass & TC_RPAREN) { /* for-in */ |
1633 | if (!n2 || (n2->info & OPCLSMASK) != OC_IN) | 1641 | if (!n2 || n2->info != TI_IN) |
1634 | syntax_error(EMSG_UNEXP_TOKEN); | 1642 | syntax_error(EMSG_UNEXP_TOKEN); |
1635 | n = chain_node(OC_WALKINIT | VV); | 1643 | n = chain_node(OC_WALKINIT | VV); |
1636 | n->l.n = n2->l.n; | 1644 | n->l.n = n2->l.n; |
@@ -1834,7 +1842,7 @@ static node *mk_splitter(const char *s, tsplitter *spl) | |||
1834 | re = &spl->re[0]; | 1842 | re = &spl->re[0]; |
1835 | ire = &spl->re[1]; | 1843 | ire = &spl->re[1]; |
1836 | n = &spl->n; | 1844 | n = &spl->n; |
1837 | if ((n->info & OPCLSMASK) == OC_REGEXP) { | 1845 | if (n->info == TI_REGEXP) { |
1838 | regfree(re); | 1846 | regfree(re); |
1839 | regfree(ire); // TODO: nuke ire, use re+1? | 1847 | regfree(ire); // TODO: nuke ire, use re+1? |
1840 | } | 1848 | } |
@@ -1858,7 +1866,7 @@ static regex_t *as_regex(node *op, regex_t *preg) | |||
1858 | int cflags; | 1866 | int cflags; |
1859 | const char *s; | 1867 | const char *s; |
1860 | 1868 | ||
1861 | if ((op->info & OPCLSMASK) == OC_REGEXP) { | 1869 | if (op->info == TI_REGEXP) { |
1862 | return icase ? op->r.ire : op->l.re; | 1870 | return icase ? op->r.ire : op->l.re; |
1863 | } | 1871 | } |
1864 | 1872 | ||
@@ -1968,7 +1976,7 @@ static int awk_split(const char *s, node *spl, char **slist) | |||
1968 | c[2] = '\n'; | 1976 | c[2] = '\n'; |
1969 | 1977 | ||
1970 | n = 0; | 1978 | n = 0; |
1971 | if ((spl->info & OPCLSMASK) == OC_REGEXP) { /* regex split */ | 1979 | if (spl->info == TI_REGEXP) { /* regex split */ |
1972 | if (!*s) | 1980 | if (!*s) |
1973 | return n; /* "": zero fields */ | 1981 | return n; /* "": zero fields */ |
1974 | n++; /* at least one field will be there */ | 1982 | n++; /* at least one field will be there */ |
@@ -2135,7 +2143,7 @@ static node *nextarg(node **pn) | |||
2135 | node *n; | 2143 | node *n; |
2136 | 2144 | ||
2137 | n = *pn; | 2145 | n = *pn; |
2138 | if (n && (n->info & OPCLSMASK) == OC_COMMA) { | 2146 | if (n && n->info == TI_COMMA) { |
2139 | *pn = n->r.n; | 2147 | *pn = n->r.n; |
2140 | n = n->l.n; | 2148 | n = n->l.n; |
2141 | } else { | 2149 | } else { |
@@ -2229,7 +2237,7 @@ static int awk_getline(rstream *rsm, var *v) | |||
2229 | so = eo = p; | 2237 | so = eo = p; |
2230 | r = 1; | 2238 | r = 1; |
2231 | if (p > 0) { | 2239 | if (p > 0) { |
2232 | if ((rsplitter.n.info & OPCLSMASK) == OC_REGEXP) { | 2240 | if (rsplitter.n.info == TI_REGEXP) { |
2233 | if (regexec(icase ? rsplitter.n.r.ire : rsplitter.n.l.re, | 2241 | if (regexec(icase ? rsplitter.n.r.ire : rsplitter.n.l.re, |
2234 | b, 1, pmatch, 0) == 0) { | 2242 | b, 1, pmatch, 0) == 0) { |
2235 | so = pmatch[0].rm_so; | 2243 | so = pmatch[0].rm_so; |
@@ -2575,8 +2583,8 @@ static NOINLINE var *exec_builtin(node *op, var *res) | |||
2575 | char *s, *s1; | 2583 | char *s, *s1; |
2576 | 2584 | ||
2577 | if (nargs > 2) { | 2585 | if (nargs > 2) { |
2578 | spl = (an[2]->info & OPCLSMASK) == OC_REGEXP ? | 2586 | spl = (an[2]->info == TI_REGEXP) ? an[2] |
2579 | an[2] : mk_splitter(getvar_s(evaluate(an[2], TMPVAR2)), &tspl); | 2587 | : mk_splitter(getvar_s(evaluate(an[2], TMPVAR2)), &tspl); |
2580 | } else { | 2588 | } else { |
2581 | spl = &fsplitter.n; | 2589 | spl = &fsplitter.n; |
2582 | } | 2590 | } |
@@ -2860,7 +2868,7 @@ static var *evaluate(node *op, var *res) | |||
2860 | /* test pattern */ | 2868 | /* test pattern */ |
2861 | case XC( OC_TEST ): | 2869 | case XC( OC_TEST ): |
2862 | debug_printf_eval("TEST\n"); | 2870 | debug_printf_eval("TEST\n"); |
2863 | if ((op1->info & OPCLSMASK) == OC_COMMA) { | 2871 | if (op1->info == TI_COMMA) { |
2864 | /* it's range pattern */ | 2872 | /* it's range pattern */ |
2865 | if ((opinfo & OF_CHECKED) || ptest(op1->l.n)) { | 2873 | if ((opinfo & OF_CHECKED) || ptest(op1->l.n)) { |
2866 | op->info |= OF_CHECKED; | 2874 | op->info |= OF_CHECKED; |
@@ -2921,7 +2929,7 @@ static var *evaluate(node *op, var *res) | |||
2921 | F = rsm->F; | 2929 | F = rsm->F; |
2922 | } | 2930 | } |
2923 | 2931 | ||
2924 | if ((opinfo & OPCLSMASK) == OC_PRINT) { | 2932 | if (opinfo == TI_PRINT) { |
2925 | if (!op1) { | 2933 | if (!op1) { |
2926 | fputs(getvar_s(intvar[F0]), F); | 2934 | fputs(getvar_s(intvar[F0]), F); |
2927 | } else { | 2935 | } else { |
@@ -2940,7 +2948,7 @@ static var *evaluate(node *op, var *res) | |||
2940 | } | 2948 | } |
2941 | } | 2949 | } |
2942 | fputs(getvar_s(intvar[ORS]), F); | 2950 | fputs(getvar_s(intvar[ORS]), F); |
2943 | } else { /* OC_PRINTF */ | 2951 | } else { /* PRINTF */ |
2944 | char *s = awk_printf(op1, &len); | 2952 | char *s = awk_printf(op1, &len); |
2945 | #if ENABLE_FEATURE_AWK_GNU_EXTENSIONS | 2953 | #if ENABLE_FEATURE_AWK_GNU_EXTENSIONS |
2946 | fwrite(s, len, 1, F); | 2954 | fwrite(s, len, 1, F); |
@@ -3064,7 +3072,7 @@ static var *evaluate(node *op, var *res) | |||
3064 | 3072 | ||
3065 | case XC( OC_TERNARY ): | 3073 | case XC( OC_TERNARY ): |
3066 | debug_printf_eval("TERNARY\n"); | 3074 | debug_printf_eval("TERNARY\n"); |
3067 | if ((op->r.n->info & OPCLSMASK) != OC_COLON) | 3075 | if (op->r.n->info != TI_COLON) |
3068 | syntax_error(EMSG_POSSIBLE_ERROR); | 3076 | syntax_error(EMSG_POSSIBLE_ERROR); |
3069 | res = evaluate(istrue(L.v) ? op->r.n->l.n : op->r.n->r.n, res); | 3077 | res = evaluate(istrue(L.v) ? op->r.n->l.n : op->r.n->r.n, res); |
3070 | break; | 3078 | break; |
@@ -3122,7 +3130,7 @@ static var *evaluate(node *op, var *res) | |||
3122 | if (op1) { | 3130 | if (op1) { |
3123 | rsm = newfile(L.s); | 3131 | rsm = newfile(L.s); |
3124 | if (!rsm->F) { | 3132 | if (!rsm->F) { |
3125 | if ((opinfo & OPCLSMASK) == OC_PGETLINE) { | 3133 | if (opinfo == TI_PGETLINE) { |
3126 | rsm->F = popen(L.s, "r"); | 3134 | rsm->F = popen(L.s, "r"); |
3127 | rsm->is_pipe = TRUE; | 3135 | rsm->is_pipe = TRUE; |
3128 | } else { | 3136 | } else { |
@@ -3158,7 +3166,7 @@ static var *evaluate(node *op, var *res) | |||
3158 | double R_d = R_d; /* for compiler */ | 3166 | double R_d = R_d; /* for compiler */ |
3159 | debug_printf_eval("FBLTIN\n"); | 3167 | debug_printf_eval("FBLTIN\n"); |
3160 | 3168 | ||
3161 | if (op1 && (op1->info & OPCLSMASK) == OC_COMMA) | 3169 | if (op1 && op1->info == TI_COMMA) |
3162 | /* Simple builtins take one arg maximum */ | 3170 | /* Simple builtins take one arg maximum */ |
3163 | syntax_error("Too many arguments"); | 3171 | syntax_error("Too many arguments"); |
3164 | 3172 | ||
@@ -3358,7 +3366,7 @@ static var *evaluate(node *op, var *res) | |||
3358 | case XC( OC_COMMA ): { | 3366 | case XC( OC_COMMA ): { |
3359 | const char *sep = ""; | 3367 | const char *sep = ""; |
3360 | debug_printf_eval("COMMA\n"); | 3368 | debug_printf_eval("COMMA\n"); |
3361 | if ((opinfo & OPCLSMASK) == OC_COMMA) | 3369 | if (opinfo == TI_COMMA) |
3362 | sep = getvar_s(intvar[SUBSEP]); | 3370 | sep = getvar_s(intvar[SUBSEP]); |
3363 | setvar_p(res, xasprintf("%s%s%s", L.s, sep, R.s)); | 3371 | setvar_p(res, xasprintf("%s%s%s", L.s, sep, R.s)); |
3364 | break; | 3372 | break; |