diff options
Diffstat (limited to 'editors/awk.c')
-rw-r--r-- | editors/awk.c | 94 |
1 files changed, 76 insertions, 18 deletions
diff --git a/editors/awk.c b/editors/awk.c index 7685546e5..71abca215 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -25,6 +25,7 @@ | |||
25 | * to perform debug printfs to stderr: */ | 25 | * to perform debug printfs to stderr: */ |
26 | #define debug_printf_walker(...) do {} while (0) | 26 | #define debug_printf_walker(...) do {} while (0) |
27 | #define debug_printf_eval(...) do {} while (0) | 27 | #define debug_printf_eval(...) do {} while (0) |
28 | #define debug_printf_parse(...) do {} while (0) | ||
28 | 29 | ||
29 | #ifndef debug_printf_walker | 30 | #ifndef debug_printf_walker |
30 | # define debug_printf_walker(...) (fprintf(stderr, __VA_ARGS__)) | 31 | # define debug_printf_walker(...) (fprintf(stderr, __VA_ARGS__)) |
@@ -32,6 +33,9 @@ | |||
32 | #ifndef debug_printf_eval | 33 | #ifndef debug_printf_eval |
33 | # define debug_printf_eval(...) (fprintf(stderr, __VA_ARGS__)) | 34 | # define debug_printf_eval(...) (fprintf(stderr, __VA_ARGS__)) |
34 | #endif | 35 | #endif |
36 | #ifndef debug_printf_parse | ||
37 | # define debug_printf_parse(...) (fprintf(stderr, __VA_ARGS__)) | ||
38 | #endif | ||
35 | 39 | ||
36 | 40 | ||
37 | 41 | ||
@@ -238,6 +242,9 @@ typedef struct tsplitter_s { | |||
238 | * For builtins it has different meaning: n n s3 s2 s1 v3 v2 v1, | 242 | * For builtins it has different meaning: n n s3 s2 s1 v3 v2 v1, |
239 | * n - min. number of args, vN - resolve Nth arg to var, sN - resolve to string | 243 | * n - min. number of args, vN - resolve Nth arg to var, sN - resolve to string |
240 | */ | 244 | */ |
245 | #undef P | ||
246 | #undef PRIMASK | ||
247 | #undef PRIMASK2 | ||
241 | #define P(x) (x << 24) | 248 | #define P(x) (x << 24) |
242 | #define PRIMASK 0x7F000000 | 249 | #define PRIMASK 0x7F000000 |
243 | #define PRIMASK2 0x7E000000 | 250 | #define PRIMASK2 0x7E000000 |
@@ -432,13 +439,13 @@ struct globals { | |||
432 | smallint nextrec; | 439 | smallint nextrec; |
433 | smallint nextfile; | 440 | smallint nextfile; |
434 | smallint is_f0_split; | 441 | smallint is_f0_split; |
442 | smallint t_rollback; | ||
435 | }; | 443 | }; |
436 | struct globals2 { | 444 | struct globals2 { |
437 | uint32_t t_info; /* often used */ | 445 | uint32_t t_info; /* often used */ |
438 | uint32_t t_tclass; | 446 | uint32_t t_tclass; |
439 | char *t_string; | 447 | char *t_string; |
440 | int t_lineno; | 448 | int t_lineno; |
441 | int t_rollback; | ||
442 | 449 | ||
443 | var *intvar[NUM_INTERNAL_VARS]; /* often used */ | 450 | var *intvar[NUM_INTERNAL_VARS]; /* often used */ |
444 | 451 | ||
@@ -496,11 +503,11 @@ struct globals2 { | |||
496 | #define nextrec (G1.nextrec ) | 503 | #define nextrec (G1.nextrec ) |
497 | #define nextfile (G1.nextfile ) | 504 | #define nextfile (G1.nextfile ) |
498 | #define is_f0_split (G1.is_f0_split ) | 505 | #define is_f0_split (G1.is_f0_split ) |
506 | #define t_rollback (G1.t_rollback ) | ||
499 | #define t_info (G.t_info ) | 507 | #define t_info (G.t_info ) |
500 | #define t_tclass (G.t_tclass ) | 508 | #define t_tclass (G.t_tclass ) |
501 | #define t_string (G.t_string ) | 509 | #define t_string (G.t_string ) |
502 | #define t_lineno (G.t_lineno ) | 510 | #define t_lineno (G.t_lineno ) |
503 | #define t_rollback (G.t_rollback ) | ||
504 | #define intvar (G.intvar ) | 511 | #define intvar (G.intvar ) |
505 | #define fsplitter (G.fsplitter ) | 512 | #define fsplitter (G.fsplitter ) |
506 | #define rsplitter (G.rsplitter ) | 513 | #define rsplitter (G.rsplitter ) |
@@ -1008,6 +1015,7 @@ static uint32_t next_token(uint32_t expected) | |||
1008 | 1015 | ||
1009 | if (*p == '\0') { | 1016 | if (*p == '\0') { |
1010 | tc = TC_EOF; | 1017 | tc = TC_EOF; |
1018 | debug_printf_parse("%s: token found: TC_EOF\n", __func__); | ||
1011 | 1019 | ||
1012 | } else if (*p == '\"') { | 1020 | } else if (*p == '\"') { |
1013 | /* it's a string */ | 1021 | /* it's a string */ |
@@ -1023,6 +1031,7 @@ static uint32_t next_token(uint32_t expected) | |||
1023 | p++; | 1031 | p++; |
1024 | *s = '\0'; | 1032 | *s = '\0'; |
1025 | tc = TC_STRING; | 1033 | tc = TC_STRING; |
1034 | debug_printf_parse("%s: token found:'%s' TC_STRING\n", __func__, t_string); | ||
1026 | 1035 | ||
1027 | } else if ((expected & TC_REGEXP) && *p == '/') { | 1036 | } else if ((expected & TC_REGEXP) && *p == '/') { |
1028 | /* it's regexp */ | 1037 | /* it's regexp */ |
@@ -1045,6 +1054,7 @@ static uint32_t next_token(uint32_t expected) | |||
1045 | p++; | 1054 | p++; |
1046 | *s = '\0'; | 1055 | *s = '\0'; |
1047 | tc = TC_REGEXP; | 1056 | tc = TC_REGEXP; |
1057 | debug_printf_parse("%s: token found:'%s' TC_REGEXP\n", __func__, t_string); | ||
1048 | 1058 | ||
1049 | } else if (*p == '.' || isdigit(*p)) { | 1059 | } else if (*p == '.' || isdigit(*p)) { |
1050 | /* it's a number */ | 1060 | /* it's a number */ |
@@ -1054,6 +1064,7 @@ static uint32_t next_token(uint32_t expected) | |||
1054 | if (*p == '.') | 1064 | if (*p == '.') |
1055 | syntax_error(EMSG_UNEXP_TOKEN); | 1065 | syntax_error(EMSG_UNEXP_TOKEN); |
1056 | tc = TC_NUMBER; | 1066 | tc = TC_NUMBER; |
1067 | debug_printf_parse("%s: token found:%f TC_NUMBER\n", __func__, t_double); | ||
1057 | 1068 | ||
1058 | } else { | 1069 | } else { |
1059 | /* search for something known */ | 1070 | /* search for something known */ |
@@ -1076,6 +1087,7 @@ static uint32_t next_token(uint32_t expected) | |||
1076 | ) { | 1087 | ) { |
1077 | /* then this is what we are looking for */ | 1088 | /* then this is what we are looking for */ |
1078 | t_info = *ti; | 1089 | t_info = *ti; |
1090 | debug_printf_parse("%s: token found:'%.*s' t_info:%x\n", __func__, l, p, t_info); | ||
1079 | p += l; | 1091 | p += l; |
1080 | goto token_found; | 1092 | goto token_found; |
1081 | } | 1093 | } |
@@ -1099,14 +1111,17 @@ static uint32_t next_token(uint32_t expected) | |||
1099 | p = skip_spaces(p); | 1111 | p = skip_spaces(p); |
1100 | if (*p == '(') { | 1112 | if (*p == '(') { |
1101 | tc = TC_FUNCTION; | 1113 | tc = TC_FUNCTION; |
1114 | debug_printf_parse("%s: token found:'%s' TC_FUNCTION\n", __func__, t_string); | ||
1102 | } else { | 1115 | } else { |
1103 | if (*p == '[') { | 1116 | if (*p == '[') { |
1104 | p++; | 1117 | p++; |
1105 | tc = TC_ARRAY; | 1118 | tc = TC_ARRAY; |
1106 | } | 1119 | debug_printf_parse("%s: token found:'%s' TC_ARRAY\n", __func__, t_string); |
1120 | } else | ||
1121 | debug_printf_parse("%s: token found:'%s' TC_VARIABLE\n", __func__, t_string); | ||
1107 | } | 1122 | } |
1108 | token_found: ; | ||
1109 | } | 1123 | } |
1124 | token_found: | ||
1110 | g_pos = p; | 1125 | g_pos = p; |
1111 | 1126 | ||
1112 | /* skipping newlines in some cases */ | 1127 | /* skipping newlines in some cases */ |
@@ -1178,6 +1193,8 @@ static node *parse_expr(uint32_t iexp) | |||
1178 | uint32_t tc, xtc; | 1193 | uint32_t tc, xtc; |
1179 | var *v; | 1194 | var *v; |
1180 | 1195 | ||
1196 | debug_printf_parse("%s(%x)\n", __func__, iexp); | ||
1197 | |||
1181 | sn.info = PRIMASK; | 1198 | sn.info = PRIMASK; |
1182 | sn.r.n = glptr = NULL; | 1199 | sn.r.n = glptr = NULL; |
1183 | xtc = TC_OPERAND | TC_UOPPRE | TC_REGEXP | iexp; | 1200 | xtc = TC_OPERAND | TC_UOPPRE | TC_REGEXP | iexp; |
@@ -1186,12 +1203,14 @@ static node *parse_expr(uint32_t iexp) | |||
1186 | 1203 | ||
1187 | if (glptr && (t_info == (OC_COMPARE | VV | P(39) | 2))) { | 1204 | if (glptr && (t_info == (OC_COMPARE | VV | P(39) | 2))) { |
1188 | /* input redirection (<) attached to glptr node */ | 1205 | /* input redirection (<) attached to glptr node */ |
1206 | debug_printf_parse("%s: input redir\n", __func__); | ||
1189 | cn = glptr->l.n = new_node(OC_CONCAT | SS | P(37)); | 1207 | cn = glptr->l.n = new_node(OC_CONCAT | SS | P(37)); |
1190 | cn->a.n = glptr; | 1208 | cn->a.n = glptr; |
1191 | xtc = TC_OPERAND | TC_UOPPRE; | 1209 | xtc = TC_OPERAND | TC_UOPPRE; |
1192 | glptr = NULL; | 1210 | glptr = NULL; |
1193 | 1211 | ||
1194 | } else if (tc & (TC_BINOP | TC_UOPPOST)) { | 1212 | } else if (tc & (TC_BINOP | TC_UOPPOST)) { |
1213 | debug_printf_parse("%s: TC_BINOP | TC_UOPPOST\n", __func__); | ||
1195 | /* for binary and postfix-unary operators, jump back over | 1214 | /* for binary and postfix-unary operators, jump back over |
1196 | * previous operators with higher priority */ | 1215 | * previous operators with higher priority */ |
1197 | vn = cn; | 1216 | vn = cn; |
@@ -1221,6 +1240,7 @@ static node *parse_expr(uint32_t iexp) | |||
1221 | vn->a.n = cn; | 1240 | vn->a.n = cn; |
1222 | 1241 | ||
1223 | } else { | 1242 | } else { |
1243 | debug_printf_parse("%s: other\n", __func__); | ||
1224 | /* for operands and prefix-unary operators, attach them | 1244 | /* for operands and prefix-unary operators, attach them |
1225 | * to last node */ | 1245 | * to last node */ |
1226 | vn = cn; | 1246 | vn = cn; |
@@ -1228,12 +1248,14 @@ static node *parse_expr(uint32_t iexp) | |||
1228 | cn->a.n = vn; | 1248 | cn->a.n = vn; |
1229 | xtc = TC_OPERAND | TC_UOPPRE | TC_REGEXP; | 1249 | xtc = TC_OPERAND | TC_UOPPRE | TC_REGEXP; |
1230 | if (tc & (TC_OPERAND | TC_REGEXP)) { | 1250 | if (tc & (TC_OPERAND | TC_REGEXP)) { |
1251 | debug_printf_parse("%s: TC_OPERAND | TC_REGEXP\n", __func__); | ||
1231 | xtc = TC_UOPPRE | TC_UOPPOST | TC_BINOP | TC_OPERAND | iexp; | 1252 | xtc = TC_UOPPRE | TC_UOPPOST | TC_BINOP | TC_OPERAND | iexp; |
1232 | /* one should be very careful with switch on tclass - | 1253 | /* one should be very careful with switch on tclass - |
1233 | * only simple tclasses should be used! */ | 1254 | * only simple tclasses should be used! */ |
1234 | switch (tc) { | 1255 | switch (tc) { |
1235 | case TC_VARIABLE: | 1256 | case TC_VARIABLE: |
1236 | case TC_ARRAY: | 1257 | case TC_ARRAY: |
1258 | debug_printf_parse("%s: TC_VARIABLE | TC_ARRAY\n", __func__); | ||
1237 | cn->info = OC_VAR; | 1259 | cn->info = OC_VAR; |
1238 | v = hash_search(ahash, t_string); | 1260 | v = hash_search(ahash, t_string); |
1239 | if (v != NULL) { | 1261 | if (v != NULL) { |
@@ -1250,6 +1272,7 @@ static node *parse_expr(uint32_t iexp) | |||
1250 | 1272 | ||
1251 | case TC_NUMBER: | 1273 | case TC_NUMBER: |
1252 | case TC_STRING: | 1274 | case TC_STRING: |
1275 | debug_printf_parse("%s: TC_NUMBER | TC_STRING\n", __func__); | ||
1253 | cn->info = OC_VAR; | 1276 | cn->info = OC_VAR; |
1254 | v = cn->l.v = xzalloc(sizeof(var)); | 1277 | v = cn->l.v = xzalloc(sizeof(var)); |
1255 | if (tc & TC_NUMBER) | 1278 | if (tc & TC_NUMBER) |
@@ -1259,32 +1282,41 @@ static node *parse_expr(uint32_t iexp) | |||
1259 | break; | 1282 | break; |
1260 | 1283 | ||
1261 | case TC_REGEXP: | 1284 | case TC_REGEXP: |
1285 | debug_printf_parse("%s: TC_REGEXP\n", __func__); | ||
1262 | mk_re_node(t_string, cn, xzalloc(sizeof(regex_t)*2)); | 1286 | mk_re_node(t_string, cn, xzalloc(sizeof(regex_t)*2)); |
1263 | break; | 1287 | break; |
1264 | 1288 | ||
1265 | case TC_FUNCTION: | 1289 | case TC_FUNCTION: |
1290 | debug_printf_parse("%s: TC_FUNCTION\n", __func__); | ||
1266 | cn->info = OC_FUNC; | 1291 | cn->info = OC_FUNC; |
1267 | cn->r.f = newfunc(t_string); | 1292 | cn->r.f = newfunc(t_string); |
1268 | cn->l.n = condition(); | 1293 | cn->l.n = condition(); |
1269 | break; | 1294 | break; |
1270 | 1295 | ||
1271 | case TC_SEQSTART: | 1296 | case TC_SEQSTART: |
1297 | debug_printf_parse("%s: TC_SEQSTART\n", __func__); | ||
1272 | cn = vn->r.n = parse_expr(TC_SEQTERM); | 1298 | cn = vn->r.n = parse_expr(TC_SEQTERM); |
1299 | if (!cn) | ||
1300 | syntax_error("Empty sequence"); | ||
1273 | cn->a.n = vn; | 1301 | cn->a.n = vn; |
1274 | break; | 1302 | break; |
1275 | 1303 | ||
1276 | case TC_GETLINE: | 1304 | case TC_GETLINE: |
1305 | debug_printf_parse("%s: TC_GETLINE\n", __func__); | ||
1277 | glptr = cn; | 1306 | glptr = cn; |
1278 | xtc = TC_OPERAND | TC_UOPPRE | TC_BINOP | iexp; | 1307 | xtc = TC_OPERAND | TC_UOPPRE | TC_BINOP | iexp; |
1279 | break; | 1308 | break; |
1280 | 1309 | ||
1281 | case TC_BUILTIN: | 1310 | case TC_BUILTIN: |
1311 | debug_printf_parse("%s: TC_BUILTIN\n", __func__); | ||
1282 | cn->l.n = condition(); | 1312 | cn->l.n = condition(); |
1283 | break; | 1313 | break; |
1284 | } | 1314 | } |
1285 | } | 1315 | } |
1286 | } | 1316 | } |
1287 | } | 1317 | } |
1318 | |||
1319 | debug_printf_parse("%s() returns %p\n", __func__, sn.r.n); | ||
1288 | return sn.r.n; | 1320 | return sn.r.n; |
1289 | } | 1321 | } |
1290 | 1322 | ||
@@ -1353,18 +1385,25 @@ static void chain_group(void) | |||
1353 | } while (c & TC_NEWLINE); | 1385 | } while (c & TC_NEWLINE); |
1354 | 1386 | ||
1355 | if (c & TC_GRPSTART) { | 1387 | if (c & TC_GRPSTART) { |
1388 | debug_printf_parse("%s: TC_GRPSTART\n", __func__); | ||
1356 | while (next_token(TC_GRPSEQ | TC_GRPTERM) != TC_GRPTERM) { | 1389 | while (next_token(TC_GRPSEQ | TC_GRPTERM) != TC_GRPTERM) { |
1390 | debug_printf_parse("%s: !TC_GRPTERM\n", __func__); | ||
1357 | if (t_tclass & TC_NEWLINE) | 1391 | if (t_tclass & TC_NEWLINE) |
1358 | continue; | 1392 | continue; |
1359 | rollback_token(); | 1393 | rollback_token(); |
1360 | chain_group(); | 1394 | chain_group(); |
1361 | } | 1395 | } |
1396 | debug_printf_parse("%s: TC_GRPTERM\n", __func__); | ||
1362 | } else if (c & (TC_OPSEQ | TC_OPTERM)) { | 1397 | } else if (c & (TC_OPSEQ | TC_OPTERM)) { |
1398 | debug_printf_parse("%s: TC_OPSEQ | TC_OPTERM\n", __func__); | ||
1363 | rollback_token(); | 1399 | rollback_token(); |
1364 | chain_expr(OC_EXEC | Vx); | 1400 | chain_expr(OC_EXEC | Vx); |
1365 | } else { /* TC_STATEMNT */ | 1401 | } else { |
1402 | /* TC_STATEMNT */ | ||
1403 | debug_printf_parse("%s: TC_STATEMNT(?)\n", __func__); | ||
1366 | switch (t_info & OPCLSMASK) { | 1404 | switch (t_info & OPCLSMASK) { |
1367 | case ST_IF: | 1405 | case ST_IF: |
1406 | debug_printf_parse("%s: ST_IF\n", __func__); | ||
1368 | n = chain_node(OC_BR | Vx); | 1407 | n = chain_node(OC_BR | Vx); |
1369 | n->l.n = condition(); | 1408 | n->l.n = condition(); |
1370 | chain_group(); | 1409 | chain_group(); |
@@ -1379,12 +1418,14 @@ static void chain_group(void) | |||
1379 | break; | 1418 | break; |
1380 | 1419 | ||
1381 | case ST_WHILE: | 1420 | case ST_WHILE: |
1421 | debug_printf_parse("%s: ST_WHILE\n", __func__); | ||
1382 | n2 = condition(); | 1422 | n2 = condition(); |
1383 | n = chain_loop(NULL); | 1423 | n = chain_loop(NULL); |
1384 | n->l.n = n2; | 1424 | n->l.n = n2; |
1385 | break; | 1425 | break; |
1386 | 1426 | ||
1387 | case ST_DO: | 1427 | case ST_DO: |
1428 | debug_printf_parse("%s: ST_DO\n", __func__); | ||
1388 | n2 = chain_node(OC_EXEC); | 1429 | n2 = chain_node(OC_EXEC); |
1389 | n = chain_loop(NULL); | 1430 | n = chain_loop(NULL); |
1390 | n2->a.n = n->a.n; | 1431 | n2->a.n = n->a.n; |
@@ -1393,6 +1434,7 @@ static void chain_group(void) | |||
1393 | break; | 1434 | break; |
1394 | 1435 | ||
1395 | case ST_FOR: | 1436 | case ST_FOR: |
1437 | debug_printf_parse("%s: ST_FOR\n", __func__); | ||
1396 | next_token(TC_SEQSTART); | 1438 | next_token(TC_SEQSTART); |
1397 | n2 = parse_expr(TC_SEMICOL | TC_SEQTERM); | 1439 | n2 = parse_expr(TC_SEMICOL | TC_SEQTERM); |
1398 | if (t_tclass & TC_SEQTERM) { /* for-in */ | 1440 | if (t_tclass & TC_SEQTERM) { /* for-in */ |
@@ -1418,6 +1460,7 @@ static void chain_group(void) | |||
1418 | 1460 | ||
1419 | case OC_PRINT: | 1461 | case OC_PRINT: |
1420 | case OC_PRINTF: | 1462 | case OC_PRINTF: |
1463 | debug_printf_parse("%s: OC_PRINT[F]\n", __func__); | ||
1421 | n = chain_node(t_info); | 1464 | n = chain_node(t_info); |
1422 | n->l.n = parse_expr(TC_OPTERM | TC_OUTRDR | TC_GRPTERM); | 1465 | n->l.n = parse_expr(TC_OPTERM | TC_OUTRDR | TC_GRPTERM); |
1423 | if (t_tclass & TC_OUTRDR) { | 1466 | if (t_tclass & TC_OUTRDR) { |
@@ -1429,17 +1472,20 @@ static void chain_group(void) | |||
1429 | break; | 1472 | break; |
1430 | 1473 | ||
1431 | case OC_BREAK: | 1474 | case OC_BREAK: |
1475 | debug_printf_parse("%s: OC_BREAK\n", __func__); | ||
1432 | n = chain_node(OC_EXEC); | 1476 | n = chain_node(OC_EXEC); |
1433 | n->a.n = break_ptr; | 1477 | n->a.n = break_ptr; |
1434 | break; | 1478 | break; |
1435 | 1479 | ||
1436 | case OC_CONTINUE: | 1480 | case OC_CONTINUE: |
1481 | debug_printf_parse("%s: OC_CONTINUE\n", __func__); | ||
1437 | n = chain_node(OC_EXEC); | 1482 | n = chain_node(OC_EXEC); |
1438 | n->a.n = continue_ptr; | 1483 | n->a.n = continue_ptr; |
1439 | break; | 1484 | break; |
1440 | 1485 | ||
1441 | /* delete, next, nextfile, return, exit */ | 1486 | /* delete, next, nextfile, return, exit */ |
1442 | default: | 1487 | default: |
1488 | debug_printf_parse("%s: default\n", __func__); | ||
1443 | chain_expr(t_info); | 1489 | chain_expr(t_info); |
1444 | } | 1490 | } |
1445 | } | 1491 | } |
@@ -1457,19 +1503,24 @@ static void parse_program(char *p) | |||
1457 | while ((tclass = next_token(TC_EOF | TC_OPSEQ | TC_GRPSTART | | 1503 | while ((tclass = next_token(TC_EOF | TC_OPSEQ | TC_GRPSTART | |
1458 | TC_OPTERM | TC_BEGIN | TC_END | TC_FUNCDECL)) != TC_EOF) { | 1504 | TC_OPTERM | TC_BEGIN | TC_END | TC_FUNCDECL)) != TC_EOF) { |
1459 | 1505 | ||
1460 | if (tclass & TC_OPTERM) | 1506 | if (tclass & TC_OPTERM) { |
1507 | debug_printf_parse("%s: TC_OPTERM\n", __func__); | ||
1461 | continue; | 1508 | continue; |
1509 | } | ||
1462 | 1510 | ||
1463 | seq = &mainseq; | 1511 | seq = &mainseq; |
1464 | if (tclass & TC_BEGIN) { | 1512 | if (tclass & TC_BEGIN) { |
1513 | debug_printf_parse("%s: TC_BEGIN\n", __func__); | ||
1465 | seq = &beginseq; | 1514 | seq = &beginseq; |
1466 | chain_group(); | 1515 | chain_group(); |
1467 | 1516 | ||
1468 | } else if (tclass & TC_END) { | 1517 | } else if (tclass & TC_END) { |
1518 | debug_printf_parse("%s: TC_END\n", __func__); | ||
1469 | seq = &endseq; | 1519 | seq = &endseq; |
1470 | chain_group(); | 1520 | chain_group(); |
1471 | 1521 | ||
1472 | } else if (tclass & TC_FUNCDECL) { | 1522 | } else if (tclass & TC_FUNCDECL) { |
1523 | debug_printf_parse("%s: TC_FUNCDECL\n", __func__); | ||
1473 | next_token(TC_FUNCTION); | 1524 | next_token(TC_FUNCTION); |
1474 | g_pos++; | 1525 | g_pos++; |
1475 | f = newfunc(t_string); | 1526 | f = newfunc(t_string); |
@@ -1487,22 +1538,27 @@ static void parse_program(char *p) | |||
1487 | clear_array(ahash); | 1538 | clear_array(ahash); |
1488 | 1539 | ||
1489 | } else if (tclass & TC_OPSEQ) { | 1540 | } else if (tclass & TC_OPSEQ) { |
1541 | debug_printf_parse("%s: TC_OPSEQ\n", __func__); | ||
1490 | rollback_token(); | 1542 | rollback_token(); |
1491 | cn = chain_node(OC_TEST); | 1543 | cn = chain_node(OC_TEST); |
1492 | cn->l.n = parse_expr(TC_OPTERM | TC_EOF | TC_GRPSTART); | 1544 | cn->l.n = parse_expr(TC_OPTERM | TC_EOF | TC_GRPSTART); |
1493 | if (t_tclass & TC_GRPSTART) { | 1545 | if (t_tclass & TC_GRPSTART) { |
1546 | debug_printf_parse("%s: TC_GRPSTART\n", __func__); | ||
1494 | rollback_token(); | 1547 | rollback_token(); |
1495 | chain_group(); | 1548 | chain_group(); |
1496 | } else { | 1549 | } else { |
1550 | debug_printf_parse("%s: !TC_GRPSTART\n", __func__); | ||
1497 | chain_node(OC_PRINT); | 1551 | chain_node(OC_PRINT); |
1498 | } | 1552 | } |
1499 | cn->r.n = mainseq.last; | 1553 | cn->r.n = mainseq.last; |
1500 | 1554 | ||
1501 | } else /* if (tclass & TC_GRPSTART) */ { | 1555 | } else /* if (tclass & TC_GRPSTART) */ { |
1556 | debug_printf_parse("%s: TC_GRPSTART(?)\n", __func__); | ||
1502 | rollback_token(); | 1557 | rollback_token(); |
1503 | chain_group(); | 1558 | chain_group(); |
1504 | } | 1559 | } |
1505 | } | 1560 | } |
1561 | debug_printf_parse("%s: TC_EOF\n", __func__); | ||
1506 | } | 1562 | } |
1507 | 1563 | ||
1508 | 1564 | ||
@@ -2627,7 +2683,7 @@ static var *evaluate(node *op, var *res) | |||
2627 | rsm = iF; | 2683 | rsm = iF; |
2628 | } | 2684 | } |
2629 | 2685 | ||
2630 | if (!rsm->F) { | 2686 | if (!rsm || !rsm->F) { |
2631 | setvar_i(intvar[ERRNO], errno); | 2687 | setvar_i(intvar[ERRNO], errno); |
2632 | setvar_i(res, -1); | 2688 | setvar_i(res, -1); |
2633 | break; | 2689 | break; |
@@ -2961,7 +3017,7 @@ static rstream *next_input_file(void) | |||
2961 | #define rsm (G.next_input_file__rsm) | 3017 | #define rsm (G.next_input_file__rsm) |
2962 | #define files_happen (G.next_input_file__files_happen) | 3018 | #define files_happen (G.next_input_file__files_happen) |
2963 | 3019 | ||
2964 | FILE *F = NULL; | 3020 | FILE *F; |
2965 | const char *fname, *ind; | 3021 | const char *fname, *ind; |
2966 | 3022 | ||
2967 | if (rsm.F) | 3023 | if (rsm.F) |
@@ -2969,19 +3025,21 @@ static rstream *next_input_file(void) | |||
2969 | rsm.F = NULL; | 3025 | rsm.F = NULL; |
2970 | rsm.pos = rsm.adv = 0; | 3026 | rsm.pos = rsm.adv = 0; |
2971 | 3027 | ||
2972 | do { | 3028 | for (;;) { |
2973 | if (getvar_i(intvar[ARGIND])+1 >= getvar_i(intvar[ARGC])) { | 3029 | if (getvar_i(intvar[ARGIND])+1 >= getvar_i(intvar[ARGC])) { |
2974 | if (files_happen) | 3030 | if (files_happen) |
2975 | return NULL; | 3031 | return NULL; |
2976 | fname = "-"; | 3032 | fname = "-"; |
2977 | F = stdin; | 3033 | F = stdin; |
2978 | } else { | 3034 | break; |
2979 | ind = getvar_s(incvar(intvar[ARGIND])); | ||
2980 | fname = getvar_s(findvar(iamarray(intvar[ARGV]), ind)); | ||
2981 | if (fname && *fname && !is_assignment(fname)) | ||
2982 | F = xfopen_stdin(fname); | ||
2983 | } | 3035 | } |
2984 | } while (!F); | 3036 | ind = getvar_s(incvar(intvar[ARGIND])); |
3037 | fname = getvar_s(findvar(iamarray(intvar[ARGV]), ind)); | ||
3038 | if (fname && *fname && !is_assignment(fname)) { | ||
3039 | F = xfopen_stdin(fname); | ||
3040 | break; | ||
3041 | } | ||
3042 | } | ||
2985 | 3043 | ||
2986 | files_happen = TRUE; | 3044 | files_happen = TRUE; |
2987 | setvar_s(intvar[FILENAME], fname); | 3045 | setvar_s(intvar[FILENAME], fname); |
@@ -2995,7 +3053,7 @@ int awk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |||
2995 | int awk_main(int argc, char **argv) | 3053 | int awk_main(int argc, char **argv) |
2996 | { | 3054 | { |
2997 | unsigned opt; | 3055 | unsigned opt; |
2998 | char *opt_F, *opt_W; | 3056 | char *opt_F; |
2999 | llist_t *list_v = NULL; | 3057 | llist_t *list_v = NULL; |
3000 | llist_t *list_f = NULL; | 3058 | llist_t *list_f = NULL; |
3001 | int i, j; | 3059 | int i, j; |
@@ -3057,7 +3115,7 @@ int awk_main(int argc, char **argv) | |||
3057 | } | 3115 | } |
3058 | } | 3116 | } |
3059 | opt_complementary = "v::f::"; /* -v and -f can occur multiple times */ | 3117 | opt_complementary = "v::f::"; /* -v and -f can occur multiple times */ |
3060 | opt = getopt32(argv, "F:v:f:W:", &opt_F, &list_v, &list_f, &opt_W); | 3118 | opt = getopt32(argv, "F:v:f:W:", &opt_F, &list_v, &list_f, NULL); |
3061 | argv += optind; | 3119 | argv += optind; |
3062 | argc -= optind; | 3120 | argc -= optind; |
3063 | if (opt & 0x1) | 3121 | if (opt & 0x1) |
@@ -3091,7 +3149,7 @@ int awk_main(int argc, char **argv) | |||
3091 | parse_program(*argv++); | 3149 | parse_program(*argv++); |
3092 | } | 3150 | } |
3093 | if (opt & 0x8) // -W | 3151 | if (opt & 0x8) // -W |
3094 | bb_error_msg("warning: unrecognized option '-W %s' ignored", opt_W); | 3152 | bb_error_msg("warning: option -W is ignored"); |
3095 | 3153 | ||
3096 | /* fill in ARGV array */ | 3154 | /* fill in ARGV array */ |
3097 | setvar_i(intvar[ARGC], argc); | 3155 | setvar_i(intvar[ARGC], argc); |