Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
curr.wb_browser.cxx
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2 of the GNU General Public License as
00007   published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if 
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU General Public License along
00021   with this program; if not, write the Free Software Foundation, Inc., 59
00022   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00023 
00024   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00025   Mountain View, CA 94043, or:
00026 
00027   http://www.sgi.com
00028 
00029   For further information regarding this notice, see:
00030 
00031   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00032 
00033 */
00034 
00035 
00036 
00037 #ifdef USE_PCH
00038 #include "be_com_pch.h"
00039 #endif /* USE_PCH */
00040 #pragma hdrstop
00041 #include <sys/types.h>
00042 #include <elf.h>
00043 #include <ctype.h>
00044 #include "wn.h"
00045 #include "wn_map.h"
00046 #include "wn_util.h" 
00047 #include <stdio.h>
00048 #include "opt_du.h"
00049 #include "opt_alias_mgr.h"
00050 #include "dep_graph.h"
00051 #include "prompf.h"
00052 #include "ir_reader.h"
00053 #include "access_vector.h"
00054 #include "if_info.h"
00055 #include "loop_info.h"
00056 #include "wb_util.h"
00057 #include "wb_buffer.h"
00058 #include "wb_carray.h"
00059 #include "wb_browser.h"
00060 #include "whirl2src.h"
00061 
00062 
00063 #if defined(_GCC_NO_PRAGMAWEAK) || defined(__CYGWIN__)
00064 
00065 void WB_BROWSER::Summary(FILE *fp) { }
00066 void ACCESS_ARRAY::Print(FILE *, int) const { }
00067 void DO_LOOP_INFO_BASE::Print(FILE *, INT) { }
00068 void IF_INFO::Print(FILE *fp) { }
00069 
00070 #endif
00071 
00072 // Solaris CC workaround
00073 
00074 #if !defined(__GNUC__) && defined(_SOLARIS_SOLARIS)
00075 
00076 #pragma weak "__1cKWB_BROWSERHSummary6MpnG__FILE__v_"
00077 #pragma weak "__1cRDO_LOOP_INFO_BASEFPrint6MpnG__FILE_i_v_"
00078 #pragma weak "__1cMACCESS_ARRAYFPrint6kMpnG__FILE_i_v_"
00079 #pragma weak "__1cHIF_INFOFPrint6MpnG__FILE__v_"
00080 
00081 #elif !defined(__GNUC__)
00082 #pragma weak Id__13ALIAS_MANAGERCGPC2WN
00083 #pragma weak Print__12ACCESS_ARRAYCGP8__file_si
00084 #pragma weak Print__17DO_LOOP_INFO_BASEGP8__file_si
00085 #pragma weak Print__7IF_INFOGP8__file_s
00086 #pragma weak Summary__10WB_BROWSERGP8__file_s
00087 #else
00088 #pragma weak Print__17DO_LOOP_INFO_BASEP8_IO_FILEi
00089 #pragma weak Print__7IF_INFOP8_IO_FILE
00090 #pragma weak Print__C12ACCESS_ARRAYP8_IO_FILEi
00091 #pragma weak Print__C13ACCESS_VECTORP8_IO_FILEii
00092 #pragma weak Summary__10WB_BROWSERP8_IO_FILE
00093 
00094 // Solaris GNU g++ workaround - 
00095 // somehow when compiled with Solaris g++, the linker still complains undefined "WB_BROWSER::Summary"
00096 // and wb_browser.o showed the following symbols undefined, too! So I added them. This solution
00097 // seems to be better than making up a dummy funciton (?) 
00098 #pragma weak Print__17DO_LOOP_INFO_BASEP4FILEi
00099 #pragma weak Print__7IF_INFOP4FILE
00100 #pragma weak Print__C12ACCESS_ARRAYP4FILEi
00101 #pragma weak Summary__10WB_BROWSERP4FILE
00102 #endif
00103 
00104 static char *operator_table[OPERATOR_LAST + 1] =
00105 {
00106   "UNKNOWN",
00107   "ABS",
00108   "ADD",
00109   "AGOTO",
00110   "ALTENTRY",
00111   "ARRAY",
00112   "ARRAYEXP",
00113   "ARRSECTION",
00114   "ASHR",
00115   "ASSERT",
00116   "BACKWARD_BARRIER",
00117   "BAND",
00118   "BIOR",
00119   "BLOCK",
00120   "BNOR",
00121   "BNOT",
00122   "BXOR",
00123   "CALL",
00124   "CAND",
00125   "CASEGOTO",
00126   "CEIL",
00127   "CIOR",
00128   "COMMA",
00129   "COMMENT",
00130   "COMPGOTO",
00131   "COMPLEX",
00132   "CONST",
00133   "CSELECT",
00134   "CVT",
00135   "CVTL",
00136   "DIV",
00137   "DIVREM",
00138   "DO_LOOP",
00139   "DO_WHILE",
00140   "EQ",
00141   "EVAL",
00142   "EXC_SCOPE_BEGIN",
00143   "EXC_SCOPE_END",
00144   "FALSEBR",
00145   "FLOOR",
00146   "FORWARD_BARRIER",
00147   "FUNC_ENTRY",
00148   "GE",
00149   "GOTO",
00150   "GT",
00151   "HIGHMPY",
00152   "HIGHPART",
00153   "ICALL",
00154   "IDNAME",
00155   "IF",
00156   "ILDA",
00157   "ILDBITS",
00158   "ILOAD",
00159   "ILOADX",
00160   "IMAGPART",
00161   "INTCONST",
00162   "INTRINSIC_CALL",
00163   "INTRINSIC_OP",
00164   "IO",
00165   "IO_ITEM",
00166   "ISTBITS",
00167   "ISTORE",
00168   "ISTOREX",
00169   "LABEL",
00170   "LAND",
00171   "LDA",
00172   "LDBITS",
00173   "LDID",
00174   "LE",
00175   "LIOR",
00176   "LNOT",
00177   "LOOP_INFO",
00178   "LOWPART",
00179   "LSHR",
00180   "LT",
00181   "MADD",
00182   "MAX",
00183   "MAXPART",
00184   "MIN",
00185   "MINMAX",
00186   "MINPART",
00187   "MLOAD",
00188   "MOD",
00189   "MPY",
00190   "MSTORE",
00191   "MSUB",
00192   "NE",
00193   "NEG",
00194   "NMADD",
00195   "NMSUB",
00196   "OPTPARM",
00197   "OPT_CHI",
00198   "OPT_RESERVE2",
00199   "PAREN",
00200   "PARM",
00201   "PICCALL",
00202   "PRAGMA",
00203   "PREFETCH",
00204   "PREFETCHX",
00205   "RCOMMA",
00206   "REALPART",
00207   "RECIP",
00208   "REGION",
00209   "REGION_EXIT",
00210   "REM",
00211   "RETURN",
00212   "RETURN_VAL",
00213   "RND",
00214   "RSQRT",
00215   "SELECT",
00216   "SHL",
00217   "SQRT",
00218   "STBITS",
00219   "STID",
00220   "SUB",
00221   "SWITCH",
00222   "TAS",
00223   "TRAP",
00224   "TRIPLET",
00225   "TRUEBR",
00226   "TRUNC",
00227   "VFCALL",
00228   "WHERE",
00229   "WHILE_DO",
00230   "XGOTO",
00231   "XMPY",
00232   "XPRAGMA",
00233   "AFFIRM",
00234   "ALLOCA",
00235   "DEALLOCA",
00236   "LDMA"
00237 };
00238 
00239 //-----------------------------------------------------------------------
00240 // NAME: WB_BROWSER::WB_BROWSER
00241 // FUNCTION: Default constructor for Whirl Browser 
00242 //-----------------------------------------------------------------------
00243 
00244 WB_BROWSER::WB_BROWSER()
00245 {
00246    _global_fd = NULL; 
00247    _du = NULL; 
00248    _alias_mgr = NULL; 
00249    _command_list = NULL; 
00250    _old_command_list = NULL; 
00251    _is_subcommand = FALSE; 
00252    _dg = NULL; 
00253    _parent_map = WN_MAP_UNDEFINED; 
00254    _prompf_id_map = WN_MAP_UNDEFINED; 
00255    _access_array_map = WN_MAP_UNDEFINED;
00256    _reduction_map = WN_MAP_UNDEFINED;
00257    _pu = NULL; 
00258    _prompf_info = NULL; 
00259    _scalar_summary = NULL; 
00260    _array_summary = NULL; 
00261    _cnode = NULL; 
00262    _fancy_level = 2; 
00263    _source_language = WB_SRC_NONE; 
00264    _sanity_check_level = 0; 
00265    for (INT i = 0; i < WB_ASCII_CHAR_COUNT; i++) 
00266      _keymap[i] = i; 
00267 }
00268 
00269 //-----------------------------------------------------------------------
00270 // NAME: WB_BROWSER::Unmappable_Character
00271 // FUNCTION: Return TRUE if the character 'ch' is not remappable in the
00272 //   .wb_keymap file.  Return FALSE otherwise.
00273 //-----------------------------------------------------------------------
00274 
00275 BOOL WB_BROWSER::Unmappable_Character(char ch)
00276 {
00277   switch (ch) {
00278   case ' ':
00279   case '\t':
00280   case '\n':
00281   case 'Q':
00282   case 'q':
00283   case 'H':
00284   case 'h':
00285     return TRUE;
00286   default:
00287     return FALSE;
00288   }
00289 }
00290 
00291 //-----------------------------------------------------------------------
00292 // NAME: WB_BROWSER::WB_BROWSER
00293 // FUNCTION: Constructor for Whirl Browser 
00294 //-----------------------------------------------------------------------
00295 
00296 WB_BROWSER::WB_BROWSER(WN* global_fd, 
00297                        DU_MANAGER* du, 
00298                        ALIAS_MANAGER* alias_mgr,
00299                        WN_MAP prompf_id_map, 
00300                        WN_MAP access_array_map, 
00301                        WN_MAP reduction_map, 
00302                        PU* pu, 
00303                        WB_COMMAND* command_list) : 
00304    _global_fd(global_fd), _du(du), _alias_mgr(alias_mgr),
00305    _prompf_id_map(prompf_id_map), _access_array_map(access_array_map),
00306    _reduction_map(reduction_map), _pu(pu), _command_list(command_list)
00307 {
00308    _old_command_list = NULL; 
00309    _is_subcommand = FALSE; 
00310    _dg = NULL; 
00311    _parent_map = WN_MAP_UNDEFINED; 
00312    _prompf_info = NULL; 
00313    _scalar_summary = NULL; 
00314    _array_summary = NULL; 
00315    _cnode = global_fd; 
00316    _fancy_level = 2; 
00317    _source_language = WB_SRC_NONE; 
00318    _sanity_check_level = 0; 
00319    for (INT i = 0; i < WB_ASCII_CHAR_COUNT; i++) 
00320      _keymap[i] = i; 
00321 }
00322 
00323 //-----------------------------------------------------------------------
00324 // NAME: WB_BROWSER::This_Node
00325 // FUNCTION: Write the address of 'wn' and its whirl symbol to 'stdout'.
00326 //-----------------------------------------------------------------------
00327 
00328 void WB_BROWSER::This_Node(WN* wn, 
00329                            BOOL print_vertex,
00330                            BOOL print_brackets)
00331 {
00332   if (wn == NULL) {
00333     fprintf(stdout, "<NULL>");
00334     return;
00335   }
00336   const char* ch = OPCODE_name(WN_opcode(wn));
00337   if (print_brackets)
00338     fprintf(stdout, "[0x%p] ", wn);
00339   else 
00340     fprintf(stdout, "0x%p ", wn);
00341   if (print_vertex && Dg() != NULL && Dg()->Get_Vertex(wn) != 0)
00342     fprintf(stdout, "V#%d ", Dg()->Get_Vertex(wn));
00343   fprintf(stdout, "%s ", ch);
00344   if (Fancy_Level() >= 3)
00345     if (OPCODE_has_next_prev(WN_opcode(wn)))
00346       fprintf(stdout, "(%d) ", (INT) WN_linenum(wn));
00347   if (Fancy_Level() >= 3 && Prompf_Id_Map() == -1) 
00348     fprintf(stdout, "<%d> ", WN_MAP32_Get(Prompf_Id_Map(), wn));
00349   if (WN_operator(wn) == OPR_INTCONST) {
00350     fprintf(stdout, "%lld ", WN_const_val(wn));
00351   } else {
00352     const char* wn_symbol = WB_Whirl_Symbol(wn);
00353     if (wn_symbol != NULL)
00354       fprintf(stdout, "%s ", wn_symbol);
00355   }
00356 }
00357 
00358 //-----------------------------------------------------------------------
00359 // NAME: WB_BROWSER::Print_This_Node
00360 // FUNCTION: Print the node 'wn' and a newline.
00361 //-----------------------------------------------------------------------
00362 
00363 void WB_BROWSER::Print_This_Node(WN* wn, 
00364                                  BOOL print_vertex,
00365                                  BOOL print_brackets)
00366 {
00367   This_Node(wn, print_vertex, print_brackets);
00368   fprintf(stdout, "\n");
00369 }
00370 
00371 //-----------------------------------------------------------------------
00372 // NAME: Address_Walk
00373 // FUNCTION: Walk the tree rooted at 'wn_tree', printing the adddresses
00374 //   of all of the nodes in the subtree, with a short description of each
00375 //   node.
00376 //-----------------------------------------------------------------------
00377 
00378 void WB_BROWSER::Address_Walk(WN* wn_tree,
00379                               INT spaces,
00380                               INT increment)
00381 { 
00382   for (INT i = 0; i < spaces; i++)
00383     fprintf(stdout, " ");
00384   Print_This_Node(wn_tree, FALSE, TRUE);
00385 
00386   if (WN_opcode(wn_tree) == OPC_BLOCK) {
00387     for (WN* wn = WN_first(wn_tree); wn != NULL; wn = WN_next(wn))
00388       Address_Walk(wn, spaces + increment, increment);
00389   } else {
00390     for (INT i = 0; i < WN_kid_count(wn_tree); i++)
00391       Address_Walk(WN_kid(wn_tree, i), spaces + increment, increment);
00392   }
00393 }
00394 
00395 //-----------------------------------------------------------------------
00396 // NAME: WB_BROWSER::Addresses
00397 // WHIRL BROWSER COMMAND: '%'
00398 // FUNCTION: Print the addresses of nodes in this subtree
00399 //-----------------------------------------------------------------------
00400 
00401 void WB_BROWSER::Addresses()
00402 {
00403   Address_Walk(Cnode(), 0, 2);
00404 }
00405 
00406 //-----------------------------------------------------------------------
00407 // NAME: WB_BROWSER::Error_Cleanup
00408 // FUNCTION: Sound the bell, write the prompt to 'stdout' and reload the
00409 //   input buffer, scanning past blanks and tabs.
00410 //-----------------------------------------------------------------------
00411 
00412 void WB_BROWSER::Error_Cleanup()
00413 { 
00414   WB_Bell();
00415   WB_Prompt();
00416   Buffer().Load_Buffer();
00417   Buffer().Scan_Blanks_And_Tabs();
00418 }
00419 
00420 //-----------------------------------------------------------------------
00421 // NAME: WB_BROWSER::Root
00422 // WHIRL BROWSER COMMAND: 'R'
00423 // FUNCTION: Go to the root of the program unit
00424 //-----------------------------------------------------------------------
00425 
00426 void WB_BROWSER::Root()
00427 {
00428   Set_Cnode(Global_Fd());
00429   Print_This_Node(Cnode());
00430 }
00431 
00432 //-----------------------------------------------------------------------
00433 // NAME: WB_BROWSER::Next
00434 // WHIRL BROWSER COMMAND: 'N'
00435 // FUNCTION: Go to the next node in the subtree chain
00436 //-----------------------------------------------------------------------
00437 
00438 void WB_BROWSER::Next()
00439 {
00440   WN* pnode = WN_next(Cnode());
00441   if (pnode == NULL) {
00442     Error_Cleanup();
00443     return;
00444   }
00445   Set_Cnode(pnode);
00446   Print_This_Node(Cnode());
00447 }
00448 
00449 //-----------------------------------------------------------------------
00450 // NAME: WB_BROWSER::Previous
00451 // WHIRL BROWSER COMMAND: 'P'
00452 // FUNCTION: Go to the previous node in the subtree chain
00453 //-----------------------------------------------------------------------
00454 
00455 void WB_BROWSER::Previous()
00456 {
00457   WN* pnode = WN_prev(Cnode());
00458   if (pnode == NULL)  {
00459     Error_Cleanup();
00460     return;
00461   }
00462   Set_Cnode(pnode);
00463   Print_This_Node(Cnode());
00464 }
00465 
00466 //-----------------------------------------------------------------------
00467 // NAME: WB_BROWSER::Set_Node()
00468 // WHIRL BROWSER COMMAND: '='
00469 // FUNCTION: Set the current node to the following address
00470 //-----------------------------------------------------------------------
00471 
00472 void WB_BROWSER::Set_Node()
00473 {
00474   INT node;
00475   Buffer().Scan_HexInteger(&node);
00476   Set_Cnode((WN*) node);
00477   Print_This_Node(Cnode());
00478 }
00479 
00480 //-----------------------------------------------------------------------
00481 // NAME: WB_BROWSER::Address()
00482 // WHIRL BROWSER COMMAND: '@'
00483 // FUNCTION: Set the current node to this numbered node
00484 //-----------------------------------------------------------------------
00485 
00486 void WB_BROWSER::Address()
00487 {
00488   INT integer;
00489   Buffer().Scan_Integer(&integer);
00490   if (integer < 0 || integer >= Carray().Next_Index()) {
00491     Error_Cleanup();
00492     return;
00493   }
00494   Set_Cnode(Carray().Element(integer));
00495   Print_This_Node(Cnode());
00496 }
00497 
00498 //-----------------------------------------------------------------------
00499 // NAME: WB_BROWSER::Fancy_Up()
00500 // WHIRL BROWSER COMMAND: '>'
00501 // FUNCTION: Increase fanciness level for printing
00502 //-----------------------------------------------------------------------
00503 
00504 void WB_BROWSER::Fancy_Up()
00505 {
00506   const INT fancy_max = 3; 
00507   if (Fancy_Level() == fancy_max) { 
00508     Error_Cleanup();
00509     return;
00510   }
00511   INT fancy_level = Fancy_Level(); 
00512   Set_Fancy_Level(++fancy_level);
00513 }
00514 
00515 //-----------------------------------------------------------------------
00516 // NAME: WB_BROWSER::Fancy_Down()
00517 // WHIRL BROWSER COMMAND: '<'
00518 // FUNCTION: Decrease fanciness level for printing
00519 //-----------------------------------------------------------------------
00520 
00521 void WB_BROWSER::Fancy_Down()
00522 {
00523   const INT fancy_min = 2; 
00524   if (Fancy_Level() == fancy_min) { 
00525     Error_Cleanup();
00526     return;
00527   }
00528   INT fancy_level = Fancy_Level(); 
00529   Set_Fancy_Level(--fancy_level);
00530 }
00531 
00532 //-----------------------------------------------------------------------
00533 // NAME: WB_BROWSER::Kids()
00534 // WHIRL BROWSER COMMAND: 'K'
00535 // FUNCTION: Print the kids of this node
00536 //-----------------------------------------------------------------------
00537 
00538 void WB_BROWSER::Kids()
00539 {
00540   if (WN_kid_count(Cnode()) == 0) {
00541     Error_Cleanup();
00542     return;
00543   }
00544   Carray().Reset_Index(); 
00545   for (INT i = 0; i < WN_kid_count(Cnode()); i++) {
00546     WN* kid = WN_kid(Cnode(), i);
00547     fprintf(stdout, "[%d] ", i);
00548     This_Node(kid); 
00549     Carray().Enter_This_Node(kid);
00550     fprintf(stdout, "\n");
00551   }
00552 }
00553 
00554 //-----------------------------------------------------------------------
00555 // NAME: WB_BROWSER::Statements()
00556 // WHIRL BROWSER COMMAND: 'S'
00557 // FUNCTION: Print the list of statements under this node
00558 //-----------------------------------------------------------------------
00559 
00560 void WB_BROWSER::Statements()
00561 {
00562   INT i = 0;
00563   if (WN_opcode(Cnode()) != OPC_BLOCK) {
00564     Error_Cleanup();
00565     return;
00566   }
00567   if (WN_first(Cnode()) == NULL) {
00568     Error_Cleanup();
00569     return;
00570   }
00571   Carray().Reset_Index(); 
00572   for (WN* node = WN_first(Cnode()); node != NULL; i++, node = WN_next(node)) {
00573     fprintf(stdout, "[%d] ", i);
00574     This_Node(node); 
00575     Carray().Enter_This_Node(node);
00576     fprintf(stdout, "\n");
00577   }
00578 }
00579 
00580 //-----------------------------------------------------------------------
00581 // NAME: WB_BROWSER::This_Tree()
00582 // WHIRL BROWSER COMMAND: 'T'
00583 // FUNCTION: Print the tree at the current node
00584 //-----------------------------------------------------------------------
00585 
00586 void WB_BROWSER::This_Tree()
00587 {
00588   if (Cnode() == NULL) {
00589     Error_Cleanup();
00590     return;
00591   }
00592   dump_tree(Cnode());
00593 }
00594 
00595 //-----------------------------------------------------------------------
00596 // NAME: Compute_ST_IDX
00597 // FUNCTION: Convert a <'st_level','st_index'> to its ST_IDX and return
00598 //   the value.
00599 //-----------------------------------------------------------------------
00600 
00601 extern ST_IDX Compute_ST_IDX(UINT32 st_level,
00602                              UINT32 st_index)
00603 {
00604   UINT32 st_idx = st_level + (st_index << 8);
00605   return (ST_IDX) (st_idx);
00606 }
00607 
00608 //-----------------------------------------------------------------------
00609 // NAME: WB_BROWSER::Symbol()
00610 // WHIRL BROWSER COMMAND: 's'
00611 // FUNCTION: Print the symbol table entry for this node
00612 //-----------------------------------------------------------------------
00613 
00614 void WB_BROWSER::Symbol()
00615 {
00616   if (Buffer().Is('<')) { 
00617     UINT32 st_level;
00618     UINT32 st_index;
00619     Buffer().Scan_Character();
00620     Buffer().Scan_Unsigned(&st_level);
00621     char separator = Buffer().Scan_Character();
00622     if (separator != ',') {
00623       Error_Cleanup();
00624       return;
00625     }
00626     Buffer().Scan_Unsigned(&st_index);
00627     char right_angle_bracket = Buffer().Scan_Character();
00628     if (right_angle_bracket != '>') {
00629       Error_Cleanup();
00630       return; 
00631     }
00632     ST_IDX st_idx = Compute_ST_IDX(st_level, st_index);
00633     ST* st = &St_Table[st_idx];
00634     fprintf(stdout, "ST_IDX: %d\n", st_idx);
00635     Print_ST(stdout, st, TRUE);
00636   } else if (Buffer().Is_Integer()) { 
00637     ST_IDX st_idx;
00638     Buffer().Scan_Unsigned(&st_idx);
00639     ST* st = &St_Table[st_idx];
00640     fprintf(stdout, "ST_IDX: %d\n", st_idx);
00641     Print_ST(stdout, st, TRUE);
00642   } else {  
00643     if (!OPCODE_has_sym(WN_opcode(Cnode()))) {
00644       Error_Cleanup();
00645       return;
00646     }
00647     Print_ST(stdout, WN_st(Cnode()), TRUE);
00648   } 
00649 }
00650 
00651 //-----------------------------------------------------------------------
00652 // NAME: WB_BROWSER::Type()
00653 // WHIRL BROWSER COMMAND: 't'
00654 // FUNCTION: Print the type table entry for this node
00655 //-----------------------------------------------------------------------
00656 
00657 void WB_BROWSER::Type()
00658 {
00659   if (Buffer().Is('<')) { 
00660     UINT32 ty_index = 0;
00661     Buffer().Scan_Character();
00662     Buffer().Scan_Unsigned(&ty_index);
00663     char right_angle_bracket = Buffer().Scan_Character();
00664     if (right_angle_bracket != '>') {
00665       Error_Cleanup();
00666       return;
00667     } 
00668     Ty_tab[ty_index].Print(stdout);
00669   } else if (Buffer().Is_Integer()) { 
00670     TY_IDX ty_idx = 0;
00671     Buffer().Scan_Unsigned(&ty_idx);
00672     Print_TY(stdout, ty_idx);
00673   } else { 
00674     if (!OPCODE_has_sym(WN_opcode(Cnode()))) {
00675       Error_Cleanup();
00676       return;
00677     }
00678     Ty_Table[ST_type(WN_st(Cnode()))].Print(stdout);
00679   }
00680 }
00681 
00682 //-----------------------------------------------------------------------
00683 // NAME: Is_Substring
00684 // FUNCTION: Return TRUE if 's1' is a substring of 's2', return FALSE
00685 //   otherwise.
00686 //-----------------------------------------------------------------------
00687 
00688 static BOOL Is_Substring(char s1[],
00689                          char s2[])
00690 {
00691   INT substring_length = strlen(s1);
00692   INT string_length = strlen(s2);
00693   INT difference = string_length - substring_length;
00694   if (substring_length > string_length)
00695     return FALSE;
00696   INT i, j;
00697   for (i = 0; i <= difference; i++) {
00698     for (j = 0; j < substring_length; j++)
00699       if (s1[j] != s2[i + j])
00700         break;
00701     if (j == substring_length)
00702       return TRUE;
00703   }
00704   return FALSE;
00705 }
00706 
00707 //-----------------------------------------------------------------------
00708 // NAME: WB_BROWSER::Find()
00709 // WHIRL BROWSER COMMAND: 'F'
00710 // FUNCTION: Find nodes with this symbol in the subtree
00711 //-----------------------------------------------------------------------
00712 
00713 void WB_BROWSER::Find_Walk(char *s, WN* wn)
00714 {
00715   if (wn == NULL)
00716     return;
00717   char* wn_symbol = (char *) WB_Whirl_Symbol(wn);
00718   BOOL test_substring = s[0] == '\'';
00719   if (wn_symbol != NULL && (!test_substring && strcmp(wn_symbol, s) == 0
00720       || test_substring && Is_Substring(&s[1], wn_symbol))) {
00721     fprintf(stdout, "[%d] ", Carray().Next_Index());
00722     This_Node(wn); 
00723     Carray().Enter_This_Node(wn);
00724     fprintf(stdout, "\n");
00725   }
00726   for (INT i = 0; i < WN_kid_count(wn); i++)
00727     Find_Walk(s, WN_kid(wn, i));
00728   if (WN_opcode(wn) == OPC_BLOCK)
00729     for (WN* wn_sub = WN_first(wn); wn_sub != NULL; wn_sub = WN_next(wn_sub))
00730       Find_Walk(s, wn_sub);
00731 }
00732 
00733 void WB_BROWSER::Find()
00734 {
00735   char s[WB_MAX_STRING_LENGTH];
00736   Buffer().Scan_Alphanumeric(s);
00737   Carray().Reset_Index(); 
00738   Find_Walk(s, Cnode());
00739 }
00740 
00741 //-----------------------------------------------------------------------
00742 // NAME: WB_BROWSER::Find_Operator()
00743 // WHIRL BROWSER COMMAND: 'o'
00744 // FUNCTION: Find nodes with this operator in the subtree
00745 //-----------------------------------------------------------------------
00746 
00747 void WB_BROWSER::Find_Operator_Walk(OPERATOR opr_test, WN* wn)
00748 {
00749   if (wn == NULL)
00750     return;
00751   if (WN_operator(wn) == opr_test) {
00752     fprintf(stdout, "[%d] ", Carray().Next_Index());
00753     This_Node(wn); 
00754     Carray().Enter_This_Node(wn);
00755     fprintf(stdout, "\n");
00756   }
00757   if (WN_opcode(wn) == OPC_BLOCK) { 
00758     for (WN* wn_sub = WN_first(wn); wn_sub != NULL; wn_sub = WN_next(wn_sub))
00759       Find_Operator_Walk(opr_test, wn_sub);
00760   } else { 
00761     for (INT i = 0; i < WN_kid_count(wn); i++)
00762       Find_Operator_Walk(opr_test, WN_kid(wn, i));
00763   } 
00764 }
00765 
00766 void WB_BROWSER::Find_Operator()
00767 {
00768   char s[WB_MAX_STRING_LENGTH];
00769   Buffer().Scan_Alphanumeric(s);
00770   INT i;
00771   for (i = 1; i <= OPERATOR_LAST; i++)
00772     if (!strcmp(s, operator_table[i]))
00773       break;
00774   if (i > OPERATOR_LAST) {
00775     Error_Cleanup();
00776     return; 
00777   } 
00778   Carray().Reset_Index(); 
00779   Find_Operator_Walk((OPERATOR) i, Cnode());
00780 }
00781 
00782 //-----------------------------------------------------------------------
00783 // NAME: WB_BROWSER::Uses()
00784 // WHIRL BROWSER COMMAND: 'U'
00785 // FUNCTION: Print the uses at the current node
00786 //-----------------------------------------------------------------------
00787 
00788 void WB_BROWSER::Uses()
00789 {
00790   if (Du() == NULL) {
00791     Error_Cleanup();
00792     return;
00793   }
00794   USE_LIST *use_list = Du()->Du_Get_Use(Cnode());
00795   if (use_list == NULL) {
00796     Error_Cleanup();
00797     return;
00798   }
00799   Carray().Reset_Index();
00800   if (use_list->Incomplete())
00801     fprintf(stdout, "WARNING: USE LIST INCOMPLETE\n");
00802   USE_LIST_ITER iter(use_list);
00803   const DU_NODE* node = NULL;
00804   INT i = 0;
00805   for (node = iter.First(); !iter.Is_Empty(); node = iter.Next()) {
00806     WN* use = node->Wn();
00807     fprintf(stdout, "[%d] ", i++);
00808     Print_This_Node(use);
00809     Carray().Enter_This_Node(use);
00810   }
00811 }
00812 
00813 //-----------------------------------------------------------------------
00814 // NAME: WB_BROWSER::Defs
00815 // WHIRL BROWSER COMMAND: 'D'
00816 // FUNCTION: Print the definitions at the current node
00817 //-----------------------------------------------------------------------
00818 
00819 void WB_BROWSER::Defs()
00820 {
00821   if (Du() == NULL) {
00822     Error_Cleanup();
00823     return;
00824   }
00825   DEF_LIST* def_list = Du()->Ud_Get_Def(Cnode());
00826   if (def_list == NULL) {
00827     Error_Cleanup();
00828     return;
00829   }
00830   if (def_list->Incomplete())
00831     fprintf(stdout, "WARNING: DEF LIST INCOMPLETE\n");
00832   fprintf(stdout, "Loop Statement: 0x%p\n", def_list->Loop_stmt());
00833   DEF_LIST_ITER iter(def_list);
00834   const DU_NODE* node = NULL;
00835   INT i = 0;
00836   for (node = iter.First(); !iter.Is_Empty(); node = iter.Next()) {
00837     WN* def = node->Wn();
00838     fprintf(stdout, "[%d] ", i++);
00839     Print_This_Node(def);
00840     Carray().Enter_This_Node(def);
00841   }
00842 }
00843 
00844 //-----------------------------------------------------------------------
00845 // NAME: WB_BROWSER::Access_Array()
00846 // WHIRL BROWSER COMMAND: 'A'
00847 // FUNCTION: Print the access array info for this node
00848 //-----------------------------------------------------------------------
00849 
00850 void WB_BROWSER::Access_Array()
00851 {
00852   if (Access_Array_Map() == -1) { 
00853     Error_Cleanup();
00854     return; 
00855   } 
00856   if (WN_operator(Cnode()) == OPR_ARRAY) { 
00857     ACCESS_ARRAY *array 
00858       = (ACCESS_ARRAY *) WN_MAP_Get(Access_Array_Map(), Cnode());
00859     if (array != NULL) {
00860       fprintf(stdout, "The access array is \n"); 
00861       array->Print(stdout);
00862     } else {
00863       fprintf(stdout, "Null ACCESS_ARRAY\n");
00864     }
00865   } else if (WN_operator(Cnode()) == OPR_IF) { 
00866     IF_INFO *info = (IF_INFO *) WN_MAP_Get(Access_Array_Map(), Cnode());
00867     if (info != NULL) {
00868       fprintf(stdout, "The if info is \n"); 
00869       info->Print(stdout);
00870     } else {
00871       fprintf(stdout, "Null IF_INFO\n");
00872     }
00873   } else if (WN_operator(Cnode()) == OPR_DO_LOOP) { 
00874     DO_LOOP_INFO_BASE* info 
00875       = (DO_LOOP_INFO_BASE*) WN_MAP_Get(Access_Array_Map(), Cnode());
00876     if (info != NULL) {
00877       fprintf(stdout, "The loop info is \n");
00878       info->Print(stdout);
00879     } else {
00880       fprintf(stdout, "NulleDO_LOOP_INFO_BASE\n");
00881     }
00882   } else { 
00883     Error_Cleanup();
00884   }  
00885 } 
00886 
00887 //-----------------------------------------------------------------------
00888 // NAME: WB_BROWSER::Reduction()
00889 // WHIRL BROWSER COMMAND: 'r'
00890 // FUNCTION: Print the reduction manager
00891 //-----------------------------------------------------------------------
00892 
00893 void WB_BROWSER::Reduction_Node(WN* wn, 
00894                                 FILE* fp)
00895 { 
00896   if (OPCODE_is_load(WN_opcode(wn)) || OPCODE_is_store(WN_opcode(wn))) {
00897     INT32 red_type = WN_MAP32_Get(Reduction_Map(), wn);
00898     switch (red_type) {
00899     case RED_ADD:
00900       fprintf(fp, "[%d] 0x%p RED_ADD ", Carray().Next_Index(), wn);
00901       break;
00902     case RED_MPY:
00903       fprintf(fp, "[%d] 0x%p RED_MPY ", Carray().Next_Index(), wn);
00904       break;
00905     case RED_MIN:
00906       fprintf(fp, "[%d] 0x%p RED_MIN ", Carray().Next_Index(), wn);
00907       break;
00908     case RED_MAX:
00909       fprintf(fp, "[%d] 0x%p RED_MAX ", Carray().Next_Index(), wn);
00910       break;
00911     }
00912     switch (red_type) {
00913     case RED_ADD:
00914     case RED_MPY:
00915     case RED_MIN:
00916     case RED_MAX:
00917       OPERATOR oper = WN_operator(wn);
00918       if (oper == OPR_ILOAD || oper == OPR_ISTORE) {
00919         Dep_Symbol(wn);
00920         fprintf(fp, "\n");
00921       } else {
00922         const char *name = WB_Whirl_Symbol(wn);
00923         fprintf(fp, "%s\n", name);
00924       }
00925       Carray().Enter_This_Node(wn);
00926       break;
00927     }
00928   }
00929 } 
00930 
00931 void WB_BROWSER::Reduction_Walk(WN* wn_tree, 
00932                                 FILE* fp) 
00933 {
00934   if (WN_operator(wn_tree) == OPR_BLOCK) { 
00935     for (WN* wn = WN_first(wn_tree); wn != NULL; wn = WN_next(wn))  
00936       Reduction_Walk(wn, fp);
00937   } else { 
00938     Reduction_Node(wn_tree, fp);
00939     for (INT i = 0; i < WN_kid_count(wn_tree); i++)
00940       Reduction_Walk(WN_kid(wn_tree, i), fp);
00941   } 
00942 } 
00943 
00944 void WB_BROWSER::Reduction()
00945 { 
00946   if (Reduction_Map() == WN_MAP_UNDEFINED) { 
00947     Error_Cleanup();
00948     return;
00949   } 
00950   Carray().Reset_Index();
00951   Reduction_Walk(Cnode(), stdout);
00952 } 
00953 
00954 //-----------------------------------------------------------------------
00955 // NAME: WB_BROWSER::Alias()
00956 // WHIRL BROWSER COMMAND: 'a'
00957 // FUNCTION: Print the alias info for this node
00958 //-----------------------------------------------------------------------
00959 
00960 BOOL WB_BROWSER::Aliased_Node(WN* wn)
00961 {
00962   OPCODE opc = WN_opcode(wn);
00963   OPERATOR opr = OPCODE_operator(opc);
00964   return (OPCODE_is_load(opc) || OPCODE_is_store(opc) || opr == OPR_PARM)
00965     && Alias_Mgr()->Id(wn) != 0;
00966 }
00967 
00968 void WB_BROWSER::Alias_Walk(WN* wn_test,
00969                             WN* wn_start,
00970                             ALIAS_RESULT ar)
00971 {
00972   if (Aliased_Node(wn_start)) {
00973     ALIAS_RESULT result = Aliased(Alias_Mgr(), wn_test, wn_start);
00974     switch (result) {
00975     case NOT_ALIASED:
00976       break;
00977     case POSSIBLY_ALIASED:
00978     case SAME_LOCATION:
00979       if (ar == result) {
00980         fprintf(stdout, "  [%d] ", Carray().Next_Index());
00981         Print_This_Node(wn_start);
00982         Carray().Enter_This_Node(wn_start);
00983       }
00984       break;
00985     }
00986   }
00987 
00988   if (WN_opcode(wn_start) == OPC_BLOCK) {
00989     for (WN* wn = WN_first(wn_start); wn != NULL; wn = WN_next(wn))
00990       Alias_Walk(wn_test, wn, ar);
00991   } else {
00992     for (INT i = 0; i < WN_kid_count(wn_start); i++)
00993       Alias_Walk(wn_test, WN_kid(wn_start, i), ar);
00994   }
00995 }
00996 
00997 void WB_BROWSER::Alias()
00998 {
00999   if (!Aliased_Node(Cnode())) {
01000     Error_Cleanup();
01001     return;
01002   }
01003   Carray().Reset_Index();
01004   fprintf(stdout, "POSSIBLY ALIASED: \n");
01005   Alias_Walk(Cnode(), Global_Fd(), POSSIBLY_ALIASED);
01006   if (Carray().Next_Index() == 0)
01007     fprintf(stdout, "  NO LOCATIONS\n");
01008   INT possible_aliases = Carray().Next_Index();
01009   fprintf(stdout, "SAME LOCATION: \n");
01010   Alias_Walk(Cnode(), Global_Fd(), SAME_LOCATION);
01011   if (Carray().Next_Index() == possible_aliases)
01012     fprintf(stdout, "  NO LOCATIONS\n");
01013 }
01014 
01015 //-----------------------------------------------------------------------
01016 // NAME: WB_Parent_Search
01017 // FUNCTION: For the tree rooted at 'wn_root', find the path of nodes
01018 //   leading from this node to 'wn_node' and push it on the stack
01019 //   'stk_parent'.  If there is no path from 'wn_root' to 'wn_node',
01020 //   return an empty stack.
01021 //-----------------------------------------------------------------------
01022 
01023 static BOOL WB_Parent_Search(WN* wn_root,
01024                              STACK<WN*>* stk_parent,
01025                              WN* wn_node)
01026 {
01027   stk_parent->Push(wn_root);
01028   if (wn_root == wn_node)
01029     return TRUE;
01030   if (WN_opcode(wn_root) == OPC_BLOCK) {
01031     for (WN* wn = WN_first(wn_root); wn != NULL; wn = WN_next(wn)) {
01032       BOOL found_path = WB_Parent_Search(wn, stk_parent, wn_node);
01033       if (found_path)
01034         return TRUE;
01035     }
01036   } else {
01037     for (INT i = 0; i < WN_kid_count(wn_root); i++) {
01038       BOOL found_path = WB_Parent_Search(WN_kid(wn_root, i), stk_parent,
01039         wn_node);
01040       if (found_path)
01041         return TRUE;
01042     }
01043   }
01044   stk_parent->Pop();
01045   return FALSE;
01046 }
01047 
01048 //-----------------------------------------------------------------------
01049 // NAME: WB_BROWSER::Parent
01050 // WHIRL BROWSER COMMAND: 'E'
01051 // FUNCTION: Go to the parent of the current node
01052 //-----------------------------------------------------------------------
01053 
01054 void WB_BROWSER::Parent()
01055 {
01056   if (Cnode() == Global_Fd()) {
01057     Error_Cleanup();
01058     return;
01059   }
01060   if (Parent_Map() == -1) {
01061     MEM_POOL_Push(&MEM_local_pool);
01062     STACK<WN*> stk_parent(&MEM_local_pool);
01063     BOOL found_path = WB_Parent_Search(Global_Fd(), &stk_parent, Cnode());
01064     if (!found_path) {
01065       Error_Cleanup();
01066       MEM_POOL_Pop(&MEM_local_pool);
01067       return;
01068     }
01069     Set_Cnode(stk_parent.Bottom_nth(stk_parent.Elements() - 2));
01070     Print_This_Node(Cnode());
01071     MEM_POOL_Pop(&MEM_local_pool);
01072   } else {
01073     WN* pnode = (WN*) WN_MAP_Get(Parent_Map(), Cnode());
01074     if (pnode == NULL) {
01075       Error_Cleanup();
01076       return;
01077     }
01078     Set_Cnode(pnode);
01079     Print_This_Node(Cnode());
01080   }
01081 }
01082 
01083 //-----------------------------------------------------------------------
01084 // NAME: WB_BROWSER:Ancestors
01085 // WHIRL BROWSER COMMAND: 'e'
01086 // FUNCTION: Print the ancestors of this node
01087 //-----------------------------------------------------------------------
01088 
01089 void WB_BROWSER::Ancestors()
01090 {
01091   if (Cnode() == Global_Fd()) {
01092     Error_Cleanup();
01093     return;
01094   }
01095   if (Parent_Map() == -1) {
01096     Carray().Reset_Index();
01097     MEM_POOL_Push(&MEM_local_pool);
01098     STACK<WN*> stk_parent(&MEM_local_pool);
01099     BOOL found_path = WB_Parent_Search(Global_Fd(), &stk_parent, Cnode());
01100     if (!found_path) {
01101       Error_Cleanup();
01102       MEM_POOL_Pop(&MEM_local_pool);
01103       return;
01104     }
01105     INT i = 0; 
01106     for (INT j = stk_parent.Elements() - 1; j >= 0; j--) {
01107       Carray().Enter_This_Node(stk_parent.Bottom_nth(j));
01108       fprintf(stdout, "[%d] ", i++);
01109       Print_This_Node(stk_parent.Bottom_nth(j));
01110     }
01111     MEM_POOL_Pop(&MEM_local_pool);
01112   } else {
01113     Carray().Reset_Index();
01114     WN* wnn = NULL; 
01115     INT i = 0; 
01116     for (WN* wn = Cnode(); wn != NULL; wn = wnn) {
01117       wnn = ((WN*) WN_MAP_Get(Parent_Map(), (WN*) wn)); 
01118       Carray().Enter_This_Node(wn);
01119       fprintf(stdout, "[%d] ", i++);
01120       Print_This_Node(wn);
01121     }
01122   }
01123 }
01124 
01125 //-----------------------------------------------------------------------
01126 // NAME: WB_BROWSER::Promp_Map
01127 // WHIRL BROWSER COMMAND: 'i'
01128 // FUNCTION: Print the PROMPF ids for tree at this node
01129 //-----------------------------------------------------------------------
01130 
01131 void WB_BROWSER::Promp_Map()
01132 {
01133   if (Prompf_Id_Map() == -1) {
01134     Error_Cleanup();
01135     return;
01136   }
01137   Carray().Reset_Index();
01138   WN_ITER* itr = WN_WALK_TreeIter(Cnode());
01139   for (INT i = 0; itr != NULL; itr = WN_WALK_TreeNext(itr)) {
01140     WN* wn = itr->wn;
01141     INT32 map_id = WN_MAP32_Get(Prompf_Id_Map(), wn);
01142     if (map_id != 0) {
01143       fprintf(stdout, "[%d] %3d ", i++, map_id);
01144       Print_This_Node(wn); 
01145       Carray().Enter_This_Node(wn);
01146     }
01147   }
01148 }
01149 
01150 //-----------------------------------------------------------------------
01151 // NAME: WB_BROWSER::Promp_Info
01152 // WHIRL BROWSER COMMAND: 'I'
01153 // FUNCTION: Print the PROMPF_INFO
01154 //-----------------------------------------------------------------------
01155 
01156 void WB_BROWSER::Promp_Info()
01157 {
01158   if (!(Prompf_Info() != NULL)) {
01159     Error_Cleanup();
01160     return;
01161   }
01162   Prompf_Info()->Print(stdout);
01163 }
01164 
01165 //-----------------------------------------------------------------------
01166 // NAME: WB_BROWSER::Whirl2fc()
01167 // WHIRL BROWSER COMMAND: 'W'
01168 // FUNCTION: Print tree in whirl2[fc] format at current node
01169 //-----------------------------------------------------------------------
01170 
01171 void WB_BROWSER::Whirl2fc()
01172 {
01173   if (Source_Language() == WB_SRC_NONE) {
01174     Whirl2Src_Init(Global_Fd());
01175     Whirl2Src_Emit(stdout, Cnode());
01176     fprintf(stdout, "\n");
01177   } else if (Source_Language() == WB_SRC_FORTRAN) {
01178     Whirl2F_Init(Global_Fd());
01179     Whirl2F_Emit(stdout, Cnode());
01180     fprintf(stdout, "\n");
01181   } else if (Source_Language() == WB_SRC_C) {
01182     Whirl2C_Init(Global_Fd());
01183     Whirl2C_Emit(stdout, Cnode());
01184     fprintf(stdout, "\n");
01185   }
01186 }
01187 
01188 //-----------------------------------------------------------------------
01189 // NAME: WB_BROWSER::Whirl2fset
01190 // WHIRL BROWSER COMMAND: 'f'
01191 // FUNCTION: Change WHIRL-TO-SOURCE language to FORTRAN
01192 //-----------------------------------------------------------------------
01193 
01194 void WB_BROWSER::Whirl2fset()
01195 {
01196   if (Source_Language() != WB_SRC_FORTRAN) {
01197     Whirl2F_Init(Global_Fd());
01198     Set_Source_Language(WB_SRC_FORTRAN);
01199   }
01200   fprintf(stdout, "WHIRL-TO-SOURCE language is FORTRAN.\n");
01201 }
01202 
01203 //-----------------------------------------------------------------------
01204 // NAME: WB_BROWSER::Whirl2cset
01205 // WHIRL BROWSER COMMAND: 'c'
01206 // FUNCTION: Change WHIRL-TO-SOURCE language to C
01207 //-----------------------------------------------------------------------
01208 
01209 void WB_BROWSER::Whirl2cset()
01210 {
01211   if (Source_Language() != WB_SRC_C) {
01212     Whirl2C_Init(Global_Fd());
01213     Set_Source_Language(WB_SRC_C);
01214   }
01215   fprintf(stdout, "WHIRL-TO-SOURCE language is C.\n");
01216 }
01217 
01218 //-----------------------------------------------------------------------
01219 // NAME: Compact_Buffer
01220 // FUNCTION: Compact 'buffer' by replacing strings like '+-' with '-'
01221 //   and '--' with '+'.
01222 //-----------------------------------------------------------------------
01223 
01224 static void Compact_Buffer(char buffer[])
01225 {
01226   INT i, j;
01227   for (i = 0, j = 0; buffer[i] != '\0'; i++) {
01228     if (buffer[i] == '+' && buffer[i+1] == '-') {
01229       buffer[j++] = '-';
01230       i++;
01231     } else if (buffer[i] == '-' && buffer[i+1] == '-') {
01232       buffer[j++] = '+';
01233       i++;
01234     } else {
01235       buffer[j++] = buffer[i];
01236     }
01237   }
01238   buffer[j] = '\0';
01239 }
01240 
01241 //-----------------------------------------------------------------------
01242 // NAME: WB_BROWSER::Dep_Symbol()
01243 // FUNCTION: Write to 'stdout' a representation of the symbol for 'wn'.
01244 //-----------------------------------------------------------------------
01245 
01246 void WB_BROWSER::Dep_Symbol(WN *wn)
01247 {
01248   WN* symbol_node = NULL;
01249   char buffer[WB_MAX_STRING_LENGTH];
01250   switch (WN_operator(wn)) {
01251   case OPR_ISTORE:
01252     symbol_node = WN_kid1(wn);
01253     break;
01254   case OPR_ILOAD:
01255     symbol_node = WN_kid0(wn);
01256     break;
01257   }
01258   if (symbol_node == NULL)
01259     return;
01260   INT cc = WB_Dump_Whirl_Expr(symbol_node, symbol_node, buffer, 0);
01261   Compact_Buffer(buffer);
01262   if (cc > WB_MAX_STRING_LENGTH - 1) {
01263     fprintf(stdout, "Expression too long!\n");
01264     Error_Cleanup();
01265     return;
01266   }
01267   fputs(buffer, stdout);
01268 }
01269 
01270 //-----------------------------------------------------------------------
01271 // NAME: WB_BROWSER::Deps()
01272 // WHIRL BROWSER COMMAND: 'G'
01273 // FUNCTION: Print the dep graph info at the current node
01274 //-----------------------------------------------------------------------
01275 
01276 void WB_BROWSER::Deps_Loop()
01277 {
01278   if (Dg() == NULL) {
01279     Error_Cleanup();
01280     return;
01281   }
01282   Carray().Reset_Index(); 
01283   WN* start_node = NULL;
01284   switch (WN_opcode(Cnode())) {
01285   case OPC_DO_LOOP:
01286     start_node = WN_do_body(Cnode());
01287     break;
01288   case OPC_DO_WHILE:
01289   case OPC_WHILE_DO:
01290     start_node = WN_while_body(Cnode());
01291     break;
01292   }
01293   WN_ITER* itr = WN_WALK_TreeIter(start_node);
01294   for (; itr != NULL; itr = WN_WALK_TreeNext(itr)) {
01295     WN* wn = itr->wn;
01296     VINDEX16 v = Dg()->Get_Vertex(wn);
01297     if (v == 0)
01298       continue;
01299     INT j = Carray().Enter_This_Node_Unique(wn);
01300     fprintf(stdout, "[%d] ", j);
01301     This_Node(wn); 
01302     fprintf(stdout, "V#%d ", v);
01303     Dep_Symbol(wn);
01304     fprintf(stdout, "\n");
01305     EINDEX16 e;
01306     if (Dg()->Get_In_Edge(v)) {
01307       fprintf(stdout, "    ");
01308       fprintf(stdout, "IN EDGES:\n");
01309       for (e = Dg()->Get_In_Edge(v); e != 0; e = Dg()->Get_Next_In_Edge(e)) {
01310         fprintf(stdout, "    ");
01311         INT j = Carray().Enter_This_Node_Unique(
01312           Dg()->Get_Wn(Dg()->Get_Source(e))); 
01313         fprintf(stdout, "[%d] ", j);
01314         This_Node(Dg()->Get_Wn(Dg()->Get_Source(e)));  
01315         fprintf(stdout, "E#%d ", e);
01316         Dep_Symbol(Dg()->Get_Wn(Dg()->Get_Source(e)));
01317       }
01318     }
01319     if (Dg()->Get_Out_Edge(v)) {
01320       fprintf(stdout, "    ");
01321       fprintf(stdout, "OUT EDGES:\n");
01322       for (e = Dg()->Get_Out_Edge(v); e != 0; e = Dg()->Get_Next_Out_Edge(e)) {
01323         fprintf(stdout, "    ");
01324         INT j = Carray().Enter_This_Node_Unique(
01325           Dg()->Get_Wn(Dg()->Get_Sink(e))); 
01326         fprintf(stdout, "[%d] ", j);
01327         This_Node(Dg()->Get_Wn(Dg()->Get_Sink(e)));  
01328         fprintf(stdout, "E#%d ", e);
01329         Dep_Symbol(Dg()->Get_Wn(Dg()->Get_Sink(e)));
01330       }
01331     }
01332   }
01333 }
01334 
01335 void WB_BROWSER::Deps_Ref()
01336 {
01337   if (Dg() == NULL) {
01338     Error_Cleanup();
01339     return;
01340   }
01341   VINDEX16 v = Dg()->Get_Vertex(Cnode());
01342   if (v == 0) {
01343     Error_Cleanup();
01344     return;
01345   }
01346   EINDEX16 e;
01347   if (!Dg()->Get_In_Edge(v) && !Dg()->Get_Out_Edge(v))
01348     fprintf(stdout, "V#%d\n", v);
01349   Carray().Reset_Index(); 
01350   if (Dg()->Get_In_Edge(v)) {
01351     fprintf(stdout, "V#%d ", v);
01352     fprintf(stdout, "IN EDGES:\n");
01353     for (e = Dg()->Get_In_Edge(v); e != 0; e = Dg()->Get_Next_In_Edge(e)) {
01354       INT j = Carray().Enter_This_Node_Unique(
01355         Dg()->Get_Wn(Dg()->Get_Source(e))); 
01356       fprintf(stdout, "[%d] ", j);
01357       This_Node(Dg()->Get_Wn(Dg()->Get_Source(e)));  
01358       fprintf(stdout, "E#%d ", e);
01359     }
01360   }
01361   if (Dg()->Get_Out_Edge(v)) {
01362     fprintf(stdout, "V#%d ", v);
01363     fprintf(stdout, "OUT EDGES:\n");
01364     for (e = Dg()->Get_Out_Edge(v); e != 0; e = Dg()->Get_Next_Out_Edge(e)) {
01365       INT j = Carray().Enter_This_Node_Unique(
01366         Dg()->Get_Wn(Dg()->Get_Sink(e))); 
01367       fprintf(stdout, "[%d] ", j);
01368       This_Node(Dg()->Get_Wn(Dg()->Get_Sink(e)));  
01369       fprintf(stdout, "E#%d ", e);
01370     }
01371   }
01372 }
01373 
01374 void WB_BROWSER::Deps()
01375 {
01376   switch (WN_opcode(Cnode())) {
01377   case OPC_DO_LOOP:
01378   case OPC_DO_WHILE:
01379   case OPC_WHILE_DO:
01380     Deps_Loop();
01381     break;
01382   default:
01383     Deps_Ref();
01384     break;
01385   }
01386 }
01387 
01388 //-----------------------------------------------------------------------
01389 // NAME: WB_BROWSER::Vertices
01390 // WHIRL BROWSER COMMAND: 'V'
01391 // FUNCTION: Print the vertices of the dep graph
01392 //-----------------------------------------------------------------------
01393 
01394 void WB_BROWSER::Vertices()
01395 {
01396   if (Dg() == NULL) {
01397     Error_Cleanup();
01398     return;
01399   }
01400   VINDEX16 v;
01401   for (v = Dg()->Get_Vertex(); v; v = Dg()->Get_Next_Vertex(v)) {
01402     WN* wn = Dg()->Get_Wn(v);
01403     fprintf(stdout, "V#%d ", (INT) v);
01404     This_Node(wn, FALSE);
01405     Dep_Symbol(wn);
01406     fprintf(stdout, "\n");
01407   }
01408 
01409   VINDEX16 w;
01410   for (v = Dg()->Get_Vertex(); v; v = Dg()->Get_Next_Vertex(v))
01411     for (w = Dg()->Get_Next_Vertex(v); w; w = Dg()->Get_Next_Vertex(w))
01412       if (Dg()->Get_Wn(v) == Dg()->Get_Wn(w))
01413         fprintf(stdout, "Vertices %d and %d are for the same node!\n", v, w);
01414 }
01415 
01416 //-----------------------------------------------------------------------
01417 // NAME: WB_BROWSER::Vertex_Set_Node
01418 // WHIRL BROWSER COMMAND: 'v'
01419 // FUNCTION: Set the current node to the node with the following vertex 
01420 //   number
01421 //-----------------------------------------------------------------------
01422 
01423 void WB_BROWSER::Vertex_Set_Node()
01424 {
01425   if (Dg() == NULL) {
01426     Error_Cleanup();
01427     return;
01428   }
01429   INT vertex_number = 0;
01430   Buffer().Scan_Integer(&vertex_number);
01431   VINDEX16 v;  
01432   for (v = Dg()->Get_Vertex(); v != 0; v = Dg()->Get_Next_Vertex(v))
01433     if (v == (VINDEX16) vertex_number)
01434       break;
01435   if (v == 0) {
01436     Error_Cleanup();
01437     return;
01438   }
01439   Set_Cnode(Dg()->Get_Wn((VINDEX16) vertex_number));
01440   Print_This_Node(Cnode());
01441 }
01442 
01443 INT loop_count = 0;
01444 
01445 //-----------------------------------------------------------------------
01446 // NAME: Dump_Spaces
01447 // FUNCTION: Print 'spaces' number of spaces to the file 'fp'.
01448 //-----------------------------------------------------------------------
01449 
01450 static void Dump_Spaces(FILE* fp, 
01451                         INT spaces)
01452 {
01453   for (INT i = 0; i < spaces; i++)
01454     fprintf(fp, " ");
01455 }
01456 
01457 //-----------------------------------------------------------------------
01458 // NAME: WB_BROWSER::Loops()
01459 // WHIRL BROWSER COMMAND: 'L'
01460 // FUNCTION: Sketch the loop nests in the program unit
01461 //-----------------------------------------------------------------------
01462 
01463 void WB_BROWSER::Loops_Walk(WN* wn, 
01464                             FILE* fp, 
01465                             INT spaces, 
01466                             INT increment)
01467 {
01468   WN* w = 0; 
01469   const char* name = NULL; 
01470   switch (WN_opcode(wn)) {
01471   case OPC_BLOCK:
01472     for (w = WN_first(wn); w; w = WN_next(w))
01473       Loops_Walk(w, fp, spaces, increment);
01474     break;
01475   case OPC_DO_LOOP:
01476     Dump_Spaces(fp, spaces);
01477     name = WB_Whirl_Symbol(wn);
01478     if (Prompf_Id_Map() != -1) {
01479       fprintf(fp, "[%d] 0x%p DOLOOP (%d) <%d> %s\n", Carray().Next_Index(), wn,
01480         (INT) WN_linenum(wn), WN_MAP32_Get(Prompf_Id_Map(), wn), name);
01481     } else {
01482       fprintf(fp, "[%d] 0x%p DOLOOP (%d) %s\n", Carray().Next_Index(), wn,
01483         (INT) WN_linenum(wn), name);
01484     }
01485     Carray().Enter_This_Node(wn); 
01486     Loops_Walk(WN_do_body(wn), fp, spaces + increment, increment);
01487     break;
01488   case OPC_FUNC_ENTRY:
01489     Dump_Spaces(fp, spaces);
01490     if (Prompf_Id_Map() != -1) {
01491       fprintf(fp, "[%d] 0x%p FUNC_ENTRY <%d> %s\n", Carray().Next_Index(), wn,
01492         WN_MAP32_Get(Prompf_Id_Map(), wn), WB_Whirl_Symbol(wn));
01493     } else {
01494       fprintf(fp, "[%d] 0x%p FUNC_ENTRY %s\n", Carray().Next_Index(), wn,
01495         WB_Whirl_Symbol(wn));
01496     }
01497     Carray().Enter_This_Node(wn);
01498     Loops_Walk(WN_func_body(wn), fp, spaces + increment, increment);
01499     break;
01500   case OPC_IF:
01501     if (Fancy_Level() < 3) {
01502       Loops_Walk(WN_then(wn), fp, spaces, increment);
01503       Loops_Walk(WN_else(wn), fp, spaces, increment);
01504     } else {
01505       Dump_Spaces(fp, spaces);
01506       fprintf(fp, "[%d] 0x%p IF ([%d] 0x%p) THEN [%d] 0x%p\n",
01507         Carray().Next_Index(), wn, Carray().Next_Index() + 1, WN_if_test(wn),
01508         Carray().Next_Index() + 2, WN_then(wn));
01509       INT if_loop_count = Carray().Next_Index();
01510       Carray().Enter_This_Node(wn);
01511       Carray().Enter_This_Node(WN_if_test(wn));
01512       Carray().Enter_This_Node(WN_then(wn));
01513       Loops_Walk(WN_then(wn), fp, spaces + increment, increment);
01514       if (!WN_else_is_empty(wn)) {
01515         Dump_Spaces(fp, spaces);
01516         fprintf(fp, "[%d] 0x%p ELSE\n", Carray().Next_Index(), WN_else(wn));
01517         Carray().Enter_This_Node(WN_else(wn));
01518         Loops_Walk(WN_else(wn), fp, spaces + increment, increment);
01519       }
01520       Dump_Spaces(fp, spaces);
01521       fprintf(fp, "[%d] 0x%p ENDIF\n", if_loop_count, wn);
01522     }
01523     break;
01524   case OPC_DO_WHILE:
01525     Dump_Spaces(fp, spaces);
01526     fprintf(fp, "[%d] 0x%p DO_WHILE_LOOP \n", Carray().Next_Index(), wn);
01527     Carray().Enter_This_Node(wn);
01528     Loops_Walk(WN_while_body(wn), fp, spaces + increment, increment);
01529     break;
01530   case OPC_WHILE_DO:
01531     Dump_Spaces(fp, spaces);
01532     fprintf(fp, "[%d] 0x%p WHILE_DO_LOOP \n", Carray().Next_Index(), wn);
01533     Carray().Enter_This_Node(wn);
01534     Loops_Walk(WN_while_body(wn), fp, spaces + increment, increment);
01535     break;
01536   case OPC_REGION:
01537     if (Fancy_Level() >= 3) {
01538       Dump_Spaces(fp, spaces);
01539       if (Prompf_Id_Map() != -1) {
01540         fprintf(fp, "[%d] 0x%p REGION <%d>\n", Carray().Next_Index(), wn,
01541           WN_MAP32_Get(Prompf_Id_Map(), wn));
01542       } else {
01543         fprintf(fp, "[%d] 0x%p REGION \n", Carray().Next_Index(), wn);
01544       }
01545       Carray().Enter_This_Node(wn);
01546       for (INT i = 0; i < WN_kid_count(wn); i++)
01547         Loops_Walk(WN_kid(wn, i), fp, spaces + increment, increment);
01548     } else {
01549       for (INT i = 0; i < WN_kid_count(wn); i++)
01550         Loops_Walk(WN_kid(wn, i), fp, spaces, increment);
01551     }
01552   }
01553 }
01554 
01555 void WB_BROWSER::Loops()
01556 {
01557   Carray().Reset_Index();
01558   Loops_Walk(Cnode(), stdout, 0, 2);
01559 }
01560 
01561 //-----------------------------------------------------------------------
01562 // NAME: WB_BROWSER::Set_Map_Id
01563 // WHIRL BROWSER COMMAND: 'M'
01564 // FUNCTION: Set the current node to node with this map id
01565 //-----------------------------------------------------------------------
01566 
01567 void WB_BROWSER::Set_Map_Id()
01568 {
01569   INT map_id = 0;
01570   Buffer().Scan_Integer(&map_id); 
01571   WN_ITER* itr = WN_WALK_TreeIter(Global_Fd());
01572   for (; itr != NULL; itr = WN_WALK_TreeNext(itr))
01573     if (WN_map_id(itr->wn) == map_id)
01574       break;
01575   if (itr == NULL) {
01576     Error_Cleanup();
01577     return;
01578   }
01579   Set_Cnode(itr->wn);
01580   Print_This_Node(Cnode());
01581 }
01582 
01583 //-----------------------------------------------------------------------
01584 // NAME: WB_BROWSER::Map_Id
01585 // WHIRL BROWSER COMMAND: 'm'
01586 // FUNCTION: Print the map-id at this node 
01587 //-----------------------------------------------------------------------
01588 
01589 void WB_BROWSER::Map_Id()
01590 {
01591   fprintf(stdout, "%d\n", WN_map_id(Cnode()));
01592 }
01593 
01594 //-----------------------------------------------------------------------
01595 // NAME: WB_BROWSER::DaVinci_Toggle
01596 // WHIRL BROWSER COMMAND: 'd'
01597 // FUNCTION: Toggle Da Vinci mode
01598 //-----------------------------------------------------------------------
01599 
01600 void WB_BROWSER::DaVinci_Toggle()
01601 {
01602   if (DaVinci_Mode()) {
01603     _davinci_mode = FALSE;
01604     fprintf(stdout, "DAVINCI is OFF.\n");
01605   } else {
01606     _davinci_mode = TRUE;
01607     fprintf(stdout, "DAVINCI is ON.\n");
01608   }
01609 }
01610 
01611 //-----------------------------------------------------------------------
01612 // NAME: WB_BROWSER::Find_Symbols
01613 // WHIRL BROWSER COMMAND: '$'
01614 // FUNCTION: Print the symbol table entry with this name
01615 //-----------------------------------------------------------------------
01616 
01617 void WB_BROWSER::Find_Symbols()
01618 {
01619   ST* st = NULL;
01620   char s[WB_MAX_STRING_LENGTH];
01621   Buffer().Scan_Alphanumeric(s);
01622   Carray().Reset_Index(); 
01623   BOOL test_substring = s[0] == '\'';
01624   INT i; 
01625   FOREACH_SYMBOL(CURRENT_SYMTAB, st, i) {
01626     if ((!test_substring && strcmp(ST_name(st), s) == 0
01627         || test_substring && Is_Substring(&s[1], ST_name(st)))) {
01628       Print_ST(stdout, st, TRUE);
01629     }
01630   }
01631   FOREACH_SYMBOL(GLOBAL_SYMTAB, st, i) {
01632     if ((!test_substring && strcmp(ST_name(st), s) == 0
01633         || test_substring && Is_Substring(&s[1], ST_name(st)))) {
01634       Print_ST(stdout, st, TRUE);
01635     }
01636   }
01637 }
01638 
01639 //-----------------------------------------------------------------------
01640 // NAME: WB_BROWSER::Required_Fields_Present
01641 // FUNCTION: Return TRUE if the 'num'th command has all of the fields 
01642 //   in the WB_BROWSER needed to print the associated information. 
01643 //-----------------------------------------------------------------------
01644 
01645 BOOL WB_BROWSER::Required_Fields_Present(INT num)
01646 { 
01647   if (Required_Fields(num) == WBR_NONE)
01648     return TRUE; 
01649   if ((Required_Fields(num) & WBR_DU) && Du() == NULL)
01650     return FALSE; 
01651   if ((Required_Fields(num) & WBR_DG) && Dg() == NULL)
01652     return FALSE; 
01653   if ((Required_Fields(num) & WBR_ALIAS) && Alias_Mgr() == NULL)
01654     return FALSE; 
01655   if ((Required_Fields(num) & WBR_PARENT) && Parent_Map() == WN_MAP_UNDEFINED)
01656     return FALSE; 
01657   if ((Required_Fields(num) & WBR_MPFMAP) && Prompf_Id_Map() == WN_MAP_UNDEFINED) 
01658     return FALSE; 
01659   if ((Required_Fields(num) & WBR_MPFINFO) && Prompf_Info() == NULL) 
01660     return FALSE; 
01661   if ((Required_Fields(num) & WBR_AAMAP) && Access_Array_Map() == WN_MAP_UNDEFINED) 
01662     return FALSE; 
01663   if ((Required_Fields(num) & WBR_REDMAP) && Reduction_Map() == WN_MAP_UNDEFINED) 
01664     return FALSE; 
01665   return TRUE; 
01666 } 
01667 
01668 //-----------------------------------------------------------------------
01669 // NAME: WB_BROWSER::Help
01670 // WHIRL BROWSER COMMAND: 'H'
01671 // FUNCTION: Print this information
01672 //-----------------------------------------------------------------------
01673 
01674 void WB_BROWSER::Help()
01675 { 
01676   for (INT i = 0; Command(i) != '\0'; i++) {
01677     if (Required_Fields_Present(i)) {
01678       for (INT j = 0; j < WB_ASCII_CHAR_COUNT; j++) 
01679         if (_keymap[j] == Command(i)) 
01680            fprintf(stdout, "  %c: %s\n", j, Command_Text(i)); 
01681     }
01682   }
01683   fprintf(stdout, "  Q: Exit the debugger\n");
01684   fprintf(stdout, "  q: Exit the debugger\n");
01685 } 
01686 
01687 //-----------------------------------------------------------------------
01688 // NAME: WB_BROWSER::Invoke_Command
01689 // FUNCTION: Invoke the command indicated by character 'ch'. 
01690 //-----------------------------------------------------------------------
01691 
01692 void WB_BROWSER::Invoke_Command(char ch)
01693 { 
01694   switch (_keymap[ch]) { 
01695   case 'R': 
01696     Root(); 
01697     break;
01698   case 'N': 
01699     Next(); 
01700     break; 
01701   case 'P': 
01702     Previous(); 
01703     break;
01704   case '=':
01705     Set_Node(); 
01706     break;
01707   case '@':
01708     Address(); 
01709     break;
01710   case '>': 
01711     Fancy_Up(); 
01712     break; 
01713   case '<': 
01714     Fancy_Down(); 
01715     break; 
01716   case 'K': 
01717     Kids(); 
01718     break; 
01719   case 'S': 
01720     Statements(); 
01721     break; 
01722   case 'T': 
01723     This_Tree(); 
01724     break; 
01725   case '%': 
01726     Addresses(); 
01727     break; 
01728   case 's': 
01729     Symbol(); 
01730     break; 
01731   case 't': 
01732     Type(); 
01733     break;
01734   case 'F': 
01735     Find(); 
01736     break; 
01737   case '$':
01738     Find_Symbols();
01739     break;
01740   case 'o': 
01741     Find_Operator();
01742     break; 
01743   case 'H':
01744   case 'h':
01745     Help(); 
01746     break; 
01747   case 'U':
01748     Uses(); 
01749     break; 
01750   case 'D':
01751     Defs(); 
01752     break; 
01753   case 'G': 
01754     Deps(); 
01755     break; 
01756   case 'V': 
01757     Vertices(); 
01758     break; 
01759   case 'v': 
01760     Vertex_Set_Node(); 
01761     break; 
01762   case 'A': 
01763     Access_Array();
01764     break; 
01765   case 'a':
01766     Alias(); 
01767     break; 
01768   case 'r': 
01769     Reduction();
01770     break; 
01771   case 'E': 
01772     Parent(); 
01773     break; 
01774   case 'e': 
01775     Ancestors(); 
01776     break; 
01777   case 'i': 
01778     Promp_Map(); 
01779     break; 
01780   case 'I':
01781     Promp_Info();
01782     break; 
01783   case 'W':
01784     Whirl2fc(); 
01785     break; 
01786   case 'f': 
01787     Whirl2fset(); 
01788     break;
01789   case 'c': 
01790     Whirl2cset(); 
01791     break; 
01792   case 'L': 
01793     Loops(); 
01794     break;
01795   case 'M': 
01796     Set_Map_Id();
01797     break; 
01798   case 'm': 
01799     Map_Id();
01800     break; 
01801   case 'd': 
01802     DaVinci_Toggle();
01803     break; 
01804   case '~': 
01805     Summary(stdout);
01806     break;
01807   default: 
01808     fprintf(stdout, "Bad character: %c\n", ch);
01809     break; 
01810   }
01811 }  
01812 
01813 //-----------------------------------------------------------------------
01814 // NAME: WB_BROWSER::Initialize_Language
01815 // FUNCTION: Set the value of 'WB_language' and print out that language.
01816 //-----------------------------------------------------------------------
01817 
01818 void WB_BROWSER::Initialize_Language() 
01819 {
01820   if (Pu() != NULL) { 
01821     switch (PU_src_lang(*Pu())) {
01822     case PU_C_LANG:
01823     case PU_CXX_LANG:
01824       Set_Source_Language(WB_SRC_C);
01825       fprintf(stdout, "WHIRL-TO-SOURCE language is C.\n");
01826       break;
01827     case PU_F90_LANG:
01828     case PU_F77_LANG:
01829       Set_Source_Language(WB_SRC_FORTRAN); 
01830       fprintf(stdout, "WHIRL-TO-SOURCE language is FORTRAN.\n");
01831       break;
01832     default:
01833       Set_Source_Language(WB_SRC_NONE);
01834       fprintf(stdout,
01835         "Can't do WHIRL-TO-SOURCE tranformations in this language.\n");
01836       break;
01837     }
01838   } else { 
01839     Set_Source_Language(WB_SRC_FORTRAN); 
01840     fprintf(stdout, "WHIRL-TO-SOURCE language is FORTRAN.\n");
01841   } 
01842 }
01843 
01844 //-----------------------------------------------------------------------
01845 // NAME: Scan_Blanks_And_Tabs
01846 // FUNCTION: In the 'buffer' advance 'buffer_start' past all blanks and 
01847 //   tabs. 
01848 //-----------------------------------------------------------------------
01849 
01850 static void Scan_Blanks_And_Tabs(char buffer[],
01851                                  INT* buffer_start)
01852 {
01853   char ch;
01854   do {
01855     ch = buffer[(*buffer_start)++];
01856   } while (ch == ' ' || ch == '\t');
01857   (*buffer_start)--;
01858 }
01859 
01860 //-----------------------------------------------------------------------
01861 // NAME: WB_BROWSER::Initialize_Keymap
01862 // FUNCTION: Initialize the keymap my writing over the default key settings
01863 //   with other, user specified key settings.
01864 //-----------------------------------------------------------------------
01865 
01866 void WB_BROWSER::Initialize_Keymap(char ch)
01867 { 
01868   const INT BUFFER_MAX = 132; 
01869   char file_name[BUFFER_MAX];
01870   strcpy(file_name, getenv("HOME"));
01871   strcat(file_name, "/.wb_keymap");
01872   FILE* fp_keymap = fopen(file_name, "r");
01873   if (fp_keymap == NULL)
01874     return;
01875   BOOL print_log = TRUE;
01876   char key_buffer[BUFFER_MAX];
01877   INT line_number = 0;
01878   while (fgets(key_buffer, BUFFER_MAX-1, fp_keymap) != NULL) {
01879     line_number++;
01880     INT key_buffer_start = 0;
01881     Scan_Blanks_And_Tabs(key_buffer, &key_buffer_start);
01882     if (strncasecmp(&key_buffer[key_buffer_start], "SILENT",
01883         strlen("SILENT")) == 0) {
01884       print_log = FALSE;
01885     } else if (strncasecmp(&key_buffer[key_buffer_start], "VERBOSE",
01886         strlen("VERBOSE")) == 0) {
01887       print_log = TRUE;
01888     } else if (strncasecmp(&key_buffer[key_buffer_start], "TRANSLATE",
01889         strlen("TRANSLATE")) == 0) {
01890       key_buffer_start += strlen("TRANSLATE");
01891       Scan_Blanks_And_Tabs(key_buffer, &key_buffer_start);
01892       char old_char = key_buffer[key_buffer_start++];
01893       if (Unmappable_Character(old_char)) {
01894         fprintf(stdout,
01895           ".wb_keymap: Error on line %d: Cannot map %c\n",
01896           line_number, old_char);
01897         continue;
01898       }
01899       if (ch == ' ') { 
01900         if (key_buffer[key_buffer_start] != ' '
01901             && key_buffer[key_buffer_start] != '\t')
01902           continue;
01903         Scan_Blanks_And_Tabs(key_buffer, &key_buffer_start);
01904         char new_char = key_buffer[key_buffer_start++];
01905         if (Unmappable_Character(new_char)) {
01906           fprintf(stdout,
01907             ".wb_keymap: Error on line %d: Cannot map %c\n",
01908             line_number, new_char);
01909           continue;
01910         }
01911         if (print_log)
01912           fprintf(stdout, ".wb_keymap: Translating '%c' to '%c'\n",
01913             old_char, new_char);
01914         _keymap[new_char] = old_char;
01915       } else {
01916         if (old_char == ch) {
01917           old_char = key_buffer[key_buffer_start++];
01918           if (Unmappable_Character(old_char)) {
01919             fprintf(stdout,
01920               ".wb_keymap: Error on line %d: Cannot map %c\n",
01921               line_number, old_char);
01922             continue;
01923           }
01924           Scan_Blanks_And_Tabs(key_buffer, &key_buffer_start);
01925           char new_char = key_buffer[key_buffer_start++];
01926           if (Unmappable_Character(new_char)) {
01927             fprintf(stdout,
01928               ".wb_keymap: Error on line %d: Cannot map %c\n",
01929               line_number, new_char);
01930             continue;
01931           }
01932           if (print_log)
01933             fprintf(stdout, ".wb_keymap: Translating '%c' to '%c'\n",
01934               old_char, new_char);
01935           _keymap[new_char] = old_char;
01936         }
01937       }
01938     } else {
01939       fprintf(stdout, ".wb_keymap: Error on line %d: Unrecognized command\n",
01940         line_number);
01941     }
01942   } 
01943   fclose(fp_keymap);
01944 } 
01945 
01946 //-----------------------------------------------------------------------
01947 // NAME: WB_BROWSER::Sdebug
01948 // FUNCTION: The 'string debugger'. Run the whirl browser using 'init_buffer'
01949 //   as the initial set of commands.
01950 // NOTE: 'sdebug' can be called from the compiler as an aid to debugging in
01951 //   batch mode.  For example, to print out the loop nests at a certain
01952 //   place during compiler execution, put a call of the form:
01953 //     sdebug("RLQ");
01954 //   in the compiler where you want to see the loops.
01955 //-----------------------------------------------------------------------
01956 
01957 void WB_BROWSER::Sdebug(char init_buffer[])
01958 {
01959   char ch;
01960   BOOL reload;
01961  
01962   if (Global_Fd() == NULL) {
01963     fprintf(stdout, "Whirl browser not valid in this phase.\n");
01964     Error_Cleanup();
01965     return;
01966   } 
01967   Initialize_Keymap(' ');
01968   Initialize_Language();
01969   Root();
01970   fprintf(stdout, "Root node is: ");
01971   Print_This_Node(Cnode());
01972   WB_Prompt();  
01973   Buffer().Reset_Buffer();
01974   if (init_buffer[0] == '\0') {
01975     reload = TRUE;
01976   } else {
01977     reload = FALSE;
01978     Buffer().Load_Buffer(init_buffer);
01979     for (INT i = 0; init_buffer[i] != '\0'; i++)
01980       fprintf(stdout, "%c", init_buffer[i]);
01981     fprintf(stdout, "\n");
01982   }
01983   while (TRUE) {
01984     if (reload) {
01985       Buffer().Load_Buffer();
01986       reload = FALSE;
01987     }
01988     ch = Buffer().Get_Command();
01989     if (ch == '\n') {
01990       WB_Prompt();
01991       reload = TRUE;
01992       continue;
01993     }
01994     if (ch == 'Q' || ch == 'q') 
01995       return; 
01996     Invoke_Command(ch); 
01997   }
01998 }
01999 
02000 //-----------------------------------------------------------------------
02001 // NAME: WB_BROWSER::Set_Subcommand
02002 // FUNCTION: Set the command list to the list corresponding to the
02003 //   command whose character is 'ch'.
02004 //-----------------------------------------------------------------------
02005 
02006 void WB_BROWSER::Set_Subcommand(char ch)
02007 {
02008   INT i;
02009   for (i = 0; Command(i) != '\0'; i++)
02010     if (Command(i) == ch)
02011        break;
02012   if (Command(i) == '\0')
02013     return;
02014   if (Subcommand(i) == NULL)
02015     return;
02016   _is_subcommand = TRUE;
02017   Set_Old_Command_List(Command_List());
02018   Set_Command_List(Subcommand(i));
02019   for (i = 0; i < WB_ASCII_CHAR_COUNT; i++)
02020     _old_keymap[i] = _keymap[i];
02021   for (i = 0; i < WB_ASCII_CHAR_COUNT; i++)
02022     _keymap[i] = i;
02023   Initialize_Keymap(ch);
02024 }
02025 
02026 //-----------------------------------------------------------------------
02027 // NAME: WB_BROWSER::Reset_Subcommand
02028 // FUNCTION: Reset the command list to its original value.
02029 //-----------------------------------------------------------------------
02030 
02031 void WB_BROWSER::Reset_Subcommand()
02032 {
02033   _is_subcommand = FALSE;
02034   Set_Command_List(Old_Command_List());
02035   Set_Old_Command_List(NULL);
02036   for (INT i = 0; i < WB_ASCII_CHAR_COUNT; i++)
02037     _keymap[i] = _old_keymap[i];
02038 }
02039 
02040 //-----------------------------------------------------------------------
02041 // NAME: WB_BROWSER::Debug 
02042 // FUNCTION: The main entry point to the whirl browser.  To start up the
02043 //   whirl browser in dbx, say 'p debug()'.
02044 //-----------------------------------------------------------------------
02045 
02046 void WB_BROWSER::Debug()
02047 {
02048   Sdebug("");
02049 }
02050 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines