aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editors/awk.c64
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 =
432static const uint32_t tokeninfo[] ALIGN4 = { 432static 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
1311static void mk_re_node(const char *s, node *n, regex_t *re) 1318static 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;