diff options
Diffstat (limited to 'editors/awk.c')
-rw-r--r-- | editors/awk.c | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/editors/awk.c b/editors/awk.c index 86cd9a289..dbb26068d 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -275,18 +275,21 @@ typedef struct tsplitter_s { | |||
275 | | TC_STRING | TC_NUMBER | TC_UOPPOST) | 275 | | TC_STRING | TC_NUMBER | TC_UOPPOST) |
276 | #define TC_CONCAT2 (TC_OPERAND | TC_UOPPRE) | 276 | #define TC_CONCAT2 (TC_OPERAND | TC_UOPPRE) |
277 | 277 | ||
278 | #define OF_RES1 0x010000 | 278 | #define OF_RES1 0x010000 |
279 | #define OF_RES2 0x020000 | 279 | #define OF_RES2 0x020000 |
280 | #define OF_STR1 0x040000 | 280 | #define OF_STR1 0x040000 |
281 | #define OF_STR2 0x080000 | 281 | #define OF_STR2 0x080000 |
282 | #define OF_NUM1 0x100000 | 282 | #define OF_NUM1 0x100000 |
283 | #define OF_CHECKED 0x200000 | 283 | #define OF_CHECKED 0x200000 |
284 | #define OF_REQUIRED 0x400000 | ||
285 | |||
284 | 286 | ||
285 | /* combined operator flags */ | 287 | /* combined operator flags */ |
286 | #define xx 0 | 288 | #define xx 0 |
287 | #define xV OF_RES2 | 289 | #define xV OF_RES2 |
288 | #define xS (OF_RES2 | OF_STR2) | 290 | #define xS (OF_RES2 | OF_STR2) |
289 | #define Vx OF_RES1 | 291 | #define Vx OF_RES1 |
292 | #define Rx (OF_RES1 | OF_NUM1 | OF_REQUIRED) | ||
290 | #define VV (OF_RES1 | OF_RES2) | 293 | #define VV (OF_RES1 | OF_RES2) |
291 | #define Nx (OF_RES1 | OF_NUM1) | 294 | #define Nx (OF_RES1 | OF_NUM1) |
292 | #define NV (OF_RES1 | OF_NUM1 | OF_RES2) | 295 | #define NV (OF_RES1 | OF_NUM1 | OF_RES2) |
@@ -425,7 +428,7 @@ static const uint32_t tokeninfo[] = { | |||
425 | 0, | 428 | 0, |
426 | 0, /* \n */ | 429 | 0, /* \n */ |
427 | ST_IF, ST_DO, ST_FOR, OC_BREAK, | 430 | ST_IF, ST_DO, ST_FOR, OC_BREAK, |
428 | OC_CONTINUE, OC_DELETE|Vx, OC_PRINT, | 431 | OC_CONTINUE, OC_DELETE|Rx, OC_PRINT, |
429 | OC_PRINTF, OC_NEXT, OC_NEXTFILE, | 432 | OC_PRINTF, OC_NEXT, OC_NEXTFILE, |
430 | OC_RETURN|Vx, OC_EXIT|Nx, | 433 | OC_RETURN|Vx, OC_EXIT|Nx, |
431 | ST_WHILE, | 434 | ST_WHILE, |
@@ -593,7 +596,7 @@ static const char EMSG_UNEXP_EOS[] ALIGN1 = "Unexpected end of string"; | |||
593 | static const char EMSG_UNEXP_TOKEN[] ALIGN1 = "Unexpected token"; | 596 | static const char EMSG_UNEXP_TOKEN[] ALIGN1 = "Unexpected token"; |
594 | static const char EMSG_DIV_BY_ZERO[] ALIGN1 = "Division by zero"; | 597 | static const char EMSG_DIV_BY_ZERO[] ALIGN1 = "Division by zero"; |
595 | static const char EMSG_INV_FMT[] ALIGN1 = "Invalid format specifier"; | 598 | static const char EMSG_INV_FMT[] ALIGN1 = "Invalid format specifier"; |
596 | static const char EMSG_TOO_FEW_ARGS[] ALIGN1 = "Too few arguments for builtin"; | 599 | static const char EMSG_TOO_FEW_ARGS[] ALIGN1 = "Too few arguments"; |
597 | static const char EMSG_NOT_ARRAY[] ALIGN1 = "Not an array"; | 600 | static const char EMSG_NOT_ARRAY[] ALIGN1 = "Not an array"; |
598 | static const char EMSG_POSSIBLE_ERROR[] ALIGN1 = "Possible syntax error"; | 601 | static const char EMSG_POSSIBLE_ERROR[] ALIGN1 = "Possible syntax error"; |
599 | static const char EMSG_UNDEF_FUNC[] ALIGN1 = "Call to undefined function"; | 602 | static const char EMSG_UNDEF_FUNC[] ALIGN1 = "Call to undefined function"; |
@@ -1269,7 +1272,7 @@ static node *parse_expr(uint32_t iexp) | |||
1269 | debug_printf_parse("%s(%x)\n", __func__, iexp); | 1272 | debug_printf_parse("%s(%x)\n", __func__, iexp); |
1270 | 1273 | ||
1271 | sn.info = PRIMASK; | 1274 | sn.info = PRIMASK; |
1272 | sn.r.n = glptr = NULL; | 1275 | sn.r.n = sn.a.n = glptr = NULL; |
1273 | xtc = TC_OPERAND | TC_UOPPRE | TC_REGEXP | iexp; | 1276 | xtc = TC_OPERAND | TC_UOPPRE | TC_REGEXP | iexp; |
1274 | 1277 | ||
1275 | while (!((tc = next_token(xtc)) & iexp)) { | 1278 | while (!((tc = next_token(xtc)) & iexp)) { |
@@ -1291,6 +1294,7 @@ static node *parse_expr(uint32_t iexp) | |||
1291 | || ((t_info == vn->info) && ((t_info & OPCLSMASK) == OC_COLON)) | 1294 | || ((t_info == vn->info) && ((t_info & OPCLSMASK) == OC_COLON)) |
1292 | ) { | 1295 | ) { |
1293 | vn = vn->a.n; | 1296 | vn = vn->a.n; |
1297 | if (!vn->a.n) syntax_error(EMSG_UNEXP_TOKEN); | ||
1294 | } | 1298 | } |
1295 | if ((t_info & OPCLSMASK) == OC_TERNARY) | 1299 | if ((t_info & OPCLSMASK) == OC_TERNARY) |
1296 | t_info += P(6); | 1300 | t_info += P(6); |
@@ -1429,7 +1433,11 @@ static void chain_expr(uint32_t info) | |||
1429 | node *n; | 1433 | node *n; |
1430 | 1434 | ||
1431 | n = chain_node(info); | 1435 | n = chain_node(info); |
1436 | |||
1432 | n->l.n = parse_expr(TC_OPTERM | TC_GRPTERM); | 1437 | n->l.n = parse_expr(TC_OPTERM | TC_GRPTERM); |
1438 | if ((info & OF_REQUIRED) && !n->l.n) | ||
1439 | syntax_error(EMSG_TOO_FEW_ARGS); | ||
1440 | |||
1433 | if (t_tclass & TC_GRPTERM) | 1441 | if (t_tclass & TC_GRPTERM) |
1434 | rollback_token(); | 1442 | rollback_token(); |
1435 | } | 1443 | } |
@@ -1609,12 +1617,25 @@ static void parse_program(char *p) | |||
1609 | f = newfunc(t_string); | 1617 | f = newfunc(t_string); |
1610 | f->body.first = NULL; | 1618 | f->body.first = NULL; |
1611 | f->nargs = 0; | 1619 | f->nargs = 0; |
1612 | while (next_token(TC_VARIABLE | TC_SEQTERM) & TC_VARIABLE) { | 1620 | /* Match func arg list: a comma sep list of >= 0 args, and a close paren */ |
1621 | while (next_token(TC_VARIABLE | TC_SEQTERM | TC_COMMA)) { | ||
1622 | /* Either an empty arg list, or trailing comma from prev iter | ||
1623 | * must be followed by an arg */ | ||
1624 | if (f->nargs == 0 && t_tclass == TC_SEQTERM) | ||
1625 | break; | ||
1626 | |||
1627 | /* TC_SEQSTART/TC_COMMA must be followed by TC_VARIABLE */ | ||
1628 | if (t_tclass != TC_VARIABLE) | ||
1629 | syntax_error(EMSG_UNEXP_TOKEN); | ||
1630 | |||
1613 | v = findvar(ahash, t_string); | 1631 | v = findvar(ahash, t_string); |
1614 | v->x.aidx = f->nargs++; | 1632 | v->x.aidx = f->nargs++; |
1615 | 1633 | ||
1634 | /* Arg followed either by end of arg list or 1 comma */ | ||
1616 | if (next_token(TC_COMMA | TC_SEQTERM) & TC_SEQTERM) | 1635 | if (next_token(TC_COMMA | TC_SEQTERM) & TC_SEQTERM) |
1617 | break; | 1636 | break; |
1637 | if (t_tclass != TC_COMMA) | ||
1638 | syntax_error(EMSG_UNEXP_TOKEN); | ||
1618 | } | 1639 | } |
1619 | seq = &f->body; | 1640 | seq = &f->body; |
1620 | chain_group(); | 1641 | chain_group(); |