aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-07-03 13:57:47 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2021-07-03 14:11:51 +0200
commit08ca313d7edb99687068b93b5d2435b59f3db23a (patch)
tree2a5a11f44574b0db7b1b4595e644663f62003db2
parentcb042b05828c4c89320bc9c7454c04c2761bbb9a (diff)
downloadbusybox-w32-08ca313d7edb99687068b93b5d2435b59f3db23a.tar.gz
busybox-w32-08ca313d7edb99687068b93b5d2435b59f3db23a.tar.bz2
busybox-w32-08ca313d7edb99687068b93b5d2435b59f3db23a.zip
awk: simplify tests for operation class
Usually, an operation class has only one possible value of "info" word. In this case, just compare the entire info word, do not bother to mask OPCLSMASK bits. (Example where this is not the case: OC_REPLACE for "<op>=") function old new delta mk_splitter 106 100 -6 chain_group 616 610 -6 nextarg 40 32 -8 exec_builtin 1157 1149 -8 as_regex 111 103 -8 awk_split 553 543 -10 parse_expr 948 936 -12 awk_getline 656 642 -14 evaluate 3387 3343 -44 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/9 up/down: 0/-116) Total: -116 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-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;