00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "system.h"
00024 #include "coretypes.h"
00025 #include "tm.h"
00026 #include "errors.h"
00027 #include "tree.h"
00028 #include "tree-inline.h"
00029 #include "diagnostic.h"
00030 #include "hashtab.h"
00031
00032
00033 #define TB_OUT_FILE stdout
00034 #define TB_IN_FILE stdin
00035 #define TB_NIY fprintf (TB_OUT_FILE, "Sorry this command is not yet implemented.\n")
00036 #define TB_WF fprintf (TB_OUT_FILE, "Warning, this command failed.\n")
00037
00038
00039
00040 #define DEFTBCODE(COMMAND, STRING, HELP) COMMAND,
00041 enum TB_Comm_code {
00042 #include "tree-browser.def"
00043 TB_UNUSED_COMMAND
00044 };
00045 #undef DEFTBCODE
00046 typedef enum TB_Comm_code TB_CODE;
00047
00048 struct tb_command {
00049 const char *help_msg;
00050 const char *comm_text;
00051 size_t comm_len;
00052 TB_CODE comm_code;
00053 };
00054
00055 #define DEFTBCODE(code, str, help) { help, str, sizeof(str) - 1, code },
00056 static const struct tb_command tb_commands[] =
00057 {
00058 #include "tree-browser.def"
00059 };
00060 #undef DEFTBCODE
00061
00062 #define TB_COMMAND_LEN(N) (tb_commands[N].comm_len)
00063 #define TB_COMMAND_TEXT(N) (tb_commands[N].comm_text)
00064 #define TB_COMMAND_CODE(N) (tb_commands[N].comm_code)
00065 #define TB_COMMAND_HELP(N) (tb_commands[N].help_msg)
00066
00067
00068
00069 struct tb_tree_code {
00070 enum tree_code code;
00071 const char *code_string;
00072 size_t code_string_len;
00073 };
00074
00075 #define DEFTREECODE(SYM, STRING, TYPE, NARGS) { SYM, STRING, sizeof (STRING) - 1 },
00076 static const struct tb_tree_code tb_tree_codes[] =
00077 {
00078 #include "tree.def"
00079 };
00080 #undef DEFTREECODE
00081
00082 #define TB_TREE_CODE(N) (tb_tree_codes[N].code)
00083 #define TB_TREE_CODE_TEXT(N) (tb_tree_codes[N].code_string)
00084 #define TB_TREE_CODE_LEN(N) (tb_tree_codes[N].code_string_len)
00085
00086
00087
00088
00089 static long TB_getline (char **, long *, FILE *);
00090 static TB_CODE TB_get_command (char *);
00091 static enum tree_code TB_get_tree_code (char *);
00092 static tree find_node_with_code (tree *, int *, void *);
00093 static tree store_child_info (tree *, int *, void *);
00094 static void TB_update_up (tree);
00095 static tree TB_current_chain_node (tree);
00096 static tree TB_prev_expr (tree);
00097 static tree TB_next_expr (tree);
00098 static tree TB_up_expr (tree);
00099 static tree TB_first_in_bind (tree);
00100 static tree TB_last_in_bind (tree);
00101 static int TB_parent_eq (const void *, const void *);
00102 static tree TB_history_prev (void);
00103
00104
00105 void browse_tree (tree);
00106
00107
00108 static htab_t TB_up_ht;
00109 static tree TB_history_stack = NULL_TREE;
00110 static int TB_verbose = 1;
00111
00112
00113
00114
00115 void
00116 browse_tree (tree begin)
00117 {
00118 tree head;
00119 TB_CODE tbc = TB_UNUSED_COMMAND;
00120 ssize_t rd;
00121 char *input = NULL;
00122 long input_size = 0;
00123
00124 fprintf (TB_OUT_FILE, "\nTree Browser\n");
00125
00126 #define TB_SET_HEAD(N) do { \
00127 TB_history_stack = tree_cons (NULL_TREE, (N), TB_history_stack); \
00128 head = N; \
00129 if (TB_verbose) \
00130 if (head) \
00131 { \
00132 print_generic_expr (TB_OUT_FILE, head, 0); \
00133 fprintf (TB_OUT_FILE, "\n"); \
00134 } \
00135 } while (0)
00136
00137 TB_SET_HEAD (begin);
00138
00139
00140 {
00141 TB_up_ht = htab_create (1023, htab_hash_pointer, &TB_parent_eq, NULL);
00142 TB_update_up (head);
00143 }
00144
00145 while (24)
00146 {
00147 fprintf (TB_OUT_FILE, "TB> ");
00148 rd = TB_getline (&input, &input_size, TB_IN_FILE);
00149
00150 if (rd == -1)
00151
00152 goto ret;
00153
00154 if (rd != 1)
00155
00156
00157 tbc = TB_get_command (input);
00158
00159 switch (tbc)
00160 {
00161 case TB_UPDATE_UP:
00162 TB_update_up (head);
00163 break;
00164
00165 case TB_MAX:
00166 if (head && (INTEGRAL_TYPE_P (head)
00167 || TREE_CODE (head) == REAL_TYPE))
00168 TB_SET_HEAD (TYPE_MAX_VALUE (head));
00169 else
00170 TB_WF;
00171 break;
00172
00173 case TB_MIN:
00174 if (head && (INTEGRAL_TYPE_P (head)
00175 || TREE_CODE (head) == REAL_TYPE))
00176 TB_SET_HEAD (TYPE_MIN_VALUE (head));
00177 else
00178 TB_WF;
00179 break;
00180
00181 case TB_ELT:
00182 if (head && TREE_CODE (head) == TREE_VEC)
00183 {
00184
00185
00186 TB_NIY;
00187 }
00188 else if (head && TREE_CODE (head) == VECTOR_CST)
00189 {
00190
00191
00192 TB_NIY;
00193 }
00194 else
00195 TB_WF;
00196 break;
00197
00198 case TB_VALUE:
00199 if (head && TREE_CODE (head) == TREE_LIST)
00200 TB_SET_HEAD (TREE_VALUE (head));
00201 else
00202 TB_WF;
00203 break;
00204
00205 case TB_PURPOSE:
00206 if (head && TREE_CODE (head) == TREE_LIST)
00207 TB_SET_HEAD (TREE_PURPOSE (head));
00208 else
00209 TB_WF;
00210 break;
00211
00212 case TB_IMAG:
00213 if (head && TREE_CODE (head) == COMPLEX_CST)
00214 TB_SET_HEAD (TREE_IMAGPART (head));
00215 else
00216 TB_WF;
00217 break;
00218
00219 case TB_REAL:
00220 if (head && TREE_CODE (head) == COMPLEX_CST)
00221 TB_SET_HEAD (TREE_REALPART (head));
00222 else
00223 TB_WF;
00224 break;
00225
00226 case TB_BLOCK:
00227 if (head && TREE_CODE (head) == BIND_EXPR)
00228 TB_SET_HEAD (TREE_OPERAND (head, 2));
00229 else
00230 TB_WF;
00231 break;
00232
00233 case TB_SUBBLOCKS:
00234 if (head && TREE_CODE (head) == BLOCK)
00235 TB_SET_HEAD (BLOCK_SUBBLOCKS (head));
00236 else
00237 TB_WF;
00238 break;
00239
00240 case TB_SUPERCONTEXT:
00241 if (head && TREE_CODE (head) == BLOCK)
00242 TB_SET_HEAD (BLOCK_SUPERCONTEXT (head));
00243 else
00244 TB_WF;
00245 break;
00246
00247 case TB_VARS:
00248 if (head && TREE_CODE (head) == BLOCK)
00249 TB_SET_HEAD (BLOCK_VARS (head));
00250 else if (head && TREE_CODE (head) == BIND_EXPR)
00251 TB_SET_HEAD (TREE_OPERAND (head, 0));
00252 else
00253 TB_WF;
00254 break;
00255
00256 case TB_REFERENCE_TO_THIS:
00257 if (head && TYPE_P (head))
00258 TB_SET_HEAD (TYPE_REFERENCE_TO (head));
00259 else
00260 TB_WF;
00261 break;
00262
00263 case TB_POINTER_TO_THIS:
00264 if (head && TYPE_P (head))
00265 TB_SET_HEAD (TYPE_POINTER_TO (head));
00266 else
00267 TB_WF;
00268 break;
00269
00270 case TB_BASETYPE:
00271 if (head && TREE_CODE (head) == OFFSET_TYPE)
00272 TB_SET_HEAD (TYPE_OFFSET_BASETYPE (head));
00273 else
00274 TB_WF;
00275 break;
00276
00277 case TB_ARG_TYPES:
00278 if (head && (TREE_CODE (head) == FUNCTION_TYPE
00279 || TREE_CODE (head) == METHOD_TYPE))
00280 TB_SET_HEAD (TYPE_ARG_TYPES (head));
00281 else
00282 TB_WF;
00283 break;
00284
00285 case TB_METHOD_BASE_TYPE:
00286 if (head && (TREE_CODE (head) == FUNCTION_TYPE
00287 || TREE_CODE (head) == METHOD_TYPE)
00288 && TYPE_METHOD_BASETYPE (head))
00289 TB_SET_HEAD (TYPE_METHOD_BASETYPE (head));
00290 else
00291 TB_WF;
00292 break;
00293
00294 case TB_FIELDS:
00295 if (head && (TREE_CODE (head) == RECORD_TYPE
00296 || TREE_CODE (head) == UNION_TYPE
00297 || TREE_CODE (head) == QUAL_UNION_TYPE))
00298 TB_SET_HEAD (TYPE_FIELDS (head));
00299 else
00300 TB_WF;
00301 break;
00302
00303 case TB_DOMAIN:
00304 if (head && TREE_CODE (head) == ARRAY_TYPE)
00305 TB_SET_HEAD (TYPE_DOMAIN (head));
00306 else
00307 TB_WF;
00308 break;
00309
00310 case TB_VALUES:
00311 if (head && TREE_CODE (head) == ENUMERAL_TYPE)
00312 TB_SET_HEAD (TYPE_VALUES (head));
00313 else
00314 TB_WF;
00315 break;
00316
00317 case TB_ARG_TYPE_AS_WRITTEN:
00318 if (head && TREE_CODE (head) == PARM_DECL)
00319 TB_SET_HEAD (DECL_ARG_TYPE_AS_WRITTEN (head));
00320 else
00321 TB_WF;
00322 break;
00323
00324 case TB_ARG_TYPE:
00325 if (head && TREE_CODE (head) == PARM_DECL)
00326 TB_SET_HEAD (DECL_ARG_TYPE (head));
00327 else
00328 TB_WF;
00329 break;
00330
00331 case TB_INITIAL:
00332 if (head && DECL_P (head))
00333 TB_SET_HEAD (DECL_INITIAL (head));
00334 else
00335 TB_WF;
00336 break;
00337
00338 case TB_RESULT:
00339 if (head && DECL_P (head))
00340 TB_SET_HEAD (DECL_RESULT_FLD (head));
00341 else
00342 TB_WF;
00343 break;
00344
00345 case TB_ARGUMENTS:
00346 if (head && DECL_P (head))
00347 TB_SET_HEAD (DECL_ARGUMENTS (head));
00348 else
00349 TB_WF;
00350 break;
00351
00352 case TB_ABSTRACT_ORIGIN:
00353 if (head && DECL_P (head))
00354 TB_SET_HEAD (DECL_ABSTRACT_ORIGIN (head));
00355 else if (head && TREE_CODE (head) == BLOCK)
00356 TB_SET_HEAD (BLOCK_ABSTRACT_ORIGIN (head));
00357 else
00358 TB_WF;
00359 break;
00360
00361 case TB_ATTRIBUTES:
00362 if (head && DECL_P (head))
00363 TB_SET_HEAD (DECL_ATTRIBUTES (head));
00364 else if (head && TYPE_P (head))
00365 TB_SET_HEAD (TYPE_ATTRIBUTES (head));
00366 else
00367 TB_WF;
00368 break;
00369
00370 case TB_CONTEXT:
00371 if (head && DECL_P (head))
00372 TB_SET_HEAD (DECL_CONTEXT (head));
00373 else if (head && TYPE_P (head)
00374 && TYPE_CONTEXT (head))
00375 TB_SET_HEAD (TYPE_CONTEXT (head));
00376 else
00377 TB_WF;
00378 break;
00379
00380 case TB_OFFSET:
00381 if (head && TREE_CODE (head) == FIELD_DECL)
00382 TB_SET_HEAD (DECL_FIELD_OFFSET (head));
00383 else
00384 TB_WF;
00385 break;
00386
00387 case TB_BIT_OFFSET:
00388 if (head && TREE_CODE (head) == FIELD_DECL)
00389 TB_SET_HEAD (DECL_FIELD_BIT_OFFSET (head));
00390 else
00391 TB_WF;
00392 break;
00393
00394 case TB_UNIT_SIZE:
00395 if (head && DECL_P (head))
00396 TB_SET_HEAD (DECL_SIZE_UNIT (head));
00397 else if (head && TYPE_P (head))
00398 TB_SET_HEAD (TYPE_SIZE_UNIT (head));
00399 else
00400 TB_WF;
00401 break;
00402
00403 case TB_SIZE:
00404 if (head && DECL_P (head))
00405 TB_SET_HEAD (DECL_SIZE (head));
00406 else if (head && TYPE_P (head))
00407 TB_SET_HEAD (TYPE_SIZE (head));
00408 else
00409 TB_WF;
00410 break;
00411
00412 case TB_TYPE:
00413 if (head && TREE_TYPE (head))
00414 TB_SET_HEAD (TREE_TYPE (head));
00415 else
00416 TB_WF;
00417 break;
00418
00419 case TB_DECL_SAVED_TREE:
00420 if (head && TREE_CODE (head) == FUNCTION_DECL
00421 && DECL_SAVED_TREE (head))
00422 TB_SET_HEAD (DECL_SAVED_TREE (head));
00423 else
00424 TB_WF;
00425 break;
00426
00427 case TB_BODY:
00428 if (head && TREE_CODE (head) == BIND_EXPR)
00429 TB_SET_HEAD (TREE_OPERAND (head, 1));
00430 else
00431 TB_WF;
00432 break;
00433
00434 case TB_CHILD_0:
00435 if (head && EXPR_P (head) && TREE_OPERAND (head, 0))
00436 TB_SET_HEAD (TREE_OPERAND (head, 0));
00437 else
00438 TB_WF;
00439 break;
00440
00441 case TB_CHILD_1:
00442 if (head && EXPR_P (head) && TREE_OPERAND (head, 1))
00443 TB_SET_HEAD (TREE_OPERAND (head, 1));
00444 else
00445 TB_WF;
00446 break;
00447
00448 case TB_CHILD_2:
00449 if (head && EXPR_P (head) && TREE_OPERAND (head, 2))
00450 TB_SET_HEAD (TREE_OPERAND (head, 2));
00451 else
00452 TB_WF;
00453 break;
00454
00455 case TB_CHILD_3:
00456 if (head && EXPR_P (head) && TREE_OPERAND (head, 3))
00457 TB_SET_HEAD (TREE_OPERAND (head, 3));
00458 else
00459 TB_WF;
00460 break;
00461
00462 case TB_PRINT:
00463 if (head)
00464 debug_tree (head);
00465 else
00466 TB_WF;
00467 break;
00468
00469 case TB_PRETTY_PRINT:
00470 if (head)
00471 {
00472 print_generic_stmt (TB_OUT_FILE, head, 0);
00473 fprintf (TB_OUT_FILE, "\n");
00474 }
00475 else
00476 TB_WF;
00477 break;
00478
00479 case TB_SEARCH_NAME:
00480
00481 break;
00482
00483 case TB_SEARCH_CODE:
00484 {
00485 enum tree_code code;
00486 char *arg_text;
00487
00488 arg_text = strchr (input, ' ');
00489 if (arg_text == NULL)
00490 {
00491 fprintf (TB_OUT_FILE, "First argument is missing. This isn't a valid search command. \n");
00492 break;
00493 }
00494 code = TB_get_tree_code (arg_text + 1);
00495
00496
00497 {
00498 tree res;
00499
00500 res = walk_tree (&head, find_node_with_code, &code, NULL);
00501 if (res == NULL_TREE)
00502 {
00503 fprintf (TB_OUT_FILE, "There's no node with this code (reachable via the walk_tree function from this node).\n");
00504 }
00505 else
00506 {
00507 fprintf (TB_OUT_FILE, "Achoo! I got this node in the tree.\n");
00508 TB_SET_HEAD (res);
00509 }
00510 }
00511 break;
00512 }
00513
00514 #define TB_MOVE_HEAD(FCT) do { \
00515 if (head) \
00516 { \
00517 tree t; \
00518 t = FCT (head); \
00519 if (t) \
00520 TB_SET_HEAD (t); \
00521 else \
00522 TB_WF; \
00523 } \
00524 else \
00525 TB_WF; \
00526 } while (0)
00527
00528 case TB_FIRST:
00529 TB_MOVE_HEAD (TB_first_in_bind);
00530 break;
00531
00532 case TB_LAST:
00533 TB_MOVE_HEAD (TB_last_in_bind);
00534 break;
00535
00536 case TB_UP:
00537 TB_MOVE_HEAD (TB_up_expr);
00538 break;
00539
00540 case TB_PREV:
00541 TB_MOVE_HEAD (TB_prev_expr);
00542 break;
00543
00544 case TB_NEXT:
00545 TB_MOVE_HEAD (TB_next_expr);
00546 break;
00547
00548 case TB_HPREV:
00549
00550
00551
00552 if (head)
00553 {
00554 tree t;
00555 t = TB_history_prev ();
00556 if (t)
00557 {
00558 head = t;
00559 if (TB_verbose)
00560 {
00561 print_generic_expr (TB_OUT_FILE, head, 0);
00562 fprintf (TB_OUT_FILE, "\n");
00563 }
00564 }
00565 else
00566 TB_WF;
00567 }
00568 else
00569 TB_WF;
00570 break;
00571
00572 case TB_CHAIN:
00573
00574 if (head && TREE_CODE (head) == BLOCK)
00575 TB_SET_HEAD (BLOCK_CHAIN (head));
00576 else if (head && TREE_CHAIN (head))
00577 TB_SET_HEAD (TREE_CHAIN (head));
00578 else
00579 TB_WF;
00580 break;
00581
00582 case TB_FUN:
00583
00584 TB_SET_HEAD (current_function_decl);
00585 fprintf (TB_OUT_FILE, "Current function declaration.\n");
00586 break;
00587
00588 case TB_HELP:
00589
00590 {
00591 int i;
00592 fprintf (TB_OUT_FILE, "Possible commands are:\n\n");
00593 for (i = 0; i < TB_UNUSED_COMMAND; i++)
00594 {
00595 fprintf (TB_OUT_FILE, "%20s - %s\n", TB_COMMAND_TEXT (i), TB_COMMAND_HELP (i));
00596 }
00597 }
00598 break;
00599
00600 case TB_VERBOSE:
00601 if (TB_verbose == 0)
00602 {
00603 TB_verbose = 1;
00604 fprintf (TB_OUT_FILE, "Verbose on.\n");
00605 }
00606 else
00607 {
00608 TB_verbose = 0;
00609 fprintf (TB_OUT_FILE, "Verbose off.\n");
00610 }
00611 break;
00612
00613 case TB_EXIT:
00614 case TB_QUIT:
00615
00616 goto ret;
00617
00618 default:
00619 TB_NIY;
00620 }
00621 }
00622
00623 ret:;
00624 htab_delete (TB_up_ht);
00625 return;
00626 }
00627
00628
00629
00630
00631 static tree
00632 TB_first_in_bind (tree node)
00633 {
00634 tree t;
00635
00636 if (node == NULL_TREE)
00637 return NULL_TREE;
00638
00639 while ((t = TB_prev_expr (node)))
00640 node = t;
00641
00642 return node;
00643 }
00644
00645
00646
00647 static tree
00648 TB_last_in_bind (tree node)
00649 {
00650 tree t;
00651
00652 if (node == NULL_TREE)
00653 return NULL_TREE;
00654
00655 while ((t = TB_next_expr (node)))
00656 node = t;
00657
00658 return node;
00659 }
00660
00661
00662
00663 static tree
00664 TB_up_expr (tree node)
00665 {
00666 tree res;
00667 if (node == NULL_TREE)
00668 return NULL_TREE;
00669
00670 res = (tree) htab_find (TB_up_ht, node);
00671 return res;
00672 }
00673
00674
00675
00676 static tree
00677 TB_prev_expr (tree node)
00678 {
00679 node = TB_current_chain_node (node);
00680
00681 if (node == NULL_TREE)
00682 return NULL_TREE;
00683
00684 node = TB_up_expr (node);
00685 if (node && TREE_CODE (node) == COMPOUND_EXPR)
00686 return node;
00687 else
00688 return NULL_TREE;
00689 }
00690
00691
00692
00693 static tree
00694 TB_next_expr (tree node)
00695 {
00696 node = TB_current_chain_node (node);
00697
00698 if (node == NULL_TREE)
00699 return NULL_TREE;
00700
00701 node = TREE_OPERAND (node, 1);
00702 return node;
00703 }
00704
00705 static tree
00706 TB_current_chain_node (tree node)
00707 {
00708 if (node == NULL_TREE)
00709 return NULL_TREE;
00710
00711 if (TREE_CODE (node) == COMPOUND_EXPR)
00712 return node;
00713
00714 node = TB_up_expr (node);
00715 if (node)
00716 {
00717 if (TREE_CODE (node) == COMPOUND_EXPR)
00718 return node;
00719
00720 node = TB_up_expr (node);
00721 if (TREE_CODE (node) == COMPOUND_EXPR)
00722 return node;
00723 }
00724
00725 return NULL_TREE;
00726 }
00727
00728
00729
00730
00731 static tree
00732 store_child_info (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
00733 void *data ATTRIBUTE_UNUSED)
00734 {
00735 tree node;
00736 void **slot;
00737
00738 node = *tp;
00739
00740
00741 if (EXPRESSION_CLASS_P (node))
00742 {
00743
00744 #define STORE_CHILD(N) do { \
00745 tree op = TREE_OPERAND (node, N); \
00746 slot = htab_find_slot (TB_up_ht, op, INSERT); \
00747 *slot = (void *) node; \
00748 } while (0)
00749
00750 switch (TREE_CODE_LENGTH (TREE_CODE (node)))
00751 {
00752 case 4:
00753 STORE_CHILD (0);
00754 STORE_CHILD (1);
00755 STORE_CHILD (2);
00756 STORE_CHILD (3);
00757 break;
00758
00759 case 3:
00760 STORE_CHILD (0);
00761 STORE_CHILD (1);
00762 STORE_CHILD (2);
00763 break;
00764
00765 case 2:
00766 STORE_CHILD (0);
00767 STORE_CHILD (1);
00768 break;
00769
00770 case 1:
00771 STORE_CHILD (0);
00772 break;
00773
00774 case 0:
00775 default:
00776
00777 break;
00778 }
00779 #undef STORE_CHILD
00780 }
00781
00782
00783 return NULL_TREE;
00784 }
00785
00786
00787
00788 static int
00789 TB_parent_eq (const void *p1, const void *p2)
00790 {
00791 tree node, parent;
00792 node = (tree) p2;
00793 parent = (tree) p1;
00794
00795 if (p1 == NULL || p2 == NULL)
00796 return 0;
00797
00798 if (EXPRESSION_CLASS_P (parent))
00799 {
00800
00801 #define TEST_CHILD(N) do { \
00802 if (node == TREE_OPERAND (parent, N)) \
00803 return 1; \
00804 } while (0)
00805
00806 switch (TREE_CODE_LENGTH (TREE_CODE (parent)))
00807 {
00808 case 4:
00809 TEST_CHILD (0);
00810 TEST_CHILD (1);
00811 TEST_CHILD (2);
00812 TEST_CHILD (3);
00813 break;
00814
00815 case 3:
00816 TEST_CHILD (0);
00817 TEST_CHILD (1);
00818 TEST_CHILD (2);
00819 break;
00820
00821 case 2:
00822 TEST_CHILD (0);
00823 TEST_CHILD (1);
00824 break;
00825
00826 case 1:
00827 TEST_CHILD (0);
00828 break;
00829
00830 case 0:
00831 default:
00832
00833 break;
00834 }
00835 #undef TEST_CHILD
00836 }
00837
00838 return 0;
00839 }
00840
00841
00842
00843 static void
00844 TB_update_up (tree node)
00845 {
00846 while (node)
00847 {
00848 walk_tree (&node, store_child_info, NULL, NULL);
00849
00850
00851 if (TREE_CODE (node) == FUNCTION_DECL)
00852 if (DECL_SAVED_TREE (node))
00853 walk_tree (&DECL_SAVED_TREE (node), store_child_info, NULL, NULL);
00854
00855
00856 node = TREE_CHAIN (node);
00857 }
00858 fprintf (TB_OUT_FILE, "Up/prev expressions updated.\n");
00859 }
00860
00861
00862
00863 static TB_CODE
00864 TB_get_command (char *input)
00865 {
00866 unsigned int mn, size_tok;
00867 int comp;
00868 char *space;
00869
00870 space = strchr (input, ' ');
00871 if (space != NULL)
00872 size_tok = strlen (input) - strlen (space);
00873 else
00874 size_tok = strlen (input) - 1;
00875
00876 for (mn = 0; mn < TB_UNUSED_COMMAND; mn++)
00877 {
00878 if (size_tok != TB_COMMAND_LEN (mn))
00879 continue;
00880
00881 comp = memcmp (input, TB_COMMAND_TEXT (mn), TB_COMMAND_LEN (mn));
00882 if (comp == 0)
00883
00884
00885 return TB_COMMAND_CODE (mn);
00886 }
00887
00888
00889 return TB_UNUSED_COMMAND;
00890 }
00891
00892
00893
00894 static enum tree_code
00895 TB_get_tree_code (char *input)
00896 {
00897 unsigned int mn, size_tok;
00898 int comp;
00899 char *space;
00900
00901 space = strchr (input, ' ');
00902 if (space != NULL)
00903 size_tok = strlen (input) - strlen (space);
00904 else
00905 size_tok = strlen (input) - 1;
00906
00907 for (mn = 0; mn < LAST_AND_UNUSED_TREE_CODE; mn++)
00908 {
00909 if (size_tok != TB_TREE_CODE_LEN (mn))
00910 continue;
00911
00912 comp = memcmp (input, TB_TREE_CODE_TEXT (mn), TB_TREE_CODE_LEN (mn));
00913 if (comp == 0)
00914 {
00915 fprintf (TB_OUT_FILE, "%s\n", TB_TREE_CODE_TEXT (mn));
00916 return TB_TREE_CODE (mn);
00917 }
00918 }
00919
00920
00921 return LAST_AND_UNUSED_TREE_CODE;
00922 }
00923
00924
00925
00926
00927 static tree
00928 find_node_with_code (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
00929 void *data)
00930 {
00931 enum tree_code *code;
00932 code = (enum tree_code *) data;
00933 if (*code == TREE_CODE (*tp))
00934 return *tp;
00935
00936 return NULL_TREE;
00937 }
00938
00939
00940
00941 static tree
00942 TB_history_prev (void)
00943 {
00944 if (TB_history_stack)
00945 {
00946 TB_history_stack = TREE_CHAIN (TB_history_stack);
00947 if (TB_history_stack)
00948 return TREE_VALUE (TB_history_stack);
00949 }
00950 return NULL_TREE;
00951 }
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961 static long
00962 TB_getline (char **lineptr, long *n, FILE *stream)
00963 {
00964 char *line, *p;
00965 long size, copy;
00966
00967 if (lineptr == NULL || n == NULL)
00968 {
00969 errno = EINVAL;
00970 return -1;
00971 }
00972
00973 if (ferror (stream))
00974 return -1;
00975
00976
00977 if (*lineptr == NULL || *n < 2)
00978 {
00979 #ifndef MAX_CANON
00980 #define MAX_CANON 256
00981 #endif
00982 line = (char *) xrealloc (*lineptr, MAX_CANON);
00983 if (line == NULL)
00984 return -1;
00985 *lineptr = line;
00986 *n = MAX_CANON;
00987 }
00988
00989 line = *lineptr;
00990 size = *n;
00991
00992 copy = size;
00993 p = line;
00994
00995 while (1)
00996 {
00997 long len;
00998
00999 while (--copy > 0)
01000 {
01001 register int c = getc (stream);
01002 if (c == EOF)
01003 goto lose;
01004 else if ((*p++ = c) == '\n')
01005 goto win;
01006 }
01007
01008
01009 len = p - line;
01010 size *= 2;
01011 line = (char *) xrealloc (line, size);
01012 if (line == NULL)
01013 goto lose;
01014 *lineptr = line;
01015 *n = size;
01016 p = line + len;
01017 copy = size - len;
01018 }
01019
01020 lose:
01021 if (p == *lineptr)
01022 return -1;
01023
01024
01025 win:
01026 #if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) || defined(MSDOS)
01027 if (p - 2 >= *lineptr && p[-2] == '\r')
01028 p[-2] = p[-1], --p;
01029 #endif
01030 *p = '\0';
01031 return p - *lineptr;
01032 }