diff options
-rw-r--r-- | ChangeLog | 48 | ||||
-rw-r--r-- | awk.h | 32 | ||||
-rw-r--r-- | awkgram.c | 272 | ||||
-rw-r--r-- | awkgram.y | 14 | ||||
-rw-r--r-- | doc/ChangeLog | 4 | ||||
-rw-r--r-- | doc/awkcard.in | 24 | ||||
-rw-r--r-- | doc/gawk.1 | 66 | ||||
-rw-r--r-- | doc/gawk.info | 602 | ||||
-rw-r--r-- | doc/gawk.texi | 64 | ||||
-rw-r--r-- | eval.c | 1 | ||||
-rw-r--r-- | interpret.h | 47 | ||||
-rw-r--r-- | main.c | 8 | ||||
-rw-r--r-- | profile.c | 9 | ||||
-rw-r--r-- | symbol.c | 302 | ||||
-rw-r--r-- | test/ChangeLog | 7 | ||||
-rw-r--r-- | test/Makefile.am | 91 | ||||
-rw-r--r-- | test/Makefile.in | 130 | ||||
-rw-r--r-- | test/Maketests | 40 | ||||
-rw-r--r-- | test/functab1.awk | 3 | ||||
-rw-r--r-- | test/functab1.ok | 2 | ||||
-rw-r--r-- | test/functab2.awk | 8 | ||||
-rw-r--r-- | test/functab2.ok | 2 | ||||
-rw-r--r-- | test/functab3.awk | 10 | ||||
-rw-r--r-- | test/functab3.ok | 2 | ||||
-rw-r--r-- | test/functab4.awk | 14 | ||||
-rw-r--r-- | test/functab4.ok | 3 | ||||
-rw-r--r-- | test/id.awk | 11 | ||||
-rw-r--r-- | test/id.ok | 32 | ||||
-rw-r--r-- | test/symtab1.awk | 18 | ||||
-rw-r--r-- | test/symtab1.ok | 31 | ||||
-rw-r--r-- | test/symtab2.awk | 6 | ||||
-rw-r--r-- | test/symtab2.ok | 2 | ||||
-rw-r--r-- | test/symtab3.awk | 1 | ||||
-rw-r--r-- | test/symtab3.ok | 2 |
34 files changed, 1259 insertions, 649 deletions
@@ -17,6 +17,54 @@ extension/Makefile.in, extension/aclocal.m4, test/Makefile.in: Regenerated. + * interpret.h (Op_Subscript): Added lint warnings for FUNCTAB + and SYMTAB. + +2012-10-02 Arnold D. Robbins <arnold@skeeve.com> + + * awk.h (func_table): Declare. + * awkgram.y: If do_posix or do_traditional, then check for + delete on SYMTAB. Add check for delete on FUNCTAB, also. + * interpret.h (Op_Subscript): For FUNCTAB, return the element name + as its value too. Avoids lots of weirdness and allows indirect calls + after assignment from FUNCTAB["foo"] to work. + (Op_store_sub): Disallow assignment to elements of FUNCTAB. + (Op_indirect_func_all): Turn assert into check and fatal error. + * symbol.c (func_table): No longer static. + (lookup): If do_posix or do_traditional, skip the global table. + (release_all_vars): Clear func_table too. + +2012-09-25 Arnold D. Robbins <arnold@skeeve.com> + + First cut at SYMTAB and FUNCTAB. This does the following: + - Change symbol table handling to use gawk arrays. + - Store symbols in SYMTAB array and allow indirect access + through SYMTAB to variables, both getting and setting. + - List function names in FUNCTAB indexes; Values cannot be + used at the moment. + - No documentation yet. + + * awk.h (Node_hashnode, hnext, hname, hlength, hcode, hvalue): + Removed, not needed any more. + (init_symbol_table, symbol_table): Add declarations. + * awkgram.y: Disallow delete on SYMTAB, fix warning for tawk + extension if traditional. + * eval.c (nodetypes): Remove Node_hashnode element. + * interpret.h (Op_subscript, Op_store_sub): Handle SYMTAB and go + through to the actual value. + * main.c (main): Init Nnull_string earlier. Add call to + init_symbol_table(). + * profile.c (pp_str, pp_len): Change definitions. + (pp_next): New macro. + (pp_push, pp_pop): Adjust uses. + * symbol.c (variables): Removed. + (global_table, param_table, func_table, symbol_table, + installing_specials): New variables. + (lookup, make_params, install_params, remove_params, remove_symbol, + make_symbol, install, get_symbols, release_all_vars, append_symbol, + release_symbols, load_symbols): Rework logic considerably. + (init_symbol_table): New function. + 2012-09-23 Arnold D. Robbins <arnold@skeeve.com> `delete array' and `nextfile' are now in POSIX. @@ -314,7 +314,6 @@ typedef enum nodevals { Node_func, /* lnode is param. list, rnode is body */ Node_ext_func, /* extension function, code_ptr is builtin code */ - Node_hashnode, /* an identifier in the symbol table */ Node_array_ref, /* array passed by ref as parameter */ Node_array_tree, /* Hashed array tree (HAT) */ Node_array_leaf, /* Linear 1-D array */ @@ -462,17 +461,11 @@ typedef struct exp_node { #define nextp sub.nodep.l.lptr #define rnode sub.nodep.r.rptr -/* Node_hashnode, Node_param_list */ -#define hnext sub.nodep.r.rptr -#define hname vname -#define hlength sub.nodep.reserved -#define hcode sub.nodep.cnt -#define hvalue sub.nodep.x.extra +/* Node_param_list */ +#define param vname /* Node_param_list, Node_func */ #define param_cnt sub.nodep.l.ll -/* Node_param_list */ -#define param vname /* Node_func */ #define fparms sub.nodep.rn @@ -1372,15 +1365,15 @@ if (--val) \ /* array.c */ typedef enum sort_context { SORTED_IN = 1, ASORT, ASORTI } SORT_CTXT; enum assoc_list_flags { -AINDEX = 0x01, /* list of indices */ -AVALUE = 0x02, /* list of values */ -AINUM = 0x04, /* numeric index */ -AISTR = 0x08, /* string index */ -AVNUM = 0x10, /* numeric scalar value */ -AVSTR = 0x20, /* string scalar value */ -AASC = 0x40, /* ascending order */ -ADESC = 0x80, /* descending order */ -ADELETE = 0x100, /* need a single index; for use in do_delete_loop */ + AINDEX = 0x01, /* list of indices */ + AVALUE = 0x02, /* list of values */ + AINUM = 0x04, /* numeric index */ + AISTR = 0x08, /* string index */ + AVNUM = 0x10, /* numeric scalar value */ + AVSTR = 0x20, /* string scalar value */ + AASC = 0x40, /* ascending order */ + ADESC = 0x80, /* descending order */ + ADELETE = 0x100, /* need a single index; for use in do_delete_loop */ }; extern NODE *make_array(void); @@ -1670,6 +1663,9 @@ extern int get_numbase(const char *str, bool use_locale); /* symbol.c */ extern void load_symbols(); +extern void init_symbol_table(); +extern NODE *symbol_table; +extern NODE *func_table; extern NODE *install_symbol(char *name, NODETYPE type); extern NODE *remove_symbol(NODE *r); extern void destroy_symbol(NODE *r); @@ -733,19 +733,19 @@ static const yytype_uint16 yyrline[] = 372, 373, 377, 396, 395, 429, 431, 436, 437, 450, 455, 456, 460, 462, 464, 471, 561, 603, 645, 758, 765, 772, 782, 791, 800, 809, 820, 836, 835, 859, - 871, 871, 969, 969, 995, 1018, 1024, 1025, 1031, 1032, - 1039, 1044, 1056, 1070, 1072, 1080, 1085, 1087, 1095, 1097, - 1106, 1107, 1115, 1120, 1120, 1131, 1135, 1143, 1144, 1147, - 1149, 1154, 1155, 1164, 1165, 1170, 1175, 1181, 1183, 1185, - 1192, 1193, 1199, 1200, 1205, 1207, 1212, 1214, 1216, 1218, - 1224, 1231, 1233, 1235, 1251, 1261, 1268, 1270, 1275, 1277, - 1279, 1287, 1289, 1294, 1296, 1301, 1303, 1305, 1355, 1357, - 1359, 1361, 1363, 1365, 1367, 1369, 1392, 1397, 1402, 1427, - 1433, 1435, 1437, 1439, 1441, 1443, 1448, 1452, 1484, 1486, - 1492, 1498, 1511, 1512, 1513, 1518, 1523, 1527, 1531, 1546, - 1559, 1564, 1600, 1618, 1619, 1625, 1626, 1631, 1633, 1640, - 1657, 1674, 1676, 1683, 1688, 1696, 1706, 1718, 1727, 1731, - 1735, 1739, 1743, 1747, 1750, 1752, 1756, 1760, 1764 + 871, 871, 969, 969, 1002, 1032, 1038, 1039, 1045, 1046, + 1053, 1058, 1070, 1084, 1086, 1094, 1099, 1101, 1109, 1111, + 1120, 1121, 1129, 1134, 1134, 1145, 1149, 1157, 1158, 1161, + 1163, 1168, 1169, 1178, 1179, 1184, 1189, 1195, 1197, 1199, + 1206, 1207, 1213, 1214, 1219, 1221, 1226, 1228, 1230, 1232, + 1238, 1245, 1247, 1249, 1265, 1275, 1282, 1284, 1289, 1291, + 1293, 1301, 1303, 1308, 1310, 1315, 1317, 1319, 1369, 1371, + 1373, 1375, 1377, 1379, 1381, 1383, 1406, 1411, 1416, 1441, + 1447, 1449, 1451, 1453, 1455, 1457, 1462, 1466, 1498, 1500, + 1506, 1512, 1525, 1526, 1527, 1532, 1537, 1541, 1545, 1560, + 1573, 1578, 1614, 1632, 1633, 1639, 1640, 1645, 1647, 1654, + 1671, 1688, 1690, 1697, 1702, 1710, 1720, 1732, 1741, 1745, + 1749, 1753, 1757, 1761, 1764, 1766, 1770, 1774, 1778 }; #endif @@ -2990,6 +2990,13 @@ regular_print: (yyvsp[(2) - (4)])->opcode = Op_push_array; (yyvsp[(2) - (4)])->memory = variable((yyvsp[(2) - (4)])->source_line, arr, Node_var_new); + if (! do_posix && ! do_traditional) { + if ((yyvsp[(2) - (4)])->memory == symbol_table) + fatal(_("`delete' is not allowed with SYMTAB")); + else if ((yyvsp[(2) - (4)])->memory == func_table) + fatal(_("`delete' is not allowed with FUNCTAB")); + } + if ((yyvsp[(4) - (4)]) == NULL) { /* * As of September 2012, POSIX has added support @@ -3013,7 +3020,7 @@ regular_print: case 64: /* Line 1787 of yacc.c */ -#line 1000 "awkgram.y" +#line 1007 "awkgram.y" { static bool warned = false; char *arr = (yyvsp[(3) - (4)])->lextok; @@ -3031,36 +3038,43 @@ regular_print: (yyvsp[(3) - (4)])->opcode = Op_push_array; (yyvsp[(1) - (4)])->expr_count = 0; (yyval) = list_append(list_create((yyvsp[(3) - (4)])), (yyvsp[(1) - (4)])); + + if (! do_posix && ! do_traditional) { + if ((yyvsp[(3) - (4)])->memory == symbol_table) + fatal(_("`delete' is not allowed with SYMTAB")); + else if ((yyvsp[(3) - (4)])->memory == func_table) + fatal(_("`delete' is not allowed with FUNCTAB")); + } } break; case 65: /* Line 1787 of yacc.c */ -#line 1019 "awkgram.y" +#line 1033 "awkgram.y" { (yyval) = optimize_assignment((yyvsp[(1) - (1)])); } break; case 66: /* Line 1787 of yacc.c */ -#line 1024 "awkgram.y" +#line 1038 "awkgram.y" { (yyval) = NULL; } break; case 67: /* Line 1787 of yacc.c */ -#line 1026 "awkgram.y" +#line 1040 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 68: /* Line 1787 of yacc.c */ -#line 1031 "awkgram.y" +#line 1045 "awkgram.y" { (yyval) = NULL; } break; case 69: /* Line 1787 of yacc.c */ -#line 1033 "awkgram.y" +#line 1047 "awkgram.y" { if ((yyvsp[(1) - (2)]) == NULL) (yyval) = list_create((yyvsp[(2) - (2)])); @@ -3071,13 +3085,13 @@ regular_print: case 70: /* Line 1787 of yacc.c */ -#line 1040 "awkgram.y" +#line 1054 "awkgram.y" { (yyval) = NULL; } break; case 71: /* Line 1787 of yacc.c */ -#line 1045 "awkgram.y" +#line 1059 "awkgram.y" { INSTRUCTION *casestmt = (yyvsp[(5) - (5)]); if ((yyvsp[(5) - (5)]) == NULL) @@ -3093,7 +3107,7 @@ regular_print: case 72: /* Line 1787 of yacc.c */ -#line 1057 "awkgram.y" +#line 1071 "awkgram.y" { INSTRUCTION *casestmt = (yyvsp[(4) - (4)]); if ((yyvsp[(4) - (4)]) == NULL) @@ -3108,13 +3122,13 @@ regular_print: case 73: /* Line 1787 of yacc.c */ -#line 1071 "awkgram.y" +#line 1085 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 74: /* Line 1787 of yacc.c */ -#line 1073 "awkgram.y" +#line 1087 "awkgram.y" { NODE *n = (yyvsp[(2) - (2)])->memory; (void) force_number(n); @@ -3126,7 +3140,7 @@ regular_print: case 75: /* Line 1787 of yacc.c */ -#line 1081 "awkgram.y" +#line 1095 "awkgram.y" { bcfree((yyvsp[(1) - (2)])); (yyval) = (yyvsp[(2) - (2)]); @@ -3135,13 +3149,13 @@ regular_print: case 76: /* Line 1787 of yacc.c */ -#line 1086 "awkgram.y" +#line 1100 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 77: /* Line 1787 of yacc.c */ -#line 1088 "awkgram.y" +#line 1102 "awkgram.y" { (yyvsp[(1) - (1)])->opcode = Op_push_re; (yyval) = (yyvsp[(1) - (1)]); @@ -3150,19 +3164,19 @@ regular_print: case 78: /* Line 1787 of yacc.c */ -#line 1096 "awkgram.y" +#line 1110 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 79: /* Line 1787 of yacc.c */ -#line 1098 "awkgram.y" +#line 1112 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 81: /* Line 1787 of yacc.c */ -#line 1108 "awkgram.y" +#line 1122 "awkgram.y" { (yyval) = (yyvsp[(2) - (3)]); } @@ -3170,7 +3184,7 @@ regular_print: case 82: /* Line 1787 of yacc.c */ -#line 1115 "awkgram.y" +#line 1129 "awkgram.y" { in_print = false; in_parens = 0; @@ -3180,13 +3194,13 @@ regular_print: case 83: /* Line 1787 of yacc.c */ -#line 1120 "awkgram.y" +#line 1134 "awkgram.y" { in_print = false; in_parens = 0; } break; case 84: /* Line 1787 of yacc.c */ -#line 1121 "awkgram.y" +#line 1135 "awkgram.y" { if ((yyvsp[(1) - (3)])->redir_type == redirect_twoway && (yyvsp[(3) - (3)])->lasti->opcode == Op_K_getline_redir @@ -3198,7 +3212,7 @@ regular_print: case 85: /* Line 1787 of yacc.c */ -#line 1132 "awkgram.y" +#line 1146 "awkgram.y" { (yyval) = mk_condition((yyvsp[(3) - (6)]), (yyvsp[(1) - (6)]), (yyvsp[(6) - (6)]), NULL, NULL); } @@ -3206,7 +3220,7 @@ regular_print: case 86: /* Line 1787 of yacc.c */ -#line 1137 "awkgram.y" +#line 1151 "awkgram.y" { (yyval) = mk_condition((yyvsp[(3) - (9)]), (yyvsp[(1) - (9)]), (yyvsp[(6) - (9)]), (yyvsp[(7) - (9)]), (yyvsp[(9) - (9)])); } @@ -3214,13 +3228,13 @@ regular_print: case 91: /* Line 1787 of yacc.c */ -#line 1154 "awkgram.y" +#line 1168 "awkgram.y" { (yyval) = NULL; } break; case 92: /* Line 1787 of yacc.c */ -#line 1156 "awkgram.y" +#line 1170 "awkgram.y" { bcfree((yyvsp[(1) - (2)])); (yyval) = (yyvsp[(2) - (2)]); @@ -3229,19 +3243,19 @@ regular_print: case 93: /* Line 1787 of yacc.c */ -#line 1164 "awkgram.y" +#line 1178 "awkgram.y" { (yyval) = NULL; } break; case 94: /* Line 1787 of yacc.c */ -#line 1166 "awkgram.y" +#line 1180 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]) ; } break; case 95: /* Line 1787 of yacc.c */ -#line 1171 "awkgram.y" +#line 1185 "awkgram.y" { (yyvsp[(1) - (1)])->param_count = 0; (yyval) = list_create((yyvsp[(1) - (1)])); @@ -3250,7 +3264,7 @@ regular_print: case 96: /* Line 1787 of yacc.c */ -#line 1176 "awkgram.y" +#line 1190 "awkgram.y" { (yyvsp[(3) - (3)])->param_count = (yyvsp[(1) - (3)])->lasti->param_count + 1; (yyval) = list_append((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)])); @@ -3260,55 +3274,55 @@ regular_print: case 97: /* Line 1787 of yacc.c */ -#line 1182 "awkgram.y" +#line 1196 "awkgram.y" { (yyval) = NULL; } break; case 98: /* Line 1787 of yacc.c */ -#line 1184 "awkgram.y" +#line 1198 "awkgram.y" { (yyval) = (yyvsp[(1) - (2)]); } break; case 99: /* Line 1787 of yacc.c */ -#line 1186 "awkgram.y" +#line 1200 "awkgram.y" { (yyval) = (yyvsp[(1) - (3)]); } break; case 100: /* Line 1787 of yacc.c */ -#line 1192 "awkgram.y" +#line 1206 "awkgram.y" { (yyval) = NULL; } break; case 101: /* Line 1787 of yacc.c */ -#line 1194 "awkgram.y" +#line 1208 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 102: /* Line 1787 of yacc.c */ -#line 1199 "awkgram.y" +#line 1213 "awkgram.y" { (yyval) = NULL; } break; case 103: /* Line 1787 of yacc.c */ -#line 1201 "awkgram.y" +#line 1215 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 104: /* Line 1787 of yacc.c */ -#line 1206 "awkgram.y" +#line 1220 "awkgram.y" { (yyval) = mk_expression_list(NULL, (yyvsp[(1) - (1)])); } break; case 105: /* Line 1787 of yacc.c */ -#line 1208 "awkgram.y" +#line 1222 "awkgram.y" { (yyval) = mk_expression_list((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)])); yyerrok; @@ -3317,31 +3331,31 @@ regular_print: case 106: /* Line 1787 of yacc.c */ -#line 1213 "awkgram.y" +#line 1227 "awkgram.y" { (yyval) = NULL; } break; case 107: /* Line 1787 of yacc.c */ -#line 1215 "awkgram.y" +#line 1229 "awkgram.y" { (yyval) = NULL; } break; case 108: /* Line 1787 of yacc.c */ -#line 1217 "awkgram.y" +#line 1231 "awkgram.y" { (yyval) = NULL; } break; case 109: /* Line 1787 of yacc.c */ -#line 1219 "awkgram.y" +#line 1233 "awkgram.y" { (yyval) = NULL; } break; case 110: /* Line 1787 of yacc.c */ -#line 1225 "awkgram.y" +#line 1239 "awkgram.y" { if (do_lint && (yyvsp[(3) - (3)])->lasti->opcode == Op_match_rec) lintwarn_ln((yyvsp[(2) - (3)])->source_line, @@ -3352,19 +3366,19 @@ regular_print: case 111: /* Line 1787 of yacc.c */ -#line 1232 "awkgram.y" +#line 1246 "awkgram.y" { (yyval) = mk_boolean((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 112: /* Line 1787 of yacc.c */ -#line 1234 "awkgram.y" +#line 1248 "awkgram.y" { (yyval) = mk_boolean((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 113: /* Line 1787 of yacc.c */ -#line 1236 "awkgram.y" +#line 1250 "awkgram.y" { if ((yyvsp[(1) - (3)])->lasti->opcode == Op_match_rec) warning_ln((yyvsp[(2) - (3)])->source_line, @@ -3384,7 +3398,7 @@ regular_print: case 114: /* Line 1787 of yacc.c */ -#line 1252 "awkgram.y" +#line 1266 "awkgram.y" { if (do_lint_old) warning_ln((yyvsp[(2) - (3)])->source_line, @@ -3398,7 +3412,7 @@ regular_print: case 115: /* Line 1787 of yacc.c */ -#line 1262 "awkgram.y" +#line 1276 "awkgram.y" { if (do_lint && (yyvsp[(3) - (3)])->lasti->opcode == Op_match_rec) lintwarn_ln((yyvsp[(2) - (3)])->source_line, @@ -3409,31 +3423,31 @@ regular_print: case 116: /* Line 1787 of yacc.c */ -#line 1269 "awkgram.y" +#line 1283 "awkgram.y" { (yyval) = mk_condition((yyvsp[(1) - (5)]), (yyvsp[(2) - (5)]), (yyvsp[(3) - (5)]), (yyvsp[(4) - (5)]), (yyvsp[(5) - (5)])); } break; case 117: /* Line 1787 of yacc.c */ -#line 1271 "awkgram.y" +#line 1285 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 118: /* Line 1787 of yacc.c */ -#line 1276 "awkgram.y" +#line 1290 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 119: /* Line 1787 of yacc.c */ -#line 1278 "awkgram.y" +#line 1292 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 120: /* Line 1787 of yacc.c */ -#line 1280 "awkgram.y" +#line 1294 "awkgram.y" { (yyvsp[(2) - (2)])->opcode = Op_assign_quotient; (yyval) = (yyvsp[(2) - (2)]); @@ -3442,43 +3456,43 @@ regular_print: case 121: /* Line 1787 of yacc.c */ -#line 1288 "awkgram.y" +#line 1302 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 122: /* Line 1787 of yacc.c */ -#line 1290 "awkgram.y" +#line 1304 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 123: /* Line 1787 of yacc.c */ -#line 1295 "awkgram.y" +#line 1309 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 124: /* Line 1787 of yacc.c */ -#line 1297 "awkgram.y" +#line 1311 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 125: /* Line 1787 of yacc.c */ -#line 1302 "awkgram.y" +#line 1316 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 126: /* Line 1787 of yacc.c */ -#line 1304 "awkgram.y" +#line 1318 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 127: /* Line 1787 of yacc.c */ -#line 1306 "awkgram.y" +#line 1320 "awkgram.y" { int count = 2; bool is_simple_var = false; @@ -3529,43 +3543,43 @@ regular_print: case 129: /* Line 1787 of yacc.c */ -#line 1358 "awkgram.y" +#line 1372 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 130: /* Line 1787 of yacc.c */ -#line 1360 "awkgram.y" +#line 1374 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 131: /* Line 1787 of yacc.c */ -#line 1362 "awkgram.y" +#line 1376 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 132: /* Line 1787 of yacc.c */ -#line 1364 "awkgram.y" +#line 1378 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 133: /* Line 1787 of yacc.c */ -#line 1366 "awkgram.y" +#line 1380 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 134: /* Line 1787 of yacc.c */ -#line 1368 "awkgram.y" +#line 1382 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 135: /* Line 1787 of yacc.c */ -#line 1370 "awkgram.y" +#line 1384 "awkgram.y" { /* * In BEGINFILE/ENDFILE, allow `getline var < file' @@ -3592,7 +3606,7 @@ regular_print: case 136: /* Line 1787 of yacc.c */ -#line 1393 "awkgram.y" +#line 1407 "awkgram.y" { (yyvsp[(2) - (2)])->opcode = Op_postincrement; (yyval) = mk_assignment((yyvsp[(1) - (2)]), NULL, (yyvsp[(2) - (2)])); @@ -3601,7 +3615,7 @@ regular_print: case 137: /* Line 1787 of yacc.c */ -#line 1398 "awkgram.y" +#line 1412 "awkgram.y" { (yyvsp[(2) - (2)])->opcode = Op_postdecrement; (yyval) = mk_assignment((yyvsp[(1) - (2)]), NULL, (yyvsp[(2) - (2)])); @@ -3610,7 +3624,7 @@ regular_print: case 138: /* Line 1787 of yacc.c */ -#line 1403 "awkgram.y" +#line 1417 "awkgram.y" { if (do_lint_old) { warning_ln((yyvsp[(4) - (5)])->source_line, @@ -3634,7 +3648,7 @@ regular_print: case 139: /* Line 1787 of yacc.c */ -#line 1428 "awkgram.y" +#line 1442 "awkgram.y" { (yyval) = mk_getline((yyvsp[(3) - (4)]), (yyvsp[(4) - (4)]), (yyvsp[(1) - (4)]), (yyvsp[(2) - (4)])->redir_type); bcfree((yyvsp[(2) - (4)])); @@ -3643,43 +3657,43 @@ regular_print: case 140: /* Line 1787 of yacc.c */ -#line 1434 "awkgram.y" +#line 1448 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 141: /* Line 1787 of yacc.c */ -#line 1436 "awkgram.y" +#line 1450 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 142: /* Line 1787 of yacc.c */ -#line 1438 "awkgram.y" +#line 1452 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 143: /* Line 1787 of yacc.c */ -#line 1440 "awkgram.y" +#line 1454 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 144: /* Line 1787 of yacc.c */ -#line 1442 "awkgram.y" +#line 1456 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 145: /* Line 1787 of yacc.c */ -#line 1444 "awkgram.y" +#line 1458 "awkgram.y" { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } break; case 146: /* Line 1787 of yacc.c */ -#line 1449 "awkgram.y" +#line 1463 "awkgram.y" { (yyval) = list_create((yyvsp[(1) - (1)])); } @@ -3687,7 +3701,7 @@ regular_print: case 147: /* Line 1787 of yacc.c */ -#line 1453 "awkgram.y" +#line 1467 "awkgram.y" { if ((yyvsp[(2) - (2)])->opcode == Op_match_rec) { (yyvsp[(2) - (2)])->opcode = Op_nomatch; @@ -3723,13 +3737,13 @@ regular_print: case 148: /* Line 1787 of yacc.c */ -#line 1485 "awkgram.y" +#line 1499 "awkgram.y" { (yyval) = (yyvsp[(2) - (3)]); } break; case 149: /* Line 1787 of yacc.c */ -#line 1487 "awkgram.y" +#line 1501 "awkgram.y" { (yyval) = snode((yyvsp[(3) - (4)]), (yyvsp[(1) - (4)])); if ((yyval) == NULL) @@ -3739,7 +3753,7 @@ regular_print: case 150: /* Line 1787 of yacc.c */ -#line 1493 "awkgram.y" +#line 1507 "awkgram.y" { (yyval) = snode((yyvsp[(3) - (4)]), (yyvsp[(1) - (4)])); if ((yyval) == NULL) @@ -3749,7 +3763,7 @@ regular_print: case 151: /* Line 1787 of yacc.c */ -#line 1499 "awkgram.y" +#line 1513 "awkgram.y" { static bool warned = false; @@ -3766,7 +3780,7 @@ regular_print: case 154: /* Line 1787 of yacc.c */ -#line 1514 "awkgram.y" +#line 1528 "awkgram.y" { (yyvsp[(1) - (2)])->opcode = Op_preincrement; (yyval) = mk_assignment((yyvsp[(2) - (2)]), NULL, (yyvsp[(1) - (2)])); @@ -3775,7 +3789,7 @@ regular_print: case 155: /* Line 1787 of yacc.c */ -#line 1519 "awkgram.y" +#line 1533 "awkgram.y" { (yyvsp[(1) - (2)])->opcode = Op_predecrement; (yyval) = mk_assignment((yyvsp[(2) - (2)]), NULL, (yyvsp[(1) - (2)])); @@ -3784,7 +3798,7 @@ regular_print: case 156: /* Line 1787 of yacc.c */ -#line 1524 "awkgram.y" +#line 1538 "awkgram.y" { (yyval) = list_create((yyvsp[(1) - (1)])); } @@ -3792,7 +3806,7 @@ regular_print: case 157: /* Line 1787 of yacc.c */ -#line 1528 "awkgram.y" +#line 1542 "awkgram.y" { (yyval) = list_create((yyvsp[(1) - (1)])); } @@ -3800,7 +3814,7 @@ regular_print: case 158: /* Line 1787 of yacc.c */ -#line 1532 "awkgram.y" +#line 1546 "awkgram.y" { if ((yyvsp[(2) - (2)])->lasti->opcode == Op_push_i && ((yyvsp[(2) - (2)])->lasti->memory->flags & (STRCUR|STRING)) == 0 @@ -3819,7 +3833,7 @@ regular_print: case 159: /* Line 1787 of yacc.c */ -#line 1547 "awkgram.y" +#line 1561 "awkgram.y" { /* * was: $$ = $2 @@ -3833,7 +3847,7 @@ regular_print: case 160: /* Line 1787 of yacc.c */ -#line 1560 "awkgram.y" +#line 1574 "awkgram.y" { func_use((yyvsp[(1) - (1)])->lasti->func_name, FUNC_USE); (yyval) = (yyvsp[(1) - (1)]); @@ -3842,7 +3856,7 @@ regular_print: case 161: /* Line 1787 of yacc.c */ -#line 1565 "awkgram.y" +#line 1579 "awkgram.y" { /* indirect function call */ INSTRUCTION *f, *t; @@ -3879,7 +3893,7 @@ regular_print: case 162: /* Line 1787 of yacc.c */ -#line 1601 "awkgram.y" +#line 1615 "awkgram.y" { param_sanity((yyvsp[(3) - (4)])); (yyvsp[(1) - (4)])->opcode = Op_func_call; @@ -3897,37 +3911,37 @@ regular_print: case 163: /* Line 1787 of yacc.c */ -#line 1618 "awkgram.y" +#line 1632 "awkgram.y" { (yyval) = NULL; } break; case 164: /* Line 1787 of yacc.c */ -#line 1620 "awkgram.y" +#line 1634 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 165: /* Line 1787 of yacc.c */ -#line 1625 "awkgram.y" +#line 1639 "awkgram.y" { (yyval) = NULL; } break; case 166: /* Line 1787 of yacc.c */ -#line 1627 "awkgram.y" +#line 1641 "awkgram.y" { (yyval) = (yyvsp[(1) - (2)]); } break; case 167: /* Line 1787 of yacc.c */ -#line 1632 "awkgram.y" +#line 1646 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 168: /* Line 1787 of yacc.c */ -#line 1634 "awkgram.y" +#line 1648 "awkgram.y" { (yyval) = list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)])); } @@ -3935,7 +3949,7 @@ regular_print: case 169: /* Line 1787 of yacc.c */ -#line 1641 "awkgram.y" +#line 1655 "awkgram.y" { INSTRUCTION *ip = (yyvsp[(1) - (1)])->lasti; int count = ip->sub_count; /* # of SUBSEP-seperated expressions */ @@ -3953,7 +3967,7 @@ regular_print: case 170: /* Line 1787 of yacc.c */ -#line 1658 "awkgram.y" +#line 1672 "awkgram.y" { INSTRUCTION *t = (yyvsp[(2) - (3)]); if ((yyvsp[(2) - (3)]) == NULL) { @@ -3971,13 +3985,13 @@ regular_print: case 171: /* Line 1787 of yacc.c */ -#line 1675 "awkgram.y" +#line 1689 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 172: /* Line 1787 of yacc.c */ -#line 1677 "awkgram.y" +#line 1691 "awkgram.y" { (yyval) = list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)])); } @@ -3985,13 +3999,13 @@ regular_print: case 173: /* Line 1787 of yacc.c */ -#line 1684 "awkgram.y" +#line 1698 "awkgram.y" { (yyval) = (yyvsp[(1) - (2)]); } break; case 174: /* Line 1787 of yacc.c */ -#line 1689 "awkgram.y" +#line 1703 "awkgram.y" { char *var_name = (yyvsp[(1) - (1)])->lextok; @@ -4003,7 +4017,7 @@ regular_print: case 175: /* Line 1787 of yacc.c */ -#line 1697 "awkgram.y" +#line 1711 "awkgram.y" { char *arr = (yyvsp[(1) - (2)])->lextok; (yyvsp[(1) - (2)])->memory = variable((yyvsp[(1) - (2)])->source_line, arr, Node_var_new); @@ -4014,7 +4028,7 @@ regular_print: case 176: /* Line 1787 of yacc.c */ -#line 1707 "awkgram.y" +#line 1721 "awkgram.y" { INSTRUCTION *ip = (yyvsp[(1) - (1)])->nexti; if (ip->opcode == Op_push @@ -4030,7 +4044,7 @@ regular_print: case 177: /* Line 1787 of yacc.c */ -#line 1719 "awkgram.y" +#line 1733 "awkgram.y" { (yyval) = list_append((yyvsp[(2) - (3)]), (yyvsp[(1) - (3)])); if ((yyvsp[(3) - (3)]) != NULL) @@ -4040,7 +4054,7 @@ regular_print: case 178: /* Line 1787 of yacc.c */ -#line 1728 "awkgram.y" +#line 1742 "awkgram.y" { (yyvsp[(1) - (1)])->opcode = Op_postincrement; } @@ -4048,7 +4062,7 @@ regular_print: case 179: /* Line 1787 of yacc.c */ -#line 1732 "awkgram.y" +#line 1746 "awkgram.y" { (yyvsp[(1) - (1)])->opcode = Op_postdecrement; } @@ -4056,43 +4070,43 @@ regular_print: case 180: /* Line 1787 of yacc.c */ -#line 1735 "awkgram.y" +#line 1749 "awkgram.y" { (yyval) = NULL; } break; case 182: /* Line 1787 of yacc.c */ -#line 1743 "awkgram.y" +#line 1757 "awkgram.y" { yyerrok; } break; case 183: /* Line 1787 of yacc.c */ -#line 1747 "awkgram.y" +#line 1761 "awkgram.y" { yyerrok; } break; case 186: /* Line 1787 of yacc.c */ -#line 1756 "awkgram.y" +#line 1770 "awkgram.y" { yyerrok; } break; case 187: /* Line 1787 of yacc.c */ -#line 1760 "awkgram.y" +#line 1774 "awkgram.y" { (yyval) = (yyvsp[(1) - (1)]); yyerrok; } break; case 188: /* Line 1787 of yacc.c */ -#line 1764 "awkgram.y" +#line 1778 "awkgram.y" { yyerrok; } break; /* Line 1787 of yacc.c */ -#line 4108 "awkgram.c" +#line 4122 "awkgram.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -4322,7 +4336,7 @@ yyreturn: /* Line 2048 of yacc.c */ -#line 1766 "awkgram.y" +#line 1780 "awkgram.y" struct token { @@ -973,6 +973,13 @@ regular_print: $2->opcode = Op_push_array; $2->memory = variable($2->source_line, arr, Node_var_new); + if (! do_posix && ! do_traditional) { + if ($2->memory == symbol_table) + fatal(_("`delete' is not allowed with SYMTAB")); + else if ($2->memory == func_table) + fatal(_("`delete' is not allowed with FUNCTAB")); + } + if ($4 == NULL) { /* * As of September 2012, POSIX has added support @@ -1014,6 +1021,13 @@ regular_print: $3->opcode = Op_push_array; $1->expr_count = 0; $$ = list_append(list_create($3), $1); + + if (! do_posix && ! do_traditional) { + if ($3->memory == symbol_table) + fatal(_("`delete' is not allowed with SYMTAB")); + else if ($3->memory == func_table) + fatal(_("`delete' is not allowed with FUNCTAB")); + } } | exp { $$ = optimize_assignment($1); } diff --git a/doc/ChangeLog b/doc/ChangeLog index 8d19b091..6f390aed 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -9,6 +9,10 @@ bug report from William Bresler <wbresler@acm.org>. Add a link to the ISO website. + * gawk.texi, gawk.1, awkcard.in: Document FUNCTAB, SYMTAB, and + PROCINFO["identifiers"]. Including that delete does not work + on FUNCTAB and SYMTAB. + 2012-09-23 Arnold D. Robbins <arnold@skeeve.com> * gawk.texi (Nextfile Statement): Document that it's now part of POSIX diff --git a/doc/awkcard.in b/doc/awkcard.in index 372d5587..9fae7cce 100644 --- a/doc/awkcard.in +++ b/doc/awkcard.in @@ -551,7 +551,8 @@ variables, each element being the value of that variable. T} \*(CB\*(FCERRNO\fP T{ -String describing the error if a +... String describing the error if a +String error value if a \*(FCgetline\*(FR redirection or read fails, or if @@ -580,6 +581,10 @@ T} Input field separator, a space by default (see \fHFields\fP above). T} +\*(CB\*(FCFUNCTAB\fP T{ +An array indexed by the names of all user-defined +and extension functions.\*(CD +T} \*(CB\*(FCIGNORECASE\fP T{ If non-zero, all regular expression and string operations ignore case. @@ -594,13 +599,13 @@ T} \*(CB\*(FCLINT\fP T{ Provides dynamic control of the \*(FC\-\^\-lint\fP option from within an AWK program. -When true, \*(GK -prints lint warnings. -When assigned the string value \*(FC"fatal"\*(FR, -lint warnings become fatal errors. -Any other true value just prints warnings.\*(CD +... When true, \*(GK +... prints lint warnings. +... When assigned the string value \*(FC"fatal"\*(FR, +... lint warnings become fatal errors. +... Any other true value just prints warnings. T} -\*(FCNF\fP T{ +\*(CD\*(FCNF\fP T{ Number of fields in the current input record. T} \*(FCNR\fP T{ @@ -650,6 +655,11 @@ Character(s) used to separate multiple subscripts in array elements, by default \*(FC"\e034"\*(FR. (See \fHArrays\fP below). T} +\*(CB\*(FCSYMTAB\fP T{ +An array indexed by the names of all global +variables and arrays. May be used to indirectly +set variable and array values.\*(CD +T} \*(CB\*(FCTEXTDOMAIN\fP T{ The internationalization text domain, for finding the localized @@ -14,7 +14,7 @@ . if \w'\(rq' .ds rq "\(rq . \} .\} -.TH GAWK 1 "Aug 09 2012" "Free Software Foundation" "Utility Commands" +.TH GAWK 1 "Oct 02 2012" "Free Software Foundation" "Utility Commands" .SH NAME gawk \- pattern scanning and processing language .SH SYNOPSIS @@ -989,6 +989,17 @@ The input field separator, a space by default. See .BR Fields , above. .TP +.B FUNCTAB +An array whose indices are the names of all the user-defined +or extension functions in the program. +.BR NOTE : +The array values cannot currently be used. +Also, you may not use the +.B delete +statment with the +.B FUNCTAB +array. +.TP .B IGNORECASE Controls the case-sensitivity of all regular expression and string operations. If @@ -1108,6 +1119,35 @@ or \fB"FIELDWIDTHS"\fP if field splitting with .B FIELDWIDTHS is in effect. .TP +\fBPROCINFO["identifiers"]\fP +A subarray, indexed by the names of all identifiers used in the +text of the AWK program. For each identifier, the value of the element is one of the following: +.RS +.TP +\fB"array"\fR +The identifier is an array. +.TP +\fB"extension"\fR +The identifier is an extension function loaded via +.BR @load . +.TP +\fB"scalar"\fR +The identifier is a scalar. +.TP +\fB"untyped"\fR +The identifier is untyped (could be used as a scalar or array, +.I gawk +doesn't know yet). +.TP +\fB"user"\fR +The identifier is a user-defined function. +.RE +The values indicate what +.I gawk +knows about the identifiers after it has finished parsing the program; they are +.I not +updated while the program runs. +.TP \fBPROCINFO["gid"]\fP the value of the .IR getgid (2) @@ -1236,6 +1276,30 @@ The length of the string matched by The character used to separate multiple subscripts in array elements, by default \fB"\e034"\fR. .TP +.B SYMTAB +An array whose indices are the names of all currently defined +global variables and arrays in the program. The array may be used +for indirect access to read or write the value of a variable: +.PP +.RS +.ft B +foo = 5 +SYMTAB["foo"] = 4 +print foo # prints 4 +.ft R +.RE +.PP +The +.B isarray() +function may be used to test if an element in +.B SYMTAB +is an array. +You may not use the +.B delete +statment with the +.B SYMTAB +array. +.TP .B TEXTDOMAIN The text domain of the \*(AK program; used to find the localized translations for the program's strings. diff --git a/doc/gawk.info b/doc/gawk.info index 1a28ab52..08fbc297 100644 --- a/doc/gawk.info +++ b/doc/gawk.info @@ -9602,6 +9602,12 @@ with a pound sign (`#'). create or remove fields from the current record. *Note Changing Fields::. +`FUNCTAB #' + An array whose indices are the names of all the user-defined or + extension functions in the program. *NOTE*: The array values + cannot currently be used. Also, you may not use the `delete' + statement with the `FUNCTAB' array. + `NR' The number of input records `awk' has processed since the beginning of the program's execution (*note Records::). `NR' is @@ -9624,6 +9630,32 @@ with a pound sign (`#'). effect, or `"FPAT"' if field matching with `FPAT' is in effect. + `PROCINFO["identifiers"]' + A subarray, indexed by the names of all identifiers used in + the text of the AWK program. For each identifier, the value + of the element is one of the following: + + `"array"' + The identifier is an array. + + `"extension"' + The identifier is an extension function loaded via + `@load'. + + `"scalar"' + The identifier is a scalar. + + `"untyped"' + The identifier is untyped (could be used as a scalar or + array, `gawk' doesn't know yet). + + `"user"' + The identifier is a user-defined function. + + The values indicate what `gawk' knows about the identifiers + after it has finished parsing the program; they are _not_ + updated while the program runs. + `PROCINFO["gid"]' The value of the `getgid()' system call. @@ -9705,6 +9737,23 @@ with a pound sign (`#'). implementations, or if `gawk' is in compatibility mode (*note Options::), it is not special. +`SYMTAB #' + An array whose indices are the names of all currently defined + global variables and arrays in the program. The array may be used + for indirect access to read or write the value of a variable: + + foo = 5 + SYMTAB["foo"] = 4 + print foo # prints 4 + + The `isarray()' function (*note Type Functions::) may be used to + test if an element in `SYMTAB' is an array. Also, you may not use + the `delete' statement with the `SYMTAB' array. + + NOTE: In order to avoid severe time-travel paradoxes(2), + neither `FUNCTAB' nor `SYMTAB' are available as elements + within the `SYMTAB' array. + Advanced Notes: Changing `NR' and `FNR' --------------------------------------- @@ -9734,6 +9783,8 @@ file by resetting `NR' to zero when `FILENAME' changed. to `"-"', even if there were data files to be processed. This behavior was incorrect and should not be relied upon in your programs. + (2) Not to mention difficult implementation issues. + File: gawk.info, Node: ARGC and ARGV, Prev: Auto-set, Up: Built-in Variables @@ -25971,7 +26022,7 @@ Index (line 67) * advanced features, data files as single record: Records. (line 180) * advanced features, fixed-width data: Constant Size. (line 9) -* advanced features, FNR/NR variables: Auto-set. (line 225) +* advanced features, FNR/NR variables: Auto-set. (line 274) * advanced features, gawk: Advanced Features. (line 6) * advanced features, gawk, network programming: TCP/IP Networking. (line 6) @@ -26476,7 +26527,7 @@ Index (line 47) * dark corner, FILENAME variable <1>: Auto-set. (line 93) * dark corner, FILENAME variable: Getline Notes. (line 19) -* dark corner, FNR/NR variables: Auto-set. (line 225) +* dark corner, FNR/NR variables: Auto-set. (line 274) * dark corner, format-control characters: Control Letters. (line 18) * dark corner, FS as null string: Single Character Fields. (line 20) @@ -26646,6 +26697,7 @@ Index * differences in awk and gawk, FIELDWIDTHS variable: User-modified. (line 35) * differences in awk and gawk, FPAT variable: User-modified. (line 45) +* differences in awk and gawk, FUNCTAB variable: Auto-set. (line 119) * differences in awk and gawk, function arguments (gawk): Calling Built-in. (line 16) * differences in awk and gawk, getline command: Getline. (line 19) @@ -26670,14 +26722,14 @@ Index (line 6) * differences in awk and gawk, print/printf statements: Format Modifiers. (line 13) -* differences in awk and gawk, PROCINFO array: Auto-set. (line 124) +* differences in awk and gawk, PROCINFO array: Auto-set. (line 130) * differences in awk and gawk, record separators: Records. (line 117) * differences in awk and gawk, regexp constants: Using Constant Regexps. (line 43) * differences in awk and gawk, regular expressions: Case-sensitivity. (line 26) * differences in awk and gawk, RS/RT variables: Records. (line 172) -* differences in awk and gawk, RT variable: Auto-set. (line 214) +* differences in awk and gawk, RT variable: Auto-set. (line 246) * differences in awk and gawk, single-character fields: Single Character Fields. (line 6) * differences in awk and gawk, split() function: String Functions. @@ -26686,6 +26738,7 @@ Index * differences in awk and gawk, strings, storing: Records. (line 192) * differences in awk and gawk, strtonum() function (gawk): String Functions. (line 404) +* differences in awk and gawk, SYMTAB variable: Auto-set. (line 254) * differences in awk and gawk, TEXTDOMAIN variable: User-modified. (line 162) * differences in awk and gawk, trunc-mod operation: Arithmetic Ops. @@ -26956,7 +27009,7 @@ Index * floating-point, numbers: General Arithmetic. (line 6) * FNR variable <1>: Auto-set. (line 103) * FNR variable: Records. (line 6) -* FNR variable, changing: Auto-set. (line 225) +* FNR variable, changing: Auto-set. (line 274) * for statement: For Statement. (line 6) * for statement, in arrays: Scanning an Array. (line 20) * format specifiers, mixing regular with positional specifiers: Printf Ordering. @@ -26999,6 +27052,7 @@ Index * FSF (Free Software Foundation) <1>: Glossary. (line 301) * FSF (Free Software Foundation) <2>: Getting. (line 10) * FSF (Free Software Foundation): Manual History. (line 6) +* FUNCTAB array: Auto-set. (line 119) * function calls: Function Calls. (line 6) * function calls, indirect: Indirect Calls. (line 6) * function pointers: Indirect Calls. (line 6) @@ -27086,6 +27140,7 @@ Index * gawk, FPAT variable in <1>: User-modified. (line 45) * gawk, FPAT variable in: Splitting By Content. (line 26) +* gawk, FUNCTAB array in: Auto-set. (line 119) * gawk, function arguments and: Calling Built-in. (line 16) * gawk, functions, adding: Dynamic Extensions. (line 9) * gawk, hexadecimal numbers and: Nondecimal-numbers. (line 42) @@ -27117,7 +27172,7 @@ Index * gawk, OS/2 version of: PC Using. (line 11) * gawk, PROCINFO array in <1>: Two-way I/O. (line 116) * gawk, PROCINFO array in <2>: Time Functions. (line 46) -* gawk, PROCINFO array in: Auto-set. (line 124) +* gawk, PROCINFO array in: Auto-set. (line 130) * gawk, regexp constants and: Using Constant Regexps. (line 28) * gawk, regular expressions, case sensitivity: Case-sensitivity. @@ -27125,7 +27180,7 @@ Index * gawk, regular expressions, operators: GNU Regexp Operators. (line 6) * gawk, regular expressions, precedence: Regexp Operators. (line 161) -* gawk, RT variable in <1>: Auto-set. (line 214) +* gawk, RT variable in <1>: Auto-set. (line 246) * gawk, RT variable in <2>: Getline/Variable/File. (line 10) * gawk, RT variable in <3>: Multiple Line. (line 129) @@ -27134,6 +27189,7 @@ Index * gawk, source code, obtaining: Getting. (line 6) * gawk, splitting fields and: Constant Size. (line 87) * gawk, string-translation functions: I18N Functions. (line 6) +* gawk, SYMTAB array in: Auto-set. (line 254) * gawk, TEXTDOMAIN variable in: User-modified. (line 162) * gawk, timestamps: Time Functions. (line 6) * gawk, uses for: Preface. (line 36) @@ -27536,9 +27592,9 @@ Index (line 49) * noassign.awk program: Ignoring Assigns. (line 15) * not Boolean-logic operator: Boolean Ops. (line 6) -* NR variable <1>: Auto-set. (line 119) +* NR variable <1>: Auto-set. (line 125) * NR variable: Records. (line 6) -* NR variable, changing: Auto-set. (line 225) +* NR variable, changing: Auto-set. (line 274) * null strings <1>: Basic Data Typing. (line 26) * null strings <2>: Truth Values. (line 6) * null strings <3>: Regexp Field Splitting. @@ -27821,7 +27877,7 @@ Index * PROCINFO array <3>: Passwd Functions. (line 6) * PROCINFO array <4>: Two-way I/O. (line 116) * PROCINFO array <5>: Time Functions. (line 46) -* PROCINFO array <6>: Auto-set. (line 124) +* PROCINFO array <6>: Auto-set. (line 130) * PROCINFO array: Obsolete. (line 11) * profiling awk programs: Profiling. (line 6) * profiling awk programs, dynamically: Profiling. (line 171) @@ -27963,7 +28019,7 @@ Index * right angle bracket (>), >> operator (I/O): Redirection. (line 50) * right shift, bitwise: Bitwise Functions. (line 32) * Ritchie, Dennis: Basic Data Typing. (line 55) -* RLENGTH variable: Auto-set. (line 201) +* RLENGTH variable: Auto-set. (line 233) * RLENGTH variable, match() function and: String Functions. (line 223) * Robbins, Arnold <1>: Future Extensions. (line 6) * Robbins, Arnold <2>: Bugs. (line 32) @@ -27990,9 +28046,9 @@ Index * RS variable: Records. (line 20) * RS variable, multiline records and: Multiple Line. (line 17) * rshift() function (gawk): Bitwise Functions. (line 52) -* RSTART variable: Auto-set. (line 207) +* RSTART variable: Auto-set. (line 239) * RSTART variable, match() function and: String Functions. (line 223) -* RT variable <1>: Auto-set. (line 214) +* RT variable <1>: Auto-set. (line 246) * RT variable <2>: Getline/Variable/File. (line 10) * RT variable <3>: Multiple Line. (line 129) @@ -28184,6 +28240,7 @@ Index * substr() function: String Functions. (line 481) * Sumner, Andrew: Other Versions. (line 55) * switch statement: Switch Statement. (line 6) +* SYMTAB array: Auto-set. (line 254) * syntactic ambiguity: /= operator vs. /=.../ regexp constant: Assignment Ops. (line 148) * system() function: I/O Functions. (line 63) @@ -28617,264 +28674,265 @@ Node: Built-in Variables393879 Node: User-modified394974 Ref: User-modified-Footnote-1403329 Node: Auto-set403391 -Ref: Auto-set-Footnote-1413299 -Node: ARGC and ARGV413504 -Node: Arrays417355 -Node: Array Basics418860 -Node: Array Intro419686 -Node: Reference to Elements424004 -Node: Assigning Elements426274 -Node: Array Example426765 -Node: Scanning an Array428497 -Node: Controlling Scanning430811 -Ref: Controlling Scanning-Footnote-1435744 -Node: Delete436060 -Ref: Delete-Footnote-1438825 -Node: Numeric Array Subscripts438882 -Node: Uninitialized Subscripts441065 -Node: Multi-dimensional442693 -Node: Multi-scanning445787 -Node: Arrays of Arrays447378 -Node: Functions452023 -Node: Built-in452845 -Node: Calling Built-in453923 -Node: Numeric Functions455911 -Ref: Numeric Functions-Footnote-1459743 -Ref: Numeric Functions-Footnote-2460100 -Ref: Numeric Functions-Footnote-3460148 -Node: String Functions460417 -Ref: String Functions-Footnote-1483914 -Ref: String Functions-Footnote-2484043 -Ref: String Functions-Footnote-3484291 -Node: Gory Details484378 -Ref: table-sub-escapes486057 -Ref: table-sub-posix-92487411 -Ref: table-sub-proposed488754 -Ref: table-posix-sub490104 -Ref: table-gensub-escapes491650 -Ref: Gory Details-Footnote-1492857 -Ref: Gory Details-Footnote-2492908 -Node: I/O Functions493059 -Ref: I/O Functions-Footnote-1499714 -Node: Time Functions499861 -Ref: Time Functions-Footnote-1510753 -Ref: Time Functions-Footnote-2510821 -Ref: Time Functions-Footnote-3510979 -Ref: Time Functions-Footnote-4511090 -Ref: Time Functions-Footnote-5511202 -Ref: Time Functions-Footnote-6511429 -Node: Bitwise Functions511695 -Ref: table-bitwise-ops512253 -Ref: Bitwise Functions-Footnote-1516474 -Node: Type Functions516658 -Node: I18N Functions517128 -Node: User-defined518755 -Node: Definition Syntax519559 -Ref: Definition Syntax-Footnote-1524469 -Node: Function Example524538 -Node: Function Caveats527132 -Node: Calling A Function527553 -Node: Variable Scope528668 -Node: Pass By Value/Reference530643 -Node: Return Statement534083 -Node: Dynamic Typing537064 -Node: Indirect Calls537799 -Node: Internationalization547484 -Node: I18N and L10N548910 -Node: Explaining gettext549596 -Ref: Explaining gettext-Footnote-1554662 -Ref: Explaining gettext-Footnote-2554846 -Node: Programmer i18n555011 -Node: Translator i18n559211 -Node: String Extraction560004 -Ref: String Extraction-Footnote-1560965 -Node: Printf Ordering561051 -Ref: Printf Ordering-Footnote-1563835 -Node: I18N Portability563899 -Ref: I18N Portability-Footnote-1566348 -Node: I18N Example566411 -Ref: I18N Example-Footnote-1569046 -Node: Gawk I18N569118 -Node: Advanced Features569735 -Node: Nondecimal Data571248 -Node: Array Sorting572831 -Node: Controlling Array Traversal573528 -Node: Array Sorting Functions581766 -Ref: Array Sorting Functions-Footnote-1585440 -Ref: Array Sorting Functions-Footnote-2585533 -Node: Two-way I/O585727 -Ref: Two-way I/O-Footnote-1591159 -Node: TCP/IP Networking591229 -Node: Profiling594073 -Node: Library Functions601527 -Ref: Library Functions-Footnote-1604534 -Node: Library Names604705 -Ref: Library Names-Footnote-1608176 -Ref: Library Names-Footnote-2608396 -Node: General Functions608482 -Node: Strtonum Function609435 -Node: Assert Function612365 -Node: Round Function615691 -Node: Cliff Random Function617234 -Node: Ordinal Functions618250 -Ref: Ordinal Functions-Footnote-1621320 -Ref: Ordinal Functions-Footnote-2621572 -Node: Join Function621781 -Ref: Join Function-Footnote-1623552 -Node: Getlocaltime Function623752 -Node: Data File Management627467 -Node: Filetrans Function628099 -Node: Rewind Function632238 -Node: File Checking633625 -Node: Empty Files634719 -Node: Ignoring Assigns636949 -Node: Getopt Function638502 -Ref: Getopt Function-Footnote-1649806 -Node: Passwd Functions650009 -Ref: Passwd Functions-Footnote-1658984 -Node: Group Functions659072 -Node: Walking Arrays667156 -Node: Sample Programs668725 -Node: Running Examples669390 -Node: Clones670118 -Node: Cut Program671342 -Node: Egrep Program681187 -Ref: Egrep Program-Footnote-1688960 -Node: Id Program689070 -Node: Split Program692686 -Ref: Split Program-Footnote-1696205 -Node: Tee Program696333 -Node: Uniq Program699136 -Node: Wc Program706565 -Ref: Wc Program-Footnote-1710831 -Ref: Wc Program-Footnote-2711031 -Node: Miscellaneous Programs711123 -Node: Dupword Program712311 -Node: Alarm Program714342 -Node: Translate Program719091 -Ref: Translate Program-Footnote-1723478 -Ref: Translate Program-Footnote-2723706 -Node: Labels Program723840 -Ref: Labels Program-Footnote-1727211 -Node: Word Sorting727295 -Node: History Sorting731179 -Node: Extract Program733018 -Ref: Extract Program-Footnote-1740501 -Node: Simple Sed740629 -Node: Igawk Program743691 -Ref: Igawk Program-Footnote-1758848 -Ref: Igawk Program-Footnote-2759049 -Node: Anagram Program759187 -Node: Signature Program762255 -Node: Debugger763355 -Node: Debugging764321 -Node: Debugging Concepts764754 -Node: Debugging Terms766610 -Node: Awk Debugging769207 -Node: Sample Debugging Session770099 -Node: Debugger Invocation770619 -Node: Finding The Bug771948 -Node: List of Debugger Commands778436 -Node: Breakpoint Control779770 -Node: Debugger Execution Control783434 -Node: Viewing And Changing Data786794 -Node: Execution Stack790150 -Node: Debugger Info791617 -Node: Miscellaneous Debugger Commands795598 -Node: Readline Support801043 -Node: Limitations801874 -Node: Arbitrary Precision Arithmetic804126 -Ref: Arbitrary Precision Arithmetic-Footnote-1805768 -Node: General Arithmetic805916 -Node: Floating Point Issues807636 -Node: String Conversion Precision808517 -Ref: String Conversion Precision-Footnote-1810223 -Node: Unexpected Results810332 -Node: POSIX Floating Point Problems812485 -Ref: POSIX Floating Point Problems-Footnote-1816310 -Node: Integer Programming816348 -Node: Floating-point Programming818101 -Ref: Floating-point Programming-Footnote-1824410 -Node: Floating-point Representation824674 -Node: Floating-point Context825839 -Ref: table-ieee-formats826681 -Node: Rounding Mode828065 -Ref: table-rounding-modes828544 -Ref: Rounding Mode-Footnote-1831548 -Node: Gawk and MPFR831729 -Node: Arbitrary Precision Floats832971 -Ref: Arbitrary Precision Floats-Footnote-1835400 -Node: Setting Precision835711 -Node: Setting Rounding Mode838444 -Ref: table-gawk-rounding-modes838848 -Node: Floating-point Constants840028 -Node: Changing Precision841452 -Ref: Changing Precision-Footnote-1842852 -Node: Exact Arithmetic843026 -Node: Arbitrary Precision Integers846134 -Ref: Arbitrary Precision Integers-Footnote-1849134 -Node: Dynamic Extensions849281 -Node: Plugin License850199 -Node: Sample Library850813 -Node: Internal File Description851497 -Node: Internal File Ops855210 -Ref: Internal File Ops-Footnote-1859773 -Node: Using Internal File Ops859913 -Node: Language History862289 -Node: V7/SVR3.1863811 -Node: SVR4866132 -Node: POSIX867574 -Node: BTL868582 -Node: POSIX/GNU869316 -Node: Common Extensions874851 -Node: Ranges and Locales875958 -Ref: Ranges and Locales-Footnote-1880576 -Ref: Ranges and Locales-Footnote-2880603 -Ref: Ranges and Locales-Footnote-3880863 -Node: Contributors881084 -Node: Installation885380 -Node: Gawk Distribution886274 -Node: Getting886758 -Node: Extracting887584 -Node: Distribution contents889276 -Node: Unix Installation894498 -Node: Quick Installation895115 -Node: Additional Configuration Options897077 -Node: Configuration Philosophy898554 -Node: Non-Unix Installation900896 -Node: PC Installation901354 -Node: PC Binary Installation902653 -Node: PC Compiling904501 -Node: PC Testing907445 -Node: PC Using908621 -Node: Cygwin912806 -Node: MSYS913806 -Node: VMS Installation914320 -Node: VMS Compilation914923 -Ref: VMS Compilation-Footnote-1915930 -Node: VMS Installation Details915988 -Node: VMS Running917623 -Node: VMS Old Gawk919230 -Node: Bugs919704 -Node: Other Versions923556 -Node: Notes928871 -Node: Compatibility Mode929458 -Node: Additions930241 -Node: Accessing The Source931168 -Node: Adding Code932594 -Node: New Ports938636 -Node: Derived Files942771 -Ref: Derived Files-Footnote-1948076 -Ref: Derived Files-Footnote-2948110 -Ref: Derived Files-Footnote-3948710 -Node: Future Extensions948808 -Node: Basic Concepts950295 -Node: Basic High Level950976 -Ref: Basic High Level-Footnote-1955011 -Node: Basic Data Typing955196 -Node: Glossary958551 -Node: Copying983726 -Node: GNU Free Documentation License1021283 -Node: Index1046420 +Ref: Auto-set-Footnote-1415085 +Ref: Auto-set-Footnote-2415290 +Node: ARGC and ARGV415346 +Node: Arrays419197 +Node: Array Basics420702 +Node: Array Intro421528 +Node: Reference to Elements425846 +Node: Assigning Elements428116 +Node: Array Example428607 +Node: Scanning an Array430339 +Node: Controlling Scanning432653 +Ref: Controlling Scanning-Footnote-1437586 +Node: Delete437902 +Ref: Delete-Footnote-1440667 +Node: Numeric Array Subscripts440724 +Node: Uninitialized Subscripts442907 +Node: Multi-dimensional444535 +Node: Multi-scanning447629 +Node: Arrays of Arrays449220 +Node: Functions453865 +Node: Built-in454687 +Node: Calling Built-in455765 +Node: Numeric Functions457753 +Ref: Numeric Functions-Footnote-1461585 +Ref: Numeric Functions-Footnote-2461942 +Ref: Numeric Functions-Footnote-3461990 +Node: String Functions462259 +Ref: String Functions-Footnote-1485756 +Ref: String Functions-Footnote-2485885 +Ref: String Functions-Footnote-3486133 +Node: Gory Details486220 +Ref: table-sub-escapes487899 +Ref: table-sub-posix-92489253 +Ref: table-sub-proposed490596 +Ref: table-posix-sub491946 +Ref: table-gensub-escapes493492 +Ref: Gory Details-Footnote-1494699 +Ref: Gory Details-Footnote-2494750 +Node: I/O Functions494901 +Ref: I/O Functions-Footnote-1501556 +Node: Time Functions501703 +Ref: Time Functions-Footnote-1512595 +Ref: Time Functions-Footnote-2512663 +Ref: Time Functions-Footnote-3512821 +Ref: Time Functions-Footnote-4512932 +Ref: Time Functions-Footnote-5513044 +Ref: Time Functions-Footnote-6513271 +Node: Bitwise Functions513537 +Ref: table-bitwise-ops514095 +Ref: Bitwise Functions-Footnote-1518316 +Node: Type Functions518500 +Node: I18N Functions518970 +Node: User-defined520597 +Node: Definition Syntax521401 +Ref: Definition Syntax-Footnote-1526311 +Node: Function Example526380 +Node: Function Caveats528974 +Node: Calling A Function529395 +Node: Variable Scope530510 +Node: Pass By Value/Reference532485 +Node: Return Statement535925 +Node: Dynamic Typing538906 +Node: Indirect Calls539641 +Node: Internationalization549326 +Node: I18N and L10N550752 +Node: Explaining gettext551438 +Ref: Explaining gettext-Footnote-1556504 +Ref: Explaining gettext-Footnote-2556688 +Node: Programmer i18n556853 +Node: Translator i18n561053 +Node: String Extraction561846 +Ref: String Extraction-Footnote-1562807 +Node: Printf Ordering562893 +Ref: Printf Ordering-Footnote-1565677 +Node: I18N Portability565741 +Ref: I18N Portability-Footnote-1568190 +Node: I18N Example568253 +Ref: I18N Example-Footnote-1570888 +Node: Gawk I18N570960 +Node: Advanced Features571577 +Node: Nondecimal Data573090 +Node: Array Sorting574673 +Node: Controlling Array Traversal575370 +Node: Array Sorting Functions583608 +Ref: Array Sorting Functions-Footnote-1587282 +Ref: Array Sorting Functions-Footnote-2587375 +Node: Two-way I/O587569 +Ref: Two-way I/O-Footnote-1593001 +Node: TCP/IP Networking593071 +Node: Profiling595915 +Node: Library Functions603369 +Ref: Library Functions-Footnote-1606376 +Node: Library Names606547 +Ref: Library Names-Footnote-1610018 +Ref: Library Names-Footnote-2610238 +Node: General Functions610324 +Node: Strtonum Function611277 +Node: Assert Function614207 +Node: Round Function617533 +Node: Cliff Random Function619076 +Node: Ordinal Functions620092 +Ref: Ordinal Functions-Footnote-1623162 +Ref: Ordinal Functions-Footnote-2623414 +Node: Join Function623623 +Ref: Join Function-Footnote-1625394 +Node: Getlocaltime Function625594 +Node: Data File Management629309 +Node: Filetrans Function629941 +Node: Rewind Function634080 +Node: File Checking635467 +Node: Empty Files636561 +Node: Ignoring Assigns638791 +Node: Getopt Function640344 +Ref: Getopt Function-Footnote-1651648 +Node: Passwd Functions651851 +Ref: Passwd Functions-Footnote-1660826 +Node: Group Functions660914 +Node: Walking Arrays668998 +Node: Sample Programs670567 +Node: Running Examples671232 +Node: Clones671960 +Node: Cut Program673184 +Node: Egrep Program683029 +Ref: Egrep Program-Footnote-1690802 +Node: Id Program690912 +Node: Split Program694528 +Ref: Split Program-Footnote-1698047 +Node: Tee Program698175 +Node: Uniq Program700978 +Node: Wc Program708407 +Ref: Wc Program-Footnote-1712673 +Ref: Wc Program-Footnote-2712873 +Node: Miscellaneous Programs712965 +Node: Dupword Program714153 +Node: Alarm Program716184 +Node: Translate Program720933 +Ref: Translate Program-Footnote-1725320 +Ref: Translate Program-Footnote-2725548 +Node: Labels Program725682 +Ref: Labels Program-Footnote-1729053 +Node: Word Sorting729137 +Node: History Sorting733021 +Node: Extract Program734860 +Ref: Extract Program-Footnote-1742343 +Node: Simple Sed742471 +Node: Igawk Program745533 +Ref: Igawk Program-Footnote-1760690 +Ref: Igawk Program-Footnote-2760891 +Node: Anagram Program761029 +Node: Signature Program764097 +Node: Debugger765197 +Node: Debugging766163 +Node: Debugging Concepts766596 +Node: Debugging Terms768452 +Node: Awk Debugging771049 +Node: Sample Debugging Session771941 +Node: Debugger Invocation772461 +Node: Finding The Bug773790 +Node: List of Debugger Commands780278 +Node: Breakpoint Control781612 +Node: Debugger Execution Control785276 +Node: Viewing And Changing Data788636 +Node: Execution Stack791992 +Node: Debugger Info793459 +Node: Miscellaneous Debugger Commands797440 +Node: Readline Support802885 +Node: Limitations803716 +Node: Arbitrary Precision Arithmetic805968 +Ref: Arbitrary Precision Arithmetic-Footnote-1807610 +Node: General Arithmetic807758 +Node: Floating Point Issues809478 +Node: String Conversion Precision810359 +Ref: String Conversion Precision-Footnote-1812065 +Node: Unexpected Results812174 +Node: POSIX Floating Point Problems814327 +Ref: POSIX Floating Point Problems-Footnote-1818152 +Node: Integer Programming818190 +Node: Floating-point Programming819943 +Ref: Floating-point Programming-Footnote-1826252 +Node: Floating-point Representation826516 +Node: Floating-point Context827681 +Ref: table-ieee-formats828523 +Node: Rounding Mode829907 +Ref: table-rounding-modes830386 +Ref: Rounding Mode-Footnote-1833390 +Node: Gawk and MPFR833571 +Node: Arbitrary Precision Floats834813 +Ref: Arbitrary Precision Floats-Footnote-1837242 +Node: Setting Precision837553 +Node: Setting Rounding Mode840286 +Ref: table-gawk-rounding-modes840690 +Node: Floating-point Constants841870 +Node: Changing Precision843294 +Ref: Changing Precision-Footnote-1844694 +Node: Exact Arithmetic844868 +Node: Arbitrary Precision Integers847976 +Ref: Arbitrary Precision Integers-Footnote-1850976 +Node: Dynamic Extensions851123 +Node: Plugin License852041 +Node: Sample Library852655 +Node: Internal File Description853339 +Node: Internal File Ops857052 +Ref: Internal File Ops-Footnote-1861615 +Node: Using Internal File Ops861755 +Node: Language History864131 +Node: V7/SVR3.1865653 +Node: SVR4867974 +Node: POSIX869416 +Node: BTL870424 +Node: POSIX/GNU871158 +Node: Common Extensions876693 +Node: Ranges and Locales877800 +Ref: Ranges and Locales-Footnote-1882418 +Ref: Ranges and Locales-Footnote-2882445 +Ref: Ranges and Locales-Footnote-3882705 +Node: Contributors882926 +Node: Installation887222 +Node: Gawk Distribution888116 +Node: Getting888600 +Node: Extracting889426 +Node: Distribution contents891118 +Node: Unix Installation896340 +Node: Quick Installation896957 +Node: Additional Configuration Options898919 +Node: Configuration Philosophy900396 +Node: Non-Unix Installation902738 +Node: PC Installation903196 +Node: PC Binary Installation904495 +Node: PC Compiling906343 +Node: PC Testing909287 +Node: PC Using910463 +Node: Cygwin914648 +Node: MSYS915648 +Node: VMS Installation916162 +Node: VMS Compilation916765 +Ref: VMS Compilation-Footnote-1917772 +Node: VMS Installation Details917830 +Node: VMS Running919465 +Node: VMS Old Gawk921072 +Node: Bugs921546 +Node: Other Versions925398 +Node: Notes930713 +Node: Compatibility Mode931300 +Node: Additions932083 +Node: Accessing The Source933010 +Node: Adding Code934436 +Node: New Ports940478 +Node: Derived Files944613 +Ref: Derived Files-Footnote-1949918 +Ref: Derived Files-Footnote-2949952 +Ref: Derived Files-Footnote-3950552 +Node: Future Extensions950650 +Node: Basic Concepts952137 +Node: Basic High Level952818 +Ref: Basic High Level-Footnote-1956853 +Node: Basic Data Typing957038 +Node: Glossary960393 +Node: Copying985568 +Node: GNU Free Documentation License1023125 +Node: Index1048262 End Tag Table diff --git a/doc/gawk.texi b/doc/gawk.texi index 2a55b978..f0378b30 100644 --- a/doc/gawk.texi +++ b/doc/gawk.texi @@ -13015,6 +13015,16 @@ assigning a value to @code{NF} has the potential to affect to @code{NF} can be used to create or remove fields from the current record. @xref{Changing Fields}. +@cindex @code{FUNCTAB} array +@cindex @command{gawk}, @code{FUNCTAB} array in +@cindex differences in @command{awk} and @command{gawk}, @code{FUNCTAB} variable +@item FUNCTAB # +An array whose indices are the names of all the user-defined +or extension functions in the program. +@strong{NOTE}: The array values cannot currently be used. +Also, you may not use the @code{delete} statement with the +@code{FUNCTAB} array. + @cindex @code{NR} variable @item NR The number of input records @command{awk} has processed since @@ -13044,6 +13054,34 @@ This is @code{"FIELDWIDTHS"} if field splitting with @code{FIELDWIDTHS} is in effect, or @code{"FPAT"} if field matching with @code{FPAT} is in effect. +@item PROCINFO["identifiers"] +A subarray, indexed by the names of all identifiers used in the +text of the AWK program. For each identifier, the value of the element is one of the following: + +@table @code +@item "array" +The identifier is an array. + +@item "extension" +The identifier is an extension function loaded via +@code{@@load}. + +@item "scalar" +The identifier is a scalar. + +@item "untyped" +The identifier is untyped (could be used as a scalar or array, +@command{gawk} doesn't know yet). + +@item "user" +The identifier is a user-defined function. +@end table + +@noindent +The values indicate what @command{gawk} knows about the identifiers +after it has finished parsing the program; they are @emph{not} updated +while the program runs. + @item PROCINFO["gid"] The value of the @code{getgid()} system call. @@ -13142,6 +13180,32 @@ In other @command{awk} implementations, or if @command{gawk} is in compatibility mode (@pxref{Options}), it is not special. + +@cindex @command{gawk}, @code{SYMTAB} array in +@cindex @code{SYMTAB} array +@cindex differences in @command{awk} and @command{gawk}, @code{SYMTAB} variable +@item SYMTAB # +An array whose indices are the names of all currently defined +global variables and arrays in the program. The array may be used +for indirect access to read or write the value of a variable: + +@example +foo = 5 +SYMTAB["foo"] = 4 +print foo # prints 4 +@end example + +@noindent +The @code{isarray()} function (@pxref{Type Functions}) may be used to test +if an element in @code{SYMTAB} is an array. +Also, you may not use the @code{delete} statement with the +@code{SYMTAB} array. + +@quotation NOTE +In order to avoid severe time-travel paradoxes@footnote{Not to mention difficult +implementation issues.}, neither @code{FUNCTAB} nor @code{SYMTAB} +are available as elements within the @code{SYMTAB} array. +@end quotation @end table @c ENDOFRANGE bvconi @c ENDOFRANGE vbconi @@ -243,7 +243,6 @@ static const char *const nodetypes[] = { "Node_param_list", "Node_func", "Node_ext_func", - "Node_hashnode", "Node_array_ref", "Node_array_tree", "Node_array_leaf", diff --git a/interpret.h b/interpret.h index c7380bd4..ab6c9b33 100644 --- a/interpret.h +++ b/interpret.h @@ -210,8 +210,32 @@ top: lintwarn(_("subscript of array `%s' is null string"), array_vname(t1)); } - r = *assoc_lookup(t1, t2); + /* for FUNCTAB, get the name as the element value */ + if (t1 == func_table) { + static bool warned = false; + + if (do_lint && ! warned) { + warned = true; + lintwarn(_("FUNCTAB is a gawk extension")); + } + r = t2; + } else { + r = *assoc_lookup(t1, t2); + } DEREF(t2); + + /* for SYMTAB, step through to the actual variable */ + if (t1 == symbol_table) { + static bool warned = false; + + if (do_lint && ! warned) { + warned = true; + lintwarn(_("SYMTAB is a gawk extension")); + } + if (r->type == Node_var) + r = r->var_value; + } + if (r->type == Node_val) UPREF(r); PUSH(r); @@ -531,6 +555,12 @@ mod: array_vname(t1), (int) t2->stlen, t2->stptr); } DEREF(t2); + + if (t1 == func_table) + fatal(_("cannot assign to elements of FUNCTAB")); + else if (t1 == symbol_table && (*lhs)->type == Node_var) + lhs = & ((*lhs)->var_value); + unref(*lhs); *lhs = POP_SCALAR(); break; @@ -876,7 +906,10 @@ match_re: arg_count = (pc + 1)->expr_count; t1 = PEEK(arg_count); /* indirect var */ - assert(t1->type == Node_val); /* @a[1](p) not allowed in grammar */ + + if (t1->type != Node_val) /* @a[1](p) not allowed in grammar */ + fatal(_("indirect function call requires a simple scalar value")); + t1 = force_string(t1); if (t1->stlen > 0) { /* retrieve function definition node */ @@ -890,9 +923,13 @@ match_re: f = lookup(t1->stptr); } - if (f == NULL || f->type != Node_func) - fatal(_("function called indirectly through `%s' does not exist"), - pc->func_name); + if (f == NULL || f->type != Node_func) { + if (f->type == Node_ext_func) + fatal(_("cannot (yet) call extension functions indirectly")); + else + fatal(_("function called indirectly through `%s' does not exist"), + pc->func_name); + } pc->func_body = f; /* save for next call */ ni = setup_frame(pc); @@ -288,12 +288,18 @@ main(int argc, char **argv) if (argc < 2) usage(EXIT_FAILURE, stderr); + /* initialize the null string */ + Nnull_string = make_string("", 0); + /* Robustness: check that file descriptors 0, 1, 2 are open */ init_fds(); /* init array handling. */ array_init(); + /* init the symbol tables */ + init_symbol_table(); + output_fp = stdout; /* we do error messages ourselves on invalid options */ @@ -588,8 +594,6 @@ out: /* load group set */ init_groupset(); - /* initialize the null string */ - Nnull_string = make_string("", 0); #ifdef HAVE_MPFR if (do_mpfr) { mpz_init(Nnull_string->mpg_i); @@ -37,8 +37,9 @@ static NODE *pp_pop(void); static void pp_free(NODE *n); const char *redir2str(int redirtype); -#define pp_str hname -#define pp_len hlength +#define pp_str vname +#define pp_len sub.nodep.reserved +#define pp_next rnode #define DONT_FREE 1 #define CAN_FREE 2 @@ -135,7 +136,7 @@ pp_push(int type, char *s, int flag) n->pp_len = strlen(s); n->flags = flag; n->type = type; - n->hnext = pp_stack; + n->pp_next = pp_stack; pp_stack = n; } @@ -144,7 +145,7 @@ pp_pop() { NODE *n; n = pp_stack; - pp_stack = n->hnext; + pp_stack = n->pp_next; return n; } @@ -30,19 +30,44 @@ extern INSTRUCTION *rule_list; #define HASHSIZE 1021 -static NODE *variables[HASHSIZE]; static int func_count; /* total number of functions */ static int var_count; /* total number of global variables and functions */ static NODE *symbol_list; static void (*install_func)(NODE *) = NULL; static NODE *make_symbol(char *name, NODETYPE type); -static NODE *install(char *name, NODE *hp, NODETYPE type); +static NODE *install(char *name, NODE *parm, NODETYPE type); static void free_bcpool(INSTRUCTION *pl); static AWK_CONTEXT *curr_ctxt = NULL; static int ctxt_level; +static NODE *global_table, *param_table; +NODE *symbol_table, *func_table; + +/* Use a flag to avoid a strcmp() call inside install() */ +static bool installing_specials = false; + +/* init_symbol_table --- make sure the symbol tables are initialized */ + +void +init_symbol_table() +{ + getnode(global_table); + memset(global_table, '\0', sizeof(NODE)); + init_array(global_table); + + getnode(param_table); + memset(param_table, '\0', sizeof(NODE)); + init_array(param_table); + + installing_specials = true; + func_table = install_symbol(estrdup("FUNCTAB", 7), Node_var_array); + + symbol_table = install_symbol(estrdup("SYMTAB", 6), Node_var_array); + installing_specials = false; +} + /* * install_symbol: * Install a global name in the symbol table, even if it is already there. @@ -56,24 +81,45 @@ install_symbol(char *name, NODETYPE type) } -/* lookup --- find the most recent global or param node for name +/* + * lookup --- find the most recent global or param node for name * installed by install_symbol */ NODE * lookup(const char *name) { - NODE *hp; - size_t len; - int hash1; - - len = strlen(name); - hash1 = hash(name, len, (unsigned long) HASHSIZE, NULL); - for (hp = variables[hash1]; hp != NULL; hp = hp->hnext) { - if (hp->hlength == len && strncmp(hp->hname, name, len) == 0) - return hp->hvalue; + NODE *n; + NODE *tmp; + /* ``It's elephants, all the way down.'' */ + NODE *tables[] = { + param_table, /* parameters shadow everything */ + global_table, /* SYMTAB and FUNCTAB found first, can't be redefined */ + func_table, /* then functions */ + symbol_table, /* then globals */ + NULL, + }; + int i; + + tmp = make_string(name, strlen(name)); + + n = NULL; + for (i = 0; tables[i] != NULL; i++) { + if (tables[i]->table_size == 0) + continue; + + if ((do_posix || do_traditional) && tables[i] == global_table) + continue; + + n = in_array(tables[i], tmp); + if (n != NULL) { + unref(tmp); + return n; + } } - return NULL; + + unref(tmp); + return n; /* NULL */ } /* make_params --- allocate function parameters for the symbol table */ @@ -81,7 +127,7 @@ lookup(const char *name) NODE * make_params(char **pnames, int pcount) { - NODE *hp, *parms; + NODE *p, *parms; int i; if (pcount <= 0 || pnames == NULL) @@ -90,12 +136,10 @@ make_params(char **pnames, int pcount) emalloc(parms, NODE *, pcount * sizeof(NODE), "make_params"); memset(parms, '\0', pcount * sizeof(NODE)); - for (i = 0, hp = parms; i < pcount; i++, hp++) { - hp->type = Node_param_list; - hp->hname = pnames[i]; /* shadows pname and vname */ - hp->hlength = strlen(pnames[i]); - hp->param_cnt = i; - hp->hvalue = hp; /* points to itself */ + for (i = 0, p = parms; i < pcount; i++, p++) { + p->type = Node_param_list; + p->param = pnames[i]; /* shadows pname and vname */ + p->param_cnt = i; } return parms; @@ -117,7 +161,7 @@ install_params(NODE *func) ) return; for (i = 0; i < pcount; i++) - (void) install(NULL, parms + i, Node_param_list); + (void) install(parms[i].param, parms + i, Node_param_list); } @@ -128,8 +172,8 @@ install_params(NODE *func) void remove_params(NODE *func) { - NODE *parms, *p, *prev, *n; - int i, pcount, hash1; + NODE *parms, *p; + int i, pcount; if (func == NULL) return; @@ -140,22 +184,15 @@ remove_params(NODE *func) return; for (i = pcount - 1; i >= 0; i--) { + NODE *tmp; + p = parms + i; - hash1 = p->hcode; - if (hash1 < 0 || hash1 >= HASHSIZE) - continue; - for (prev = NULL, n = variables[hash1]; n != NULL; - prev = n, n = n->hnext) { - if (n == p) - break; - } - if (n == NULL) - continue; - if (prev == NULL) - variables[hash1] = n->hnext; /* param at the head of the chain */ - else - prev->hnext = n->hnext; /* param not at the head */ + tmp = make_string(p->vname, strlen(p->vname)); + (void) assoc_remove(param_table, tmp); + unref(tmp); } + + assoc_clear(param_table); /* shazzam! */ } @@ -164,33 +201,16 @@ remove_params(NODE *func) NODE * remove_symbol(NODE *r) { - NODE *prev, *hp; - int hash1; - - hash1 = hash(r->vname, strlen(r->vname), (unsigned long) HASHSIZE, NULL); - for (prev = NULL, hp = variables[hash1]; hp != NULL; - prev = hp, hp = hp->hnext) { - if (hp->hvalue == r) - break; - } + NODE *n = in_array(symbol_table, r); - if (hp == NULL) - return NULL; - assert(hp->hcode == hash1); - - if (prev == NULL) - variables[hash1] = hp->hnext; /* symbol at the head of chain */ - else - prev->hnext = hp->hnext; /* symbol not at the head */ - - if (r->type == Node_param_list) - return r; /* r == hp */ - if (r->type == Node_func) - func_count--; - if (r->type != Node_ext_func) - var_count--; - freenode(hp); - return r; + if (n == NULL) + return n; + + n = dupnode(n); + + (void) assoc_remove(symbol_table, r); + + return n; } @@ -248,46 +268,56 @@ destroy_symbol(NODE *r) static NODE * make_symbol(char *name, NODETYPE type) { - NODE *hp, *r; + NODE *r; - getnode(hp); - hp->type = Node_hashnode; - hp->hlength = strlen(name); - hp->hname = name; getnode(r); memset(r, '\0', sizeof(NODE)); - hp->hvalue = r; if (type == Node_var_array) init_array(r); else if (type == Node_var) r->var_value = dupnode(Nnull_string); r->vname = name; r->type = type; - return hp; + + return r; } /* install --- install a global name or function parameter in the symbol table */ static NODE * -install(char *name, NODE *hp, NODETYPE type) +install(char *name, NODE *parm, NODETYPE type) { - int hash1; NODE *r; + NODE **aptr; + NODE *table; + NODE *n_name; + + n_name = make_string(name, strlen(name)); + table = symbol_table; + + if (type == Node_param_list) { + table = param_table; + } else if (type == Node_func || type == Node_ext_func) { + table = func_table; + } else if (installing_specials) { + table = global_table; + } - if (hp == NULL) { + if (parm != NULL) { + r = parm; + } else { /* global symbol */ - hp = make_symbol(name, type); + r = make_symbol(name, type); if (type == Node_func) func_count++; - if (type != Node_ext_func) + if (type != Node_ext_func && table != global_table) var_count++; /* total, includes Node_func */ } - r = hp->hvalue; - hash1 = hash(hp->hname, hp->hlength, (unsigned long) HASHSIZE, NULL); - hp->hcode = hash1; - hp->hnext = variables[hash1]; - variables[hash1] = hp; + aptr = assoc_lookup(table, n_name); + unref(*aptr); + *aptr = r; + unref(n_name); if (install_func) (*install_func)(r); @@ -322,30 +352,33 @@ get_symbols(SYMBOL_TYPE what, int sort) { int i; NODE **table; - NODE *hp, *r; + NODE **list; + NODE *r; long j, count = 0; + long max; + NODE *the_table; - if (what == FUNCTION) + if (what == FUNCTION) { count = func_count; - else /* if (what == VARIABLE) */ + the_table = func_table; + } else { /* what == VARIABLE */ count = var_count; + the_table = symbol_table; + update_global_values(); + } emalloc(table, NODE **, (count + 1) * sizeof(NODE *), "symbol_list"); - if (what == VARIABLE) - update_global_values(); - for (i = j = 0; i < HASHSIZE; i++) - for (hp = variables[i]; hp != NULL; hp = hp->hnext) { - if (hp->type != Node_hashnode) - continue; - r = hp->hvalue; - if (r->type == Node_ext_func) - continue; - if (what == FUNCTION && r->type == Node_func) - table[j++] = r; - else if (what == VARIABLE) - table[j++] = r; - } + max = the_table->table_size * 2; + list = assoc_list(the_table, "@unsorted", ASORTI); + for (i = j = 0; i < max; i += 2) { + r = list[i+1]; + if (r->type == Node_ext_func) + continue; + if (what == VARIABLE || r->type == Node_func) + table[j++] = r; + } + efree(list); if (sort && count > 1) qsort(table, count, sizeof(NODE *), comp_symbol); /* Shazzam! */ @@ -417,25 +450,9 @@ foreach_func(NODE **table, int (*pfunc)(INSTRUCTION *, void *), void *data) void release_all_vars() { - int i; - NODE *hp, *r, *next; - - for (i = 0; i < HASHSIZE; i++) - for (hp = variables[i]; hp != NULL; hp = next) { - next = hp->hnext; - if (hp->type != Node_hashnode) - continue; - r = hp->hvalue; - if (r->type == Node_func || r->type == Node_ext_func) - continue; - if (r->type == Node_var_array) - assoc_clear(r); - else if (r->type == Node_var) - unref(r->var_value); - efree(r->vname); - freenode(r); - freenode(hp); - } + assoc_clear(symbol_table); + assoc_clear(func_table); + assoc_clear(global_table); } @@ -446,12 +463,12 @@ release_all_vars() void append_symbol(NODE *r) { - NODE *hp; + NODE *p; - getnode(hp); - hp->lnode = r; - hp->rnode = symbol_list->rnode; - symbol_list->rnode = hp; + getnode(p); + p->lnode = r; + p->rnode = symbol_list->rnode; + symbol_list->rnode = p; } /* release_symbol --- free symbol list and optionally remove symbol from symbol table */ @@ -459,17 +476,17 @@ append_symbol(NODE *r) void release_symbols(NODE *symlist, int keep_globals) { - NODE *hp, *next; + NODE *p, *next; - for (hp = symlist->rnode; hp != NULL; hp = next) { + for (p = symlist->rnode; p != NULL; p = next) { if (! keep_globals) { /* destroys globals, function, and params * if still in symbol table */ - destroy_symbol(hp->lnode); + destroy_symbol(p->lnode); } - next = hp->rnode; - freenode(hp); + next = p->rnode; + freenode(p); } symlist->rnode = NULL; } @@ -479,12 +496,19 @@ release_symbols(NODE *symlist, int keep_globals) void load_symbols() { - NODE *hp, *r; + NODE *r; NODE *tmp; NODE *sym_array; NODE **aptr; - long i; - NODE *user, *extension, *variable, *scalar,*array; + long i, j, max; + NODE *user, *extension, *untyped, *scalar, *array; + NODE **list; + NODE *tables[] = { + func_table, + symbol_table, + global_table, + NULL + }; if (PROCINFO_node == NULL) return; @@ -506,15 +530,16 @@ load_symbols() user = make_string("user", 4); extension = make_string("extension", 9); scalar = make_string("scalar", 6); - variable = make_string("variable", 8); + untyped = make_string("untyped", 7); array = make_string("array", 5); - for (i = 0; i < HASHSIZE; i++) { - for (hp = variables[i]; hp != NULL; hp = hp->hnext) { - if (hp->type != Node_hashnode) - continue; - - r = hp->hvalue; + for (i = 0; tables[i] != NULL; i++) { + list = assoc_list(tables[i], "@unsorted", ASORTI); + max = tables[i]->table_size * 2; + if (max == 0) + continue; + for (j = 0; j < max; j += 2) { + r = list[j+1]; if ( r->type == Node_ext_func || r->type == Node_func || r->type == Node_var @@ -538,7 +563,7 @@ load_symbols() *aptr = dupnode(array); break; case Node_var_new: - *aptr = dupnode(variable); + *aptr = dupnode(untyped); break; default: cant_happen(); @@ -546,12 +571,13 @@ load_symbols() } } } + efree(list); } unref(user); unref(extension); unref(scalar); - unref(variable); + unref(untyped); unref(array); } diff --git a/test/ChangeLog b/test/ChangeLog index 3f5a7bce..bd327f24 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -5,6 +5,13 @@ * Makefile.am (shlib-tests): config.h is in builddir. (beginfile2): So is gawk itself. + * Makefile.am (functab1, functab2, functab3, functab4, id, symtab1, + symtab2, symtab3): New tests. + * functab1.awk, functab1.ok, functab2.awk, functab2.ok, functab3.awk, + functab3.ok, functab4.awk, functab4.ok, id.awk, id.ok, symtab1.awk, + symtab1.ok, symtab2.awk, symtab2.ok, symtab3.awk, symtab3.ok: + New files. + 2012-09-23 Arnold D. Robbins <arnold@skeeve.com> * lintwarn.ok: Updated. diff --git a/test/Makefile.am b/test/Makefile.am index 135ddd80..c64e1e3b 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -47,8 +47,6 @@ EXTRA_DIST = \ anchgsub.awk \ anchgsub.in \ anchgsub.ok \ - arraysort.awk \ - arraysort.ok \ argarray.awk \ argarray.in \ argarray.ok \ @@ -62,6 +60,8 @@ EXTRA_DIST = \ arrayprm3.ok \ arrayref.awk \ arrayref.ok \ + arraysort.awk \ + arraysort.ok \ arrymem1.awk \ arrymem1.ok \ arryref2.awk \ @@ -160,10 +160,10 @@ EXTRA_DIST = \ defref.ok \ delargv.awk \ delargv.ok \ - delarprm.awk \ - delarprm.ok \ delarpm2.awk \ delarpm2.ok \ + delarprm.awk \ + delarprm.ok \ delfunc.awk \ delfunc.ok \ delsub.awk \ @@ -199,8 +199,8 @@ EXTRA_DIST = \ fcall_exit.awk \ fcall_exit.ok \ fcall_exit2.awk \ - fcall_exit2.ok \ fcall_exit2.in \ + fcall_exit2.ok \ fflush.ok \ fflush.sh \ fieldwdth.awk \ @@ -214,9 +214,9 @@ EXTRA_DIST = \ fldchgnf.awk \ fldchgnf.in \ fldchgnf.ok \ + fmtspcl-mpfr.ok \ fmtspcl.awk \ fmtspcl.tok \ - fmtspcl-mpfr.ok \ fmttest.awk \ fmttest.ok \ fnamedat.awk \ @@ -227,9 +227,9 @@ EXTRA_DIST = \ fnarray2.awk \ fnarray2.in \ fnarray2.ok \ + fnarydel-mpfr.ok \ fnarydel.awk \ fnarydel.ok \ - fnarydel-mpfr.ok \ fnaryscl.awk \ fnaryscl.ok \ fnasgnm.awk \ @@ -239,13 +239,19 @@ EXTRA_DIST = \ fnmatch.ok \ fnmisc.awk \ fnmisc.ok \ + fnparydl-mpfr.ok \ fnparydl.awk \ fnparydl.ok \ - fnparydl-mpfr.ok \ + fordel.awk \ + fordel.ok \ fork.awk \ fork.ok \ fork2.awk \ fork2.ok \ + forref.awk \ + forref.ok \ + forsimp.awk \ + forsimp.ok \ fpat1.awk \ fpat1.in \ fpat1.ok \ @@ -257,12 +263,6 @@ EXTRA_DIST = \ fpatnull.awk \ fpatnull.in \ fpatnull.ok \ - fordel.awk \ - fordel.ok \ - forref.awk \ - forref.ok \ - forsimp.awk \ - forsimp.ok \ fsbs.awk \ fsbs.in \ fsbs.ok \ @@ -279,6 +279,14 @@ EXTRA_DIST = \ fstabplus.in \ fstabplus.ok \ fts.awk \ + functab1.awk \ + functab1.ok \ + functab2.awk \ + functab2.ok \ + functab3.awk \ + functab3.ok \ + functab4.awk \ + functab4.ok \ funlen.awk \ funlen.in \ funlen.ok \ @@ -367,29 +375,31 @@ EXTRA_DIST = \ icasers.awk \ icasers.in \ icasers.ok \ + id.awk \ + id.ok \ igncdym.awk \ igncdym.in \ igncdym.ok \ igncfs.awk \ igncfs.in \ igncfs.ok \ + ignrcas2.awk \ + ignrcas2.ok \ ignrcase.awk \ ignrcase.in \ ignrcase.ok \ - ignrcas2.awk \ - ignrcas2.ok \ - inclib.awk \ - include.awk \ - include.ok \ - include2.ok \ incdupe.ok \ incdupe2.ok \ incdupe3.ok \ - inchello.awk \ incdupe4.ok \ incdupe5.ok \ incdupe6.ok \ incdupe7.ok \ + inchello.awk \ + inclib.awk \ + include.awk \ + include.ok \ + include2.ok \ indirectcall.awk \ indirectcall.in \ indirectcall.ok \ @@ -434,8 +444,8 @@ EXTRA_DIST = \ longsub.in \ longsub.ok \ longwrds.awk \ - longwrds.ok \ longwrds.in \ + longwrds.ok \ manglprm.awk \ manglprm.in \ manglprm.ok \ @@ -602,9 +612,6 @@ EXTRA_DIST = \ prdupval.awk \ prdupval.in \ prdupval.ok \ - profile2.ok \ - profile3.awk \ - profile3.ok \ prec.awk \ prec.ok \ printf0.awk \ @@ -626,24 +633,30 @@ EXTRA_DIST = \ prmreuse.ok \ procinfs.awk \ procinfs.ok \ + profile2.ok \ + profile3.awk \ + profile3.ok \ prt1eval.awk \ prt1eval.ok \ prtoeval.awk \ prtoeval.ok \ pty1.awk \ pty1.ok \ + rand-mpfr.ok \ rand.awk \ rand.ok \ - rand-mpfr.ok \ range1.awk \ range1.in \ range1.ok \ - readdir0.awk \ readdir.awk \ + readdir0.awk \ rebt8b1.awk \ rebt8b1.ok \ rebt8b2.awk \ rebt8b2.ok \ + rebuf.awk \ + rebuf.in \ + rebuf.ok \ redfilnm.awk \ redfilnm.in \ redfilnm.ok \ @@ -657,9 +670,6 @@ EXTRA_DIST = \ regtest.sh \ regx8bit.awk \ regx8bit.ok \ - rebuf.awk \ - rebuf.in \ - rebuf.ok \ reindops.awk \ reindops.in \ reindops.ok \ @@ -757,16 +767,16 @@ EXTRA_DIST = \ sprintfc.ok \ strcat1.awk \ strcat1.ok \ + strftime.awk \ + strftlng.awk \ + strftlng.ok \ + strnum1.awk \ + strnum1.ok \ strtod.awk \ strtod.in \ strtod.ok \ - strnum1.awk \ - strnum1.ok \ strtonum.awk \ strtonum.ok \ - strftime.awk \ - strftlng.awk \ - strftlng.ok \ subamp.awk \ subamp.in \ subamp.ok \ @@ -783,6 +793,12 @@ EXTRA_DIST = \ swaplns.ok \ switch2.awk \ switch2.ok \ + symtab1.awk \ + symtab1.ok \ + symtab2.awk \ + symtab2.ok \ + symtab3.awk \ + symtab3.ok \ synerr1.awk \ synerr1.ok \ synerr2.awk \ @@ -837,6 +853,7 @@ EXTRA_DIST = \ zeroflag.awk \ zeroflag.ok + TESTS_WE_ARE_NOT_DOING_YET_FIXME_ONE_DAY = longdbl # Get rid of core files when cleaning and generated .ok file @@ -890,9 +907,10 @@ GAWK_EXT_TESTS = \ backw badargs beginfile1 beginfile2 binmode1 charasbytes \ clos1way delsub devfd devfd1 devfd2 dumpvars exit \ fieldwdth fpat1 fpat2 fpat3 fpatnull fsfwfs funlen \ + functab1 functab2 functab3 functab4 \ fwtest fwtest2 fwtest3 \ gensub gensub2 getlndir gnuops2 gnuops3 gnureops \ - icasefs icasers igncdym igncfs ignrcas2 ignrcase indirectcall \ + icasefs icasers id igncdym igncfs ignrcas2 ignrcase indirectcall \ lint lintold lintwarn \ manyfiles match1 match2 match3 mbstr1 \ nastyparm next nondec nondec2 \ @@ -901,6 +919,7 @@ GAWK_EXT_TESTS = \ rebuf regx8bit reint reint2 rsstart1 \ rsstart2 rsstart3 rstest6 shadow sortfor sortu splitarg4 strftime \ strtonum switch2 \ + symtab1 symtab2 symtab3 \ include include2 incdupe incdupe2 incdupe3 \ incdupe4 incdupe5 incdupe6 incdupe7 diff --git a/test/Makefile.in b/test/Makefile.in index e60c1c6e..db461f52 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -259,8 +259,6 @@ EXTRA_DIST = \ anchgsub.awk \ anchgsub.in \ anchgsub.ok \ - arraysort.awk \ - arraysort.ok \ argarray.awk \ argarray.in \ argarray.ok \ @@ -274,6 +272,8 @@ EXTRA_DIST = \ arrayprm3.ok \ arrayref.awk \ arrayref.ok \ + arraysort.awk \ + arraysort.ok \ arrymem1.awk \ arrymem1.ok \ arryref2.awk \ @@ -372,10 +372,10 @@ EXTRA_DIST = \ defref.ok \ delargv.awk \ delargv.ok \ - delarprm.awk \ - delarprm.ok \ delarpm2.awk \ delarpm2.ok \ + delarprm.awk \ + delarprm.ok \ delfunc.awk \ delfunc.ok \ delsub.awk \ @@ -411,8 +411,8 @@ EXTRA_DIST = \ fcall_exit.awk \ fcall_exit.ok \ fcall_exit2.awk \ - fcall_exit2.ok \ fcall_exit2.in \ + fcall_exit2.ok \ fflush.ok \ fflush.sh \ fieldwdth.awk \ @@ -426,9 +426,9 @@ EXTRA_DIST = \ fldchgnf.awk \ fldchgnf.in \ fldchgnf.ok \ + fmtspcl-mpfr.ok \ fmtspcl.awk \ fmtspcl.tok \ - fmtspcl-mpfr.ok \ fmttest.awk \ fmttest.ok \ fnamedat.awk \ @@ -439,9 +439,9 @@ EXTRA_DIST = \ fnarray2.awk \ fnarray2.in \ fnarray2.ok \ + fnarydel-mpfr.ok \ fnarydel.awk \ fnarydel.ok \ - fnarydel-mpfr.ok \ fnaryscl.awk \ fnaryscl.ok \ fnasgnm.awk \ @@ -451,13 +451,19 @@ EXTRA_DIST = \ fnmatch.ok \ fnmisc.awk \ fnmisc.ok \ + fnparydl-mpfr.ok \ fnparydl.awk \ fnparydl.ok \ - fnparydl-mpfr.ok \ + fordel.awk \ + fordel.ok \ fork.awk \ fork.ok \ fork2.awk \ fork2.ok \ + forref.awk \ + forref.ok \ + forsimp.awk \ + forsimp.ok \ fpat1.awk \ fpat1.in \ fpat1.ok \ @@ -469,12 +475,6 @@ EXTRA_DIST = \ fpatnull.awk \ fpatnull.in \ fpatnull.ok \ - fordel.awk \ - fordel.ok \ - forref.awk \ - forref.ok \ - forsimp.awk \ - forsimp.ok \ fsbs.awk \ fsbs.in \ fsbs.ok \ @@ -491,6 +491,14 @@ EXTRA_DIST = \ fstabplus.in \ fstabplus.ok \ fts.awk \ + functab1.awk \ + functab1.ok \ + functab2.awk \ + functab2.ok \ + functab3.awk \ + functab3.ok \ + functab4.awk \ + functab4.ok \ funlen.awk \ funlen.in \ funlen.ok \ @@ -579,29 +587,31 @@ EXTRA_DIST = \ icasers.awk \ icasers.in \ icasers.ok \ + id.awk \ + id.ok \ igncdym.awk \ igncdym.in \ igncdym.ok \ igncfs.awk \ igncfs.in \ igncfs.ok \ + ignrcas2.awk \ + ignrcas2.ok \ ignrcase.awk \ ignrcase.in \ ignrcase.ok \ - ignrcas2.awk \ - ignrcas2.ok \ - inclib.awk \ - include.awk \ - include.ok \ - include2.ok \ incdupe.ok \ incdupe2.ok \ incdupe3.ok \ - inchello.awk \ incdupe4.ok \ incdupe5.ok \ incdupe6.ok \ incdupe7.ok \ + inchello.awk \ + inclib.awk \ + include.awk \ + include.ok \ + include2.ok \ indirectcall.awk \ indirectcall.in \ indirectcall.ok \ @@ -646,8 +656,8 @@ EXTRA_DIST = \ longsub.in \ longsub.ok \ longwrds.awk \ - longwrds.ok \ longwrds.in \ + longwrds.ok \ manglprm.awk \ manglprm.in \ manglprm.ok \ @@ -814,9 +824,6 @@ EXTRA_DIST = \ prdupval.awk \ prdupval.in \ prdupval.ok \ - profile2.ok \ - profile3.awk \ - profile3.ok \ prec.awk \ prec.ok \ printf0.awk \ @@ -838,24 +845,30 @@ EXTRA_DIST = \ prmreuse.ok \ procinfs.awk \ procinfs.ok \ + profile2.ok \ + profile3.awk \ + profile3.ok \ prt1eval.awk \ prt1eval.ok \ prtoeval.awk \ prtoeval.ok \ pty1.awk \ pty1.ok \ + rand-mpfr.ok \ rand.awk \ rand.ok \ - rand-mpfr.ok \ range1.awk \ range1.in \ range1.ok \ - readdir0.awk \ readdir.awk \ + readdir0.awk \ rebt8b1.awk \ rebt8b1.ok \ rebt8b2.awk \ rebt8b2.ok \ + rebuf.awk \ + rebuf.in \ + rebuf.ok \ redfilnm.awk \ redfilnm.in \ redfilnm.ok \ @@ -869,9 +882,6 @@ EXTRA_DIST = \ regtest.sh \ regx8bit.awk \ regx8bit.ok \ - rebuf.awk \ - rebuf.in \ - rebuf.ok \ reindops.awk \ reindops.in \ reindops.ok \ @@ -969,16 +979,16 @@ EXTRA_DIST = \ sprintfc.ok \ strcat1.awk \ strcat1.ok \ + strftime.awk \ + strftlng.awk \ + strftlng.ok \ + strnum1.awk \ + strnum1.ok \ strtod.awk \ strtod.in \ strtod.ok \ - strnum1.awk \ - strnum1.ok \ strtonum.awk \ strtonum.ok \ - strftime.awk \ - strftlng.awk \ - strftlng.ok \ subamp.awk \ subamp.in \ subamp.ok \ @@ -995,6 +1005,12 @@ EXTRA_DIST = \ swaplns.ok \ switch2.awk \ switch2.ok \ + symtab1.awk \ + symtab1.ok \ + symtab2.awk \ + symtab2.ok \ + symtab3.awk \ + symtab3.ok \ synerr1.awk \ synerr1.ok \ synerr2.awk \ @@ -1102,9 +1118,10 @@ GAWK_EXT_TESTS = \ backw badargs beginfile1 beginfile2 binmode1 charasbytes \ clos1way delsub devfd devfd1 devfd2 dumpvars exit \ fieldwdth fpat1 fpat2 fpat3 fpatnull fsfwfs funlen \ + functab1 functab2 functab3 functab4 \ fwtest fwtest2 fwtest3 \ gensub gensub2 getlndir gnuops2 gnuops3 gnureops \ - icasefs icasers igncdym igncfs ignrcas2 ignrcase indirectcall \ + icasefs icasers id igncdym igncfs ignrcas2 ignrcase indirectcall \ lint lintold lintwarn \ manyfiles match1 match2 match3 mbstr1 \ nastyparm next nondec nondec2 \ @@ -1113,6 +1130,7 @@ GAWK_EXT_TESTS = \ rebuf regx8bit reint reint2 rsstart1 \ rsstart2 rsstart3 rstest6 shadow sortfor sortu splitarg4 strftime \ strtonum switch2 \ + symtab1 symtab2 symtab3 \ include include2 incdupe incdupe2 incdupe3 \ incdupe4 incdupe5 incdupe6 incdupe7 @@ -3014,6 +3032,26 @@ funlen: @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ +functab1: + @echo $@ + @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ + +functab2: + @echo $@ + @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ + +functab3: + @echo $@ + @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ + +functab4: + @echo $@ + @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ + fwtest: @echo $@ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @@ -3069,6 +3107,11 @@ icasers: @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ +id: + @echo $@ + @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ + igncdym: @echo $@ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @@ -3204,6 +3247,21 @@ switch2: @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ +symtab1: + @echo $@ + @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ + +symtab2: + @echo $@ + @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ + +symtab3: + @echo $@ + @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ + include: @echo $@ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/Maketests b/test/Maketests index 3951c3ff..6490410c 100644 --- a/test/Maketests +++ b/test/Maketests @@ -960,6 +960,26 @@ funlen: @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ +functab1: + @echo $@ + @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ + +functab2: + @echo $@ + @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ + +functab3: + @echo $@ + @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ + +functab4: + @echo $@ + @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ + fwtest: @echo $@ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @@ -1015,6 +1035,11 @@ icasers: @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ +id: + @echo $@ + @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ + igncdym: @echo $@ @AWKPATH=$(srcdir) $(AWK) -f $@.awk < $(srcdir)/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @@ -1150,6 +1175,21 @@ switch2: @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ +symtab1: + @echo $@ + @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ + +symtab2: + @echo $@ + @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ + +symtab3: + @echo $@ + @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@ + include: @echo $@ @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/functab1.awk b/test/functab1.awk new file mode 100644 index 00000000..05692684 --- /dev/null +++ b/test/functab1.awk @@ -0,0 +1,3 @@ +BEGIN { + delete FUNCTAB +} diff --git a/test/functab1.ok b/test/functab1.ok new file mode 100644 index 00000000..2a60a4cb --- /dev/null +++ b/test/functab1.ok @@ -0,0 +1,2 @@ +gawk: functab1.awk:3: fatal: `delete' is not allowed with FUNCTAB +EXIT CODE: 2 diff --git a/test/functab2.awk b/test/functab2.awk new file mode 100644 index 00000000..9a07dfc3 --- /dev/null +++ b/test/functab2.awk @@ -0,0 +1,8 @@ +function foo() +{ + print "foo!" +} + +BEGIN { + FUNCTAB["a"] = "something" +} diff --git a/test/functab2.ok b/test/functab2.ok new file mode 100644 index 00000000..32b07ad3 --- /dev/null +++ b/test/functab2.ok @@ -0,0 +1,2 @@ +gawk: functab2.awk:7: fatal: cannot assign to elements of FUNCTAB +EXIT CODE: 2 diff --git a/test/functab3.awk b/test/functab3.awk new file mode 100644 index 00000000..98fa49b1 --- /dev/null +++ b/test/functab3.awk @@ -0,0 +1,10 @@ +function foo() +{ + print "foo!" +} + +BEGIN { + x = FUNCTAB["foo"] + print "x =", x + @x() +} diff --git a/test/functab3.ok b/test/functab3.ok new file mode 100644 index 00000000..66f53d72 --- /dev/null +++ b/test/functab3.ok @@ -0,0 +1,2 @@ +x = foo +foo! diff --git a/test/functab4.awk b/test/functab4.awk new file mode 100644 index 00000000..0d9d4267 --- /dev/null +++ b/test/functab4.awk @@ -0,0 +1,14 @@ +@load "filefuncs" + +function foo() +{ + print "foo!" +} + +BEGIN { + x = FUNCTAB["chdir"] + print "x =", x + @x("/tmp") + printf "we are now in --> " + system("/bin/pwd || /usr/bin/pwd") +} diff --git a/test/functab4.ok b/test/functab4.ok new file mode 100644 index 00000000..70a520b7 --- /dev/null +++ b/test/functab4.ok @@ -0,0 +1,3 @@ +x = chdir +gawk: functab4.awk:11: fatal: cannot (yet) call extension functions indirectly +EXIT CODE: 2 diff --git a/test/id.awk b/test/id.awk new file mode 100644 index 00000000..2a35e42c --- /dev/null +++ b/test/id.awk @@ -0,0 +1,11 @@ +function function1() +{ + print "function1" +} + +BEGIN { + an_array[1] = 1 + + for (i in PROCINFO["identifiers"]) + printf("%s -> %s\n", i, PROCINFO["identifiers"][i]) +} diff --git a/test/id.ok b/test/id.ok new file mode 100644 index 00000000..d31573de --- /dev/null +++ b/test/id.ok @@ -0,0 +1,32 @@ +FUNCTAB -> array +ARGV -> array +SYMTAB -> array +ORS -> scalar +ROUNDMODE -> scalar +i -> untyped +OFS -> scalar +ERRNO -> scalar +FNR -> scalar +LINT -> scalar +IGNORECASE -> scalar +NR -> scalar +function1 -> user +ARGIND -> scalar +NF -> scalar +TEXTDOMAIN -> scalar +CONVFMT -> scalar +FIELDWIDTHS -> scalar +ARGC -> scalar +an_array -> untyped +PROCINFO -> array +PREC -> scalar +SUBSEP -> scalar +FPAT -> scalar +RS -> scalar +FS -> scalar +OFMT -> scalar +RLENGTH -> scalar +RT -> scalar +BINMODE -> scalar +FILENAME -> scalar +RSTART -> scalar diff --git a/test/symtab1.awk b/test/symtab1.awk new file mode 100644 index 00000000..6ca7d632 --- /dev/null +++ b/test/symtab1.awk @@ -0,0 +1,18 @@ +function dumparray(name, array, i) +{ + for (i in array) + if (isarray(array[i])) + dumparray(name "[" i "]", array[i]) + else + printf("%s[%s] = %s\n", name, i, array[i]) +} + +BEGIN { + a[1] = 1 + a[2][1] = 21 + for (i in SYMTAB) + if (isarray(SYMTAB[i])) + dumparray(i, SYMTAB[i]) + else + printf("SYMTAB[\"%s\"] = \"%s\"\n", i, SYMTAB[i]) +} diff --git a/test/symtab1.ok b/test/symtab1.ok new file mode 100644 index 00000000..3e435dd2 --- /dev/null +++ b/test/symtab1.ok @@ -0,0 +1,31 @@ +ARGV[0] = gawk +SYMTAB["i"] = "i" +SYMTAB["ROUNDMODE"] = "N" +SYMTAB["ORS"] = " +" +SYMTAB["OFS"] = " " +SYMTAB["LINT"] = "0" +SYMTAB["FNR"] = "0" +SYMTAB["ERRNO"] = "" +SYMTAB["NR"] = "0" +SYMTAB["IGNORECASE"] = "0" +SYMTAB["TEXTDOMAIN"] = "messages" +SYMTAB["NF"] = "-1" +SYMTAB["ARGIND"] = "0" +a[1] = 1 +a[2][1] = 21 +SYMTAB["ARGC"] = "1" +SYMTAB["FIELDWIDTHS"] = "" +SYMTAB["CONVFMT"] = "%.6g" +SYMTAB["SUBSEP"] = "" +SYMTAB["PREC"] = "53" +SYMTAB["RS"] = " +" +SYMTAB["FPAT"] = "[^[:space:]]+" +SYMTAB["RT"] = "" +SYMTAB["RLENGTH"] = "0" +SYMTAB["OFMT"] = "%.6g" +SYMTAB["FS"] = " " +SYMTAB["RSTART"] = "0" +SYMTAB["FILENAME"] = "" +SYMTAB["BINMODE"] = "0" diff --git a/test/symtab2.awk b/test/symtab2.awk new file mode 100644 index 00000000..bb26f75d --- /dev/null +++ b/test/symtab2.awk @@ -0,0 +1,6 @@ +BEGIN { + a = 5 + printf "a = %d, SYMTAB[\"a\"] = %d\n", a, SYMTAB["a"] + SYMTAB["a"] = 4 + printf "a = %d, SYMTAB[\"a\"] = %d\n", a, SYMTAB["a"] +} diff --git a/test/symtab2.ok b/test/symtab2.ok new file mode 100644 index 00000000..23d2bf69 --- /dev/null +++ b/test/symtab2.ok @@ -0,0 +1,2 @@ +a = 5, SYMTAB["a"] = 5 +a = 4, SYMTAB["a"] = 4 diff --git a/test/symtab3.awk b/test/symtab3.awk new file mode 100644 index 00000000..4c2026dc --- /dev/null +++ b/test/symtab3.awk @@ -0,0 +1 @@ +BEGIN { a = 5 ; delete SYMTAB["a"] } diff --git a/test/symtab3.ok b/test/symtab3.ok new file mode 100644 index 00000000..5b283583 --- /dev/null +++ b/test/symtab3.ok @@ -0,0 +1,2 @@ +gawk: symtab3.awk:1: fatal: `delete' is not allowed with SYMTAB +EXIT CODE: 2 |