diff options
| -rw-r--r-- | editors/awk.c | 94 |
1 files changed, 47 insertions, 47 deletions
diff --git a/editors/awk.c b/editors/awk.c index 9a3b63df6..d31b97d86 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
| @@ -207,48 +207,48 @@ typedef struct tsplitter_s { | |||
| 207 | } tsplitter; | 207 | } tsplitter; |
| 208 | 208 | ||
| 209 | /* simple token classes */ | 209 | /* simple token classes */ |
| 210 | /* Order and hex values are very important!!! See next_token() */ | 210 | /* order and hex values are very important!!! See next_token() */ |
| 211 | #define TC_SEQSTART (1 << 0) /* ( */ | 211 | #define TC_LPAREN (1 << 0) /* ( */ |
| 212 | #define TC_SEQTERM (1 << 1) /* ) */ | 212 | #define TC_RPAREN (1 << 1) /* ) */ |
| 213 | #define TC_REGEXP (1 << 2) /* /.../ */ | 213 | #define TC_REGEXP (1 << 2) /* /.../ */ |
| 214 | #define TC_OUTRDR (1 << 3) /* | > >> */ | 214 | #define TC_OUTRDR (1 << 3) /* | > >> */ |
| 215 | #define TC_UOPPOST (1 << 4) /* unary postfix operator ++ -- */ | 215 | #define TC_UOPPOST (1 << 4) /* unary postfix operator ++ -- */ |
| 216 | #define TC_UOPPRE1 (1 << 5) /* unary prefix operator ++ -- $ */ | 216 | #define TC_UOPPRE1 (1 << 5) /* unary prefix operator ++ -- $ */ |
| 217 | #define TC_BINOPX (1 << 6) /* two-opnd operator */ | 217 | #define TC_BINOPX (1 << 6) /* two-opnd operator */ |
| 218 | #define TC_IN (1 << 7) | 218 | #define TC_IN (1 << 7) /* 'in' */ |
| 219 | #define TC_COMMA (1 << 8) | 219 | #define TC_COMMA (1 << 8) /* , */ |
| 220 | #define TC_PIPE (1 << 9) /* input redirection pipe */ | 220 | #define TC_PIPE (1 << 9) /* input redirection pipe | */ |
| 221 | #define TC_UOPPRE2 (1 << 10) /* unary prefix operator + - ! */ | 221 | #define TC_UOPPRE2 (1 << 10) /* unary prefix operator + - ! */ |
| 222 | #define TC_ARRTERM (1 << 11) /* ] */ | 222 | #define TC_ARRTERM (1 << 11) /* ] */ |
| 223 | #define TC_GRPSTART (1 << 12) /* { */ | 223 | #define TC_GRPSTART (1 << 12) /* { */ |
| 224 | #define TC_GRPTERM (1 << 13) /* } */ | 224 | #define TC_GRPTERM (1 << 13) /* } */ |
| 225 | #define TC_SEMICOL (1 << 14) | 225 | #define TC_SEMICOL (1 << 14) /* ; */ |
| 226 | #define TC_NEWLINE (1 << 15) | 226 | #define TC_NEWLINE (1 << 15) |
| 227 | #define TC_STATX (1 << 16) /* ctl statement (for, next...) */ | 227 | #define TC_STATX (1 << 16) /* ctl statement (for, next...) */ |
| 228 | #define TC_WHILE (1 << 17) | 228 | #define TC_WHILE (1 << 17) /* 'while' */ |
| 229 | #define TC_ELSE (1 << 18) | 229 | #define TC_ELSE (1 << 18) /* 'else' */ |
| 230 | #define TC_BUILTIN (1 << 19) | 230 | #define TC_BUILTIN (1 << 19) |
| 231 | /* This costs ~50 bytes of code. | 231 | /* This costs ~50 bytes of code. |
| 232 | * A separate class to support deprecated "length" form. If we don't need that | 232 | * A separate class to support deprecated "length" form. If we don't need that |
| 233 | * (i.e. if we demand that only "length()" with () is valid), then TC_LENGTH | 233 | * (i.e. if we demand that only "length()" with () is valid), then TC_LENGTH |
| 234 | * can be merged with TC_BUILTIN: | 234 | * can be merged with TC_BUILTIN: |
| 235 | */ | 235 | */ |
| 236 | #define TC_LENGTH (1 << 20) | 236 | #define TC_LENGTH (1 << 20) /* 'length' */ |
| 237 | #define TC_GETLINE (1 << 21) | 237 | #define TC_GETLINE (1 << 21) /* 'getline' */ |
| 238 | #define TC_FUNCDECL (1 << 22) /* 'function' 'func' */ | 238 | #define TC_FUNCDECL (1 << 22) /* 'function' 'func' */ |
| 239 | #define TC_BEGIN (1 << 23) | 239 | #define TC_BEGIN (1 << 23) /* 'BEGIN' */ |
| 240 | #define TC_END (1 << 24) | 240 | #define TC_END (1 << 24) /* 'END' */ |
| 241 | #define TC_EOF (1 << 25) | 241 | #define TC_EOF (1 << 25) |
| 242 | #define TC_VARIABLE (1 << 26) | 242 | #define TC_VARIABLE (1 << 26) /* name */ |
| 243 | #define TC_ARRAY (1 << 27) | 243 | #define TC_ARRAY (1 << 27) /* name[ */ |
| 244 | #define TC_FUNCTION (1 << 28) | 244 | #define TC_FUNCTION (1 << 28) /* name( - but unlike TC_ARRAY, parser does not consume '(' */ |
| 245 | #define TC_STRING (1 << 29) | 245 | #define TC_STRING (1 << 29) /* "..." */ |
| 246 | #define TC_NUMBER (1 << 30) | 246 | #define TC_NUMBER (1 << 30) |
| 247 | 247 | ||
| 248 | #ifndef debug_parse_print_tc | 248 | #ifndef debug_parse_print_tc |
| 249 | #define debug_parse_print_tc(n) do { \ | 249 | #define debug_parse_print_tc(n) do { \ |
| 250 | if ((n) & TC_SEQSTART) debug_printf_parse(" SEQSTART"); \ | 250 | if ((n) & TC_LPAREN ) debug_printf_parse(" LPAREN" ); \ |
| 251 | if ((n) & TC_SEQTERM ) debug_printf_parse(" SEQTERM" ); \ | 251 | if ((n) & TC_RPAREN ) debug_printf_parse(" RPAREN" ); \ |
| 252 | if ((n) & TC_REGEXP ) debug_printf_parse(" REGEXP" ); \ | 252 | if ((n) & TC_REGEXP ) debug_printf_parse(" REGEXP" ); \ |
| 253 | if ((n) & TC_OUTRDR ) debug_printf_parse(" OUTRDR" ); \ | 253 | if ((n) & TC_OUTRDR ) debug_printf_parse(" OUTRDR" ); \ |
| 254 | if ((n) & TC_UOPPOST ) debug_printf_parse(" UOPPOST" ); \ | 254 | if ((n) & TC_UOPPOST ) debug_printf_parse(" UOPPOST" ); \ |
| @@ -288,7 +288,7 @@ if ((n) & TC_NUMBER ) debug_printf_parse(" NUMBER" ); \ | |||
| 288 | //#define TS_UNARYOP (TS_UOPPRE | TC_UOPPOST) | 288 | //#define TS_UNARYOP (TS_UOPPRE | TC_UOPPOST) |
| 289 | #define TS_OPERAND (TC_VARIABLE | TC_ARRAY | TC_FUNCTION \ | 289 | #define TS_OPERAND (TC_VARIABLE | TC_ARRAY | TC_FUNCTION \ |
| 290 | | TC_BUILTIN | TC_LENGTH | TC_GETLINE \ | 290 | | TC_BUILTIN | TC_LENGTH | TC_GETLINE \ |
| 291 | | TC_SEQSTART | TC_STRING | TC_NUMBER) | 291 | | TC_LPAREN | TC_STRING | TC_NUMBER) |
| 292 | 292 | ||
| 293 | #define TS_LVALUE (TC_VARIABLE | TC_ARRAY) | 293 | #define TS_LVALUE (TC_VARIABLE | TC_ARRAY) |
| 294 | #define TS_STATEMNT (TC_STATX | TC_WHILE) | 294 | #define TS_STATEMNT (TC_STATX | TC_WHILE) |
| @@ -310,7 +310,7 @@ if ((n) & TC_NUMBER ) debug_printf_parse(" NUMBER" ); \ | |||
| 310 | 310 | ||
| 311 | /* if previous token class is CONCAT_L and next is CONCAT_R, concatenation */ | 311 | /* if previous token class is CONCAT_L and next is CONCAT_R, concatenation */ |
| 312 | /* operator is inserted between them */ | 312 | /* operator is inserted between them */ |
| 313 | #define TS_CONCAT_L (TC_VARIABLE | TC_ARRTERM | TC_SEQTERM \ | 313 | #define TS_CONCAT_L (TC_VARIABLE | TC_ARRTERM | TC_RPAREN \ |
| 314 | | TC_STRING | TC_NUMBER | TC_UOPPOST \ | 314 | | TC_STRING | TC_NUMBER | TC_UOPPOST \ |
| 315 | | TC_LENGTH) | 315 | | TC_LENGTH) |
| 316 | #define TS_CONCAT_R (TS_OPERAND | TS_UOPPRE) | 316 | #define TS_CONCAT_R (TS_OPERAND | TS_UOPPRE) |
| @@ -394,8 +394,8 @@ enum { | |||
| 394 | #define NTCC '\377' | 394 | #define NTCC '\377' |
| 395 | 395 | ||
| 396 | static const char tokenlist[] ALIGN1 = | 396 | static const char tokenlist[] ALIGN1 = |
| 397 | "\1(" NTC /* TC_SEQSTART */ | 397 | "\1(" NTC /* TC_LPAREN */ |
| 398 | "\1)" NTC /* TC_SEQTERM */ | 398 | "\1)" NTC /* TC_RPAREN */ |
| 399 | "\1/" NTC /* TC_REGEXP */ | 399 | "\1/" NTC /* TC_REGEXP */ |
| 400 | "\2>>" "\1>" "\1|" NTC /* TC_OUTRDR */ | 400 | "\2>>" "\1>" "\1|" NTC /* TC_OUTRDR */ |
| 401 | "\2++" "\2--" NTC /* TC_UOPPOST */ | 401 | "\2++" "\2--" NTC /* TC_UOPPOST */ |
| @@ -1250,9 +1250,9 @@ static uint32_t next_token(uint32_t expected) | |||
| 1250 | /* insert concatenation operator when needed */ | 1250 | /* insert concatenation operator when needed */ |
| 1251 | debug_printf_parse("%s: concat_inserted if all nonzero: %x %x %x %x\n", __func__, | 1251 | debug_printf_parse("%s: concat_inserted if all nonzero: %x %x %x %x\n", __func__, |
| 1252 | (last_token_class & TS_CONCAT_L), (tc & TS_CONCAT_R), (expected & TS_BINOP), | 1252 | (last_token_class & TS_CONCAT_L), (tc & TS_CONCAT_R), (expected & TS_BINOP), |
| 1253 | !(last_token_class == TC_LENGTH && tc == TC_SEQSTART)); | 1253 | !(last_token_class == TC_LENGTH && tc == TC_LPAREN)); |
| 1254 | if ((last_token_class & TS_CONCAT_L) && (tc & TS_CONCAT_R) && (expected & TS_BINOP) | 1254 | if ((last_token_class & TS_CONCAT_L) && (tc & TS_CONCAT_R) && (expected & TS_BINOP) |
| 1255 | && !(last_token_class == TC_LENGTH && tc == TC_SEQSTART) /* but not for "length(..." */ | 1255 | && !(last_token_class == TC_LENGTH && tc == TC_LPAREN) /* but not for "length(..." */ |
| 1256 | ) { | 1256 | ) { |
| 1257 | concat_inserted = TRUE; | 1257 | concat_inserted = TRUE; |
| 1258 | save_tclass = tc; | 1258 | save_tclass = tc; |
| @@ -1304,10 +1304,10 @@ static void mk_re_node(const char *s, node *n, regex_t *re) | |||
| 1304 | xregcomp(re + 1, s, REG_EXTENDED | REG_ICASE); | 1304 | xregcomp(re + 1, s, REG_EXTENDED | REG_ICASE); |
| 1305 | } | 1305 | } |
| 1306 | 1306 | ||
| 1307 | static node *condition(void) | 1307 | static node *parse_lrparen_list(void) |
| 1308 | { | 1308 | { |
| 1309 | next_token(TC_SEQSTART); | 1309 | next_token(TC_LPAREN); |
| 1310 | return parse_expr(TC_SEQTERM); | 1310 | return parse_expr(TC_RPAREN); |
| 1311 | } | 1311 | } |
| 1312 | 1312 | ||
| 1313 | /* parse expression terminated by given argument, return ptr | 1313 | /* parse expression terminated by given argument, return ptr |
| @@ -1430,12 +1430,12 @@ static node *parse_expr(uint32_t term_tc) | |||
| 1430 | debug_printf_parse("%s: TC_FUNCTION\n", __func__); | 1430 | debug_printf_parse("%s: TC_FUNCTION\n", __func__); |
| 1431 | cn->info = OC_FUNC; | 1431 | cn->info = OC_FUNC; |
| 1432 | cn->r.f = newfunc(t_string); | 1432 | cn->r.f = newfunc(t_string); |
| 1433 | cn->l.n = condition(); | 1433 | cn->l.n = parse_lrparen_list(); |
| 1434 | break; | 1434 | break; |
| 1435 | 1435 | ||
| 1436 | case TC_SEQSTART: | 1436 | case TC_LPAREN: |
| 1437 | debug_printf_parse("%s: TC_SEQSTART\n", __func__); | 1437 | debug_printf_parse("%s: TC_LPAREN\n", __func__); |
| 1438 | cn = vn->r.n = parse_expr(TC_SEQTERM); | 1438 | cn = vn->r.n = parse_expr(TC_RPAREN); |
| 1439 | if (!cn) | 1439 | if (!cn) |
| 1440 | syntax_error("Empty sequence"); | 1440 | syntax_error("Empty sequence"); |
| 1441 | cn->a.n = vn; | 1441 | cn->a.n = vn; |
| @@ -1449,21 +1449,21 @@ static node *parse_expr(uint32_t term_tc) | |||
| 1449 | 1449 | ||
| 1450 | case TC_BUILTIN: | 1450 | case TC_BUILTIN: |
| 1451 | debug_printf_parse("%s: TC_BUILTIN\n", __func__); | 1451 | debug_printf_parse("%s: TC_BUILTIN\n", __func__); |
| 1452 | cn->l.n = condition(); | 1452 | cn->l.n = parse_lrparen_list(); |
| 1453 | break; | 1453 | break; |
| 1454 | 1454 | ||
| 1455 | case TC_LENGTH: | 1455 | case TC_LENGTH: |
| 1456 | debug_printf_parse("%s: TC_LENGTH\n", __func__); | 1456 | debug_printf_parse("%s: TC_LENGTH\n", __func__); |
| 1457 | next_token(TC_SEQSTART /* length(...) */ | 1457 | next_token(TC_LPAREN /* length(...) */ |
| 1458 | | TS_OPTERM /* length; (or newline)*/ | 1458 | | TS_OPTERM /* length; (or newline)*/ |
| 1459 | | TC_GRPTERM /* length } */ | 1459 | | TC_GRPTERM /* length } */ |
| 1460 | | TC_BINOPX /* length <op> NUM */ | 1460 | | TC_BINOPX /* length <op> NUM */ |
| 1461 | | TC_COMMA /* print length, 1 */ | 1461 | | TC_COMMA /* print length, 1 */ |
| 1462 | ); | 1462 | ); |
| 1463 | rollback_token(); | 1463 | rollback_token(); |
| 1464 | if (t_tclass & TC_SEQSTART) { | 1464 | if (t_tclass & TC_LPAREN) { |
| 1465 | /* It was a "(" token. Handle just like TC_BUILTIN */ | 1465 | /* It was a "(" token. Handle just like TC_BUILTIN */ |
| 1466 | cn->l.n = condition(); | 1466 | cn->l.n = parse_lrparen_list(); |
| 1467 | } | 1467 | } |
| 1468 | break; | 1468 | break; |
| 1469 | } | 1469 | } |
| @@ -1562,7 +1562,7 @@ static void chain_group(void) | |||
| 1562 | case ST_IF: | 1562 | case ST_IF: |
| 1563 | debug_printf_parse("%s: ST_IF\n", __func__); | 1563 | debug_printf_parse("%s: ST_IF\n", __func__); |
| 1564 | n = chain_node(OC_BR | Vx); | 1564 | n = chain_node(OC_BR | Vx); |
| 1565 | n->l.n = condition(); | 1565 | n->l.n = parse_lrparen_list(); |
| 1566 | chain_group(); | 1566 | chain_group(); |
| 1567 | n2 = chain_node(OC_EXEC); | 1567 | n2 = chain_node(OC_EXEC); |
| 1568 | n->r.n = seq->last; | 1568 | n->r.n = seq->last; |
| @@ -1576,7 +1576,7 @@ static void chain_group(void) | |||
| 1576 | 1576 | ||
| 1577 | case ST_WHILE: | 1577 | case ST_WHILE: |
| 1578 | debug_printf_parse("%s: ST_WHILE\n", __func__); | 1578 | debug_printf_parse("%s: ST_WHILE\n", __func__); |
| 1579 | n2 = condition(); | 1579 | n2 = parse_lrparen_list(); |
| 1580 | n = chain_loop(NULL); | 1580 | n = chain_loop(NULL); |
| 1581 | n->l.n = n2; | 1581 | n->l.n = n2; |
| 1582 | break; | 1582 | break; |
| @@ -1587,14 +1587,14 @@ static void chain_group(void) | |||
| 1587 | n = chain_loop(NULL); | 1587 | n = chain_loop(NULL); |
| 1588 | n2->a.n = n->a.n; | 1588 | n2->a.n = n->a.n; |
| 1589 | next_token(TC_WHILE); | 1589 | next_token(TC_WHILE); |
| 1590 | n->l.n = condition(); | 1590 | n->l.n = parse_lrparen_list(); |
| 1591 | break; | 1591 | break; |
| 1592 | 1592 | ||
| 1593 | case ST_FOR: | 1593 | case ST_FOR: |
| 1594 | debug_printf_parse("%s: ST_FOR\n", __func__); | 1594 | debug_printf_parse("%s: ST_FOR\n", __func__); |
| 1595 | next_token(TC_SEQSTART); | 1595 | next_token(TC_LPAREN); |
| 1596 | n2 = parse_expr(TC_SEMICOL | TC_SEQTERM); | 1596 | n2 = parse_expr(TC_SEMICOL | TC_RPAREN); |
| 1597 | if (t_tclass & TC_SEQTERM) { /* for-in */ | 1597 | if (t_tclass & TC_RPAREN) { /* for-in */ |
| 1598 | if (!n2 || (n2->info & OPCLSMASK) != OC_IN) | 1598 | if (!n2 || (n2->info & OPCLSMASK) != OC_IN) |
| 1599 | syntax_error(EMSG_UNEXP_TOKEN); | 1599 | syntax_error(EMSG_UNEXP_TOKEN); |
| 1600 | n = chain_node(OC_WALKINIT | VV); | 1600 | n = chain_node(OC_WALKINIT | VV); |
| @@ -1607,7 +1607,7 @@ static void chain_group(void) | |||
| 1607 | n = chain_node(OC_EXEC | Vx); | 1607 | n = chain_node(OC_EXEC | Vx); |
| 1608 | n->l.n = n2; | 1608 | n->l.n = n2; |
| 1609 | n2 = parse_expr(TC_SEMICOL); | 1609 | n2 = parse_expr(TC_SEMICOL); |
| 1610 | n3 = parse_expr(TC_SEQTERM); | 1610 | n3 = parse_expr(TC_RPAREN); |
| 1611 | n = chain_loop(n3); | 1611 | n = chain_loop(n3); |
| 1612 | n->l.n = n2; | 1612 | n->l.n = n2; |
| 1613 | if (!n2) | 1613 | if (!n2) |
| @@ -1686,13 +1686,13 @@ static void parse_program(char *p) | |||
| 1686 | f->body.first = NULL; | 1686 | f->body.first = NULL; |
| 1687 | f->nargs = 0; | 1687 | f->nargs = 0; |
| 1688 | /* Match func arg list: a comma sep list of >= 0 args, and a close paren */ | 1688 | /* Match func arg list: a comma sep list of >= 0 args, and a close paren */ |
| 1689 | while (next_token(TC_VARIABLE | TC_SEQTERM | TC_COMMA)) { | 1689 | while (next_token(TC_VARIABLE | TC_RPAREN | TC_COMMA)) { |
| 1690 | /* Either an empty arg list, or trailing comma from prev iter | 1690 | /* Either an empty arg list, or trailing comma from prev iter |
| 1691 | * must be followed by an arg */ | 1691 | * must be followed by an arg */ |
| 1692 | if (f->nargs == 0 && t_tclass == TC_SEQTERM) | 1692 | if (f->nargs == 0 && t_tclass == TC_RPAREN) |
| 1693 | break; | 1693 | break; |
| 1694 | 1694 | ||
| 1695 | /* TC_SEQSTART/TC_COMMA must be followed by TC_VARIABLE */ | 1695 | /* TC_LPAREN/TC_COMMA must be followed by TC_VARIABLE */ |
| 1696 | if (t_tclass != TC_VARIABLE) | 1696 | if (t_tclass != TC_VARIABLE) |
| 1697 | syntax_error(EMSG_UNEXP_TOKEN); | 1697 | syntax_error(EMSG_UNEXP_TOKEN); |
| 1698 | 1698 | ||
| @@ -1700,7 +1700,7 @@ static void parse_program(char *p) | |||
| 1700 | v->x.aidx = f->nargs++; | 1700 | v->x.aidx = f->nargs++; |
| 1701 | 1701 | ||
| 1702 | /* Arg followed either by end of arg list or 1 comma */ | 1702 | /* Arg followed either by end of arg list or 1 comma */ |
| 1703 | if (next_token(TC_COMMA | TC_SEQTERM) & TC_SEQTERM) | 1703 | if (next_token(TC_COMMA | TC_RPAREN) & TC_RPAREN) |
| 1704 | break; | 1704 | break; |
| 1705 | //Impossible: next_token() above would error out and die | 1705 | //Impossible: next_token() above would error out and die |
| 1706 | // if (t_tclass != TC_COMMA) | 1706 | // if (t_tclass != TC_COMMA) |
