Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
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 * ==================================================================== 00038 * 00039 * 00040 * Revision history: 00041 * 08-Sep-89 - Original Version 00042 * 24-Jan-91 - Copied for TP/Muse 00043 * 00044 * Description: 00045 * 00046 * This module provides tracing support in the microcode compiler and 00047 * associated tools. See tracing.h for the external interface. 00048 * 00049 * ==================================================================== 00050 * ==================================================================== 00051 */ 00052 00053 static char *source_file = __FILE__; 00054 00055 #include <errno.h> 00056 00057 #include "defs.h" 00058 #include "tracing.h" 00059 #include "erglob.h" 00060 #include "flags.h" 00061 #include "util.h" 00062 00063 /* The following strings are useful in creating trace messages: */ 00064 char *SBar = 00065 "-----------------------------------------------------------------------\n"; 00066 char *DBar = 00067 "=======================================================================\n"; 00068 char *Sharps = 00069 "#######################################################################\n"; 00070 00071 #define INDENT 2 00072 00073 /* The trace file descriptor, to be used in fprintf tracing: */ 00074 static FILE *TFile_internal = NULL; 00075 00076 00077 #ifdef FRONT_END_F77 00078 extern FILE *Kqqgso(); 00079 #endif 00080 00081 /* Flags controlling progress tracing: */ 00082 INT32 Progress_Flags = 0; 00083 00084 /* Local static data: files */ 00085 static BOOL Non_stdout_TFile = FALSE; /* TFile other than stdout? */ 00086 static char *TFile_Name = "stdout"; /* TFile name */ 00087 00088 /* Local static data: flags */ 00089 #define BB_COUNT 50 /* Number of traceable BBs */ 00090 #define PU_COUNT 10 /* Number of traceable PUs */ 00091 #define REGION_COUNT 10 /* Number of traceable REGIONs */ 00092 #define CTRL_COUNT 50 /* Number of control options */ 00093 static UINT TI_Mask; /* Info mask */ 00094 static UINT TD_Mask; /* Debug option mask */ 00095 static UINT TI_Phase[TP_COUNT]; /* IR trace flags */ 00096 static UINT TS_Phase[TP_COUNT]; /* SYMTAB trace flags */ 00097 static UINT TN_Phase[TP_COUNT]; /* TN trace flags */ 00098 static UINT TA_Phase[TP_COUNT]; /* Memory Allocation Trace */ 00099 static UINT TP_Mask[TP_COUNT]; /* Per-phase trace masks */ 00100 static UINT TB_Enable[BB_COUNT]; /* BB enable list */ 00101 static UINT BB_Cnt = 0; /* Next BB traced */ 00102 static UINT Xstop_Phase = TP_LAST; /* Last phase to execute */ 00103 static UINT TC_Enable[CTRL_COUNT]; /* Control option list */ 00104 static char *PU_Enable[PU_COUNT]; /* PUs to trace */ 00105 static INT PU_Num_Enable[PU_COUNT]; /* PUs to trace */ 00106 static UINT PU_Cnt = 0; /* Next PU traced */ 00107 static UINT PU_NCnt = 0; /* Next PU number traced */ 00108 static INT Region_Num_Enable[REGION_COUNT]; /* Regions to trace */ 00109 static UINT REGION_NCnt = 0; /* Next REGION number traced */ 00110 00111 static char *Current_PU_Name = NULL; 00112 static INT Current_PU_Number = 0; 00113 static INT Current_Region_Number = 0; /* for debugging regions */ 00114 00115 00116 /* ==================================================================== 00117 * 00118 * Phase_Descriptors 00119 * 00120 * This array provides 3-character names and full names for the trace 00121 * phases, for use by Get_Trace_Phase_Number and List_Phase_Numbers 00122 * below. 00123 * 00124 * ==================================================================== 00125 */ 00126 00127 typedef struct { 00128 INT32 num; /* Phase number (TP_COUNT to terminate list) */ 00129 char *id; /* 3-character ID for phase */ 00130 char *name; /* Full descriptive name for phase */ 00131 } PDESC; 00132 00133 #define PD_num(p) (p->num) 00134 #define PD_id(p) (p->id) 00135 #define PD_name(p) (p->name) 00136 00137 /* WARNING: The ID MUST BE a 3-character string, with the first 00138 * character alphabetic (or at least not a digit). They are 00139 * interpreted case-insensitive, and therefore must be unique ignoring 00140 * case. Also, there is no inherent reason that multiple IDs could 00141 * not be used for the same phase, except that the listing routine 00142 * will then print them all... 00143 */ 00144 static PDESC Phases[] = { 00145 /* Miscellaneous "phases": */ 00146 { TP_PTRACE1, "PT1", "Performance #1" }, 00147 { TP_PTRACE2, "PT2", "Performance #2" }, 00148 { TP_MISC, "MSC", "Miscellaneous" }, 00149 00150 /* Front end phases: */ 00151 { TP_SEMANTICS, "SEM", "Semantic analyzer" }, 00152 { TP_IRB, "IRB", "IR (WHIRL) builder" }, 00153 00154 /* Intermediate/utility phases: */ 00155 { TP_IR_READ, "IRR", "IR (WHIRL) reader/writer" }, 00156 { TP_WHIRL2FC, "WH2", "WHIRL to Fortran/C" }, 00157 { TP_WHIRLSIMP, "SMP", "WHIRL simplifier" }, 00158 { TP_REGION, "RGN", "Region support" }, 00159 { TP_ORI, "ORI", "Olimit Region Insertion" }, 00160 { TP_FEEDBACK, "FDB", "Feedback support" }, 00161 { TP_VHO_LOWER, "VHO", "VHO lowering" }, 00162 { TP_LOWER, "LOW", "WHIRL lowering" }, 00163 { TP_LOWER90, "L90", "F90 WHIRL lowering" }, 00164 00165 /* IPA/inlining phases: */ 00166 { TP_INLINE, "INL", "Inliner" }, 00167 { TP_IPL, "IPL", "IPA local summary phase" }, 00168 { TP_IPA, "IPA", "IPA analysis phase" }, 00169 { TP_IPO, "IPO", "IPA optimization phase" }, 00170 { TP_IPM, "IPM", "IPA miscellaneous" }, 00171 00172 /* Global optimizer: */ 00173 { TP_ALIAS, "ALI", "Alias/mod/ref analysis" }, 00174 { TP_WOPT1, "OPT", "Global optimization" }, 00175 { TP_WOPT2, "OP2", "More global optimization" }, 00176 { TP_WOPT3, "OP3", "Even more global optimization" }, 00177 00178 /* Loop nest optimizer: */ 00179 { TP_VECDD, "VDD", "Vector data dependency analysis" }, 00180 { TP_LNOPT, "LNO", "Loop Nest Optimization" }, 00181 { TP_LNOPT2, "LN2", "More Loop Nest Optimization" }, 00182 { TP_LNOPT3, "LN3", "Even more Loop Nest Optimization" }, 00183 00184 /* Code generator: */ 00185 { TP_CG, "CGM", "Code Generator miscellaneous" }, 00186 { TP_DATALAYOUT, "LAY", "Data layout" }, 00187 { TP_CGEXP, "EXP", "Code generator expansion" }, 00188 { TP_LOCALIZE, "LOC", "Localize TNs" }, 00189 { TP_FIND_GLOB, "GLR", "Find global register live ranges" }, 00190 { TP_EBO, "EBO", "Extended Block Optimizer" }, 00191 { TP_FLOWOPT, "FLW", "Control flow optimization" }, 00192 { TP_HBF, "HBF", "Hyperblock Formation" }, 00193 { TP_PQS, "PQS", "Predicate query system" }, 00194 { TP_CGPREP, "PRP", "Code generator scheduling prep" }, 00195 { TP_CGLOOP, "LOP", "Code generator loop optimization" }, 00196 { TP_SWPIPE, "SWP", "Software pipelining" }, 00197 { TP_SRA, "SRA", "Software pipelining register allocation" }, 00198 { TP_SCHED, "SCH", "Scheduling" }, 00199 { TP_GCM, "GCM", "Global code motion" }, 00200 { TP_GRA, "GRA", "Global register allocation" }, 00201 { TP_ALLOC, "LRA", "Local register allocation" }, 00202 { TP_PSGCM, "PSG", "Post Schedule Global code motion" }, 00203 { TP_THR, "THR", "Tree-Height Reduction" }, 00204 { TP_EMIT, "EMT", "Code emission" }, 00205 00206 { TP_TEMP, "TMP", "Temporary use" }, 00207 00208 /* This one must be last: */ 00209 { TP_COUNT, NULL, NULL } 00210 }; 00211 00212 /* ==================================================================== 00213 * 00214 * Get_Trace_Phase_Number 00215 * 00216 * Extract the phase number from a trace option. It is either numeric, 00217 * in which case we return the value, or it is a 3-character string, in 00218 * which case we look up the phase number in the table above. If we 00219 * find the number, cp is updated to point to the next character; 00220 * otherwise it is left unchanged and an error message is printed. 00221 * 00222 * ==================================================================== 00223 */ 00224 00225 INT32 00226 Get_Trace_Phase_Number ( 00227 char **cp, /* Pointer to phase number string */ 00228 char *arg ) /* Pointer to argument for error messages */ 00229 { 00230 /* First check whether the phase is given numerically: */ 00231 if ( **cp >= '0' && **cp <= '9' ) { 00232 return Get_Numeric_Flag ( cp, 0, TP_LAST, 0, arg ); 00233 00234 /* Otherwise, go search the table for it: */ 00235 } else { 00236 PDESC *phase = Phases; 00237 00238 while ( PD_num(phase) != TP_COUNT ) { 00239 if ( strncasecmp ( *cp, PD_id(phase), 3 ) == 0 ) { 00240 *cp += 3; 00241 return PD_num(phase); 00242 } 00243 ++phase; 00244 } 00245 ErrMsg ( EC_Trace_Phase, -1, TP_MIN, TP_LAST ); 00246 return 0; 00247 } 00248 } 00249 00250 /* ==================================================================== 00251 * 00252 * List_Phase_Numbers 00253 * 00254 * List the trace phases to TFile. 00255 * 00256 * ==================================================================== 00257 */ 00258 00259 void 00260 List_Phase_Numbers ( void ) 00261 { 00262 PDESC *phase = Phases; 00263 00264 fprintf ( Get_Trace_File(), 00265 "Trace phase numbers supported and their values:\n" ); 00266 while ( PD_num(phase) != TP_COUNT ) { 00267 fprintf ( Get_Trace_File(), " %3s: -tt%02d:0x%08x (%s)\n", 00268 PD_id(phase), PD_num(phase), TP_Mask[PD_num(phase)], 00269 PD_name(phase) ); 00270 ++phase; 00271 } 00272 } 00273 00274 /* ==================================================================== 00275 * 00276 * Set_Trace 00277 * 00278 * Set a trace flag specified by: 00279 * Function Argument Resulting action 00280 * -------- -------- ---------------- 00281 * TKIND_INFO flag mask Enable masked traces 00282 * TKIND_DEBUG flag mask Enable masked options 00283 * TKIND_IR phase number Enable IR trace for phase 00284 * TKIND_SYMTAB phase number Enable SYMTAB trace for phase 00285 * TKIND_TN phase number Enable TN trace for phase 00286 * TKIND_BB BB number Restrict tracing to BB 00287 * TKIND_XPHASE phase number Stop execution after phase 00288 * TKIND_CTRL control number Enable control option 00289 * phase number flag mask Enable masked per-phase traces 00290 * 00291 * ==================================================================== 00292 */ 00293 00294 void 00295 Set_Trace ( INT func, INT arg ) 00296 { 00297 /* Check the function value: */ 00298 if ( func < TKIND_MIN || func == 0 ) { 00299 ErrMsg ( EC_Trace_Func, func ); 00300 return; 00301 } else if ( func > TP_LAST ) { 00302 ErrMsg ( EC_Trace_Phase, func, TKIND_MIN, TP_LAST ); 00303 return; 00304 } 00305 00306 /* Set the internal flag: */ 00307 switch ( func ) { 00308 /* INFO mask: */ 00309 case TKIND_INFO: 00310 TI_Mask |= arg; 00311 return; 00312 00313 /* DEBUG mask: */ 00314 case TKIND_DEBUG: 00315 TD_Mask |= arg; 00316 return; 00317 00318 /* IR phase: */ 00319 case TKIND_IR: 00320 if ( arg != Check_Range (arg, TP_MIN, TP_LAST, 0) ) { 00321 ErrMsg ( EC_Trace_Phase, arg, TP_MIN, TP_LAST ); 00322 } else { 00323 TI_Phase[arg] = TRUE; 00324 } 00325 return; 00326 00327 /* SYMTAB phase: */ 00328 case TKIND_SYMTAB: 00329 if ( arg != Check_Range (arg, TP_MIN, TP_LAST, 0) ) { 00330 ErrMsg ( EC_Trace_Phase, arg, TP_MIN, TP_LAST ); 00331 } else { 00332 TS_Phase[arg] = TRUE; 00333 } 00334 return; 00335 00336 /* TN phase: */ 00337 case TKIND_TN: 00338 if ( arg != Check_Range (arg, TP_MIN, TP_LAST, 0) ) { 00339 ErrMsg ( EC_Trace_Phase, arg, TP_MIN, TP_LAST ); 00340 } else { 00341 TN_Phase[arg] = TRUE; 00342 } 00343 return; 00344 00345 /* Alloc phase: */ 00346 case TKIND_ALLOC: 00347 if ( arg != Check_Range (arg, TP_MIN, TP_LAST, 0) ) { 00348 ErrMsg ( EC_Trace_Phase, arg, TP_MIN, TP_LAST ); 00349 } else { 00350 TA_Phase[arg] = TRUE; 00351 } 00352 return; 00353 00354 /* BB number: */ 00355 case TKIND_BB: 00356 if ( ++BB_Cnt >= BB_COUNT ) { 00357 ErrMsg ( EC_Trace_BBs, arg ); 00358 --BB_Cnt; 00359 } else { 00360 TB_Enable[BB_Cnt] = arg; 00361 } 00362 return; 00363 00364 /* Stop execution after phase: */ 00365 case TKIND_XPHASE: 00366 if ( arg != Check_Range (arg, TP_MIN, TP_LAST, 0) ) { 00367 ErrMsg ( EC_Trace_Phase, arg, TP_MIN, TP_LAST ); 00368 } else { 00369 Xstop_Phase = arg; 00370 } 00371 return; 00372 00373 /* Control option: */ 00374 case TKIND_CTRL: 00375 if ( arg != Check_Range (arg, 0, CTRL_COUNT-1, 0) ) { 00376 ErrMsg ( EC_Trace_Control, arg, CTRL_COUNT-1 ); 00377 } else { 00378 TC_Enable[arg] = TRUE; 00379 } 00380 return; 00381 00382 /* Per-phase mask: */ 00383 default: 00384 TP_Mask[func] |= arg; 00385 return; 00386 } 00387 } 00388 00389 /* Set current PU for pu tracing */ 00390 #define RID_CREATE_NEW_ID -1 /* see be/region/region_util.h */ 00391 void 00392 Set_Current_PU_For_Trace ( char *name, INT number ) 00393 { 00394 Current_PU_Name = name; 00395 Current_PU_Number = number; 00396 00397 Set_Current_Region_For_Trace(RID_CREATE_NEW_ID/* invalid region id */); 00398 } 00399 /* Set current REGION for region tracing */ 00400 void 00401 Set_Current_Region_For_Trace ( INT number ) 00402 { 00403 Current_Region_Number = number; 00404 } 00405 00406 /* ==================================================================== 00407 * 00408 * Set_Trace_Pu 00409 * 00410 * Note a PU to be traced. 00411 * 00412 * ==================================================================== 00413 */ 00414 00415 void 00416 Set_Trace_Pu ( char *name ) 00417 { 00418 if ( ++PU_Cnt >= PU_COUNT ) { 00419 ErrMsg ( EC_Trace_PUs, name ); 00420 --PU_Cnt; 00421 } else { 00422 PU_Enable[PU_Cnt] = name; 00423 } 00424 return; 00425 } 00426 00427 void 00428 Set_Trace_Pu_Number ( INT number ) 00429 { 00430 if ( ++PU_NCnt >= PU_COUNT ) { 00431 ErrMsg ( EC_Trace_PUs, "<number>"); 00432 --PU_NCnt; 00433 } else { 00434 PU_Num_Enable[PU_NCnt] = number; 00435 } 00436 return; 00437 } 00438 00439 /* ==================================================================== 00440 * 00441 * Set_Trace_Region 00442 * 00443 * Note a Region to be traced. 00444 * 00445 * ==================================================================== 00446 */ 00447 void 00448 Set_Trace_Region_Number ( INT number ) 00449 { 00450 if ( ++REGION_NCnt >= REGION_COUNT ) { 00451 ErrMsg ( EC_Trace_REGIONs, "<number>"); 00452 --REGION_NCnt; 00453 } else 00454 Region_Num_Enable[REGION_NCnt] = number; 00455 return; 00456 } 00457 00458 /* ==================================================================== 00459 * 00460 * Get_BB_Trace 00461 * 00462 * Determine whether a given BB is enabled for tracing, independent of 00463 * other trace options. If specific PUs are enabled, any BBs in that 00464 * PU are automatically enabled. 00465 * 00466 * ==================================================================== 00467 */ 00468 00469 BOOL 00470 Get_BB_Trace ( INT32 bb_id ) 00471 { 00472 INT16 i; 00473 BOOL enabled = TRUE; 00474 00475 if ( PU_Cnt > 0 ) { 00476 for ( i = 1; i <= PU_Cnt; i++ ) { 00477 if ( strcmp(PU_Enable[i],Current_PU_Name) == 0 ) return TRUE; 00478 } 00479 enabled = FALSE; 00480 } 00481 if ( PU_NCnt > 0 ) { 00482 for ( i = 1; i <= PU_NCnt; i++ ) { 00483 if ( PU_Num_Enable[i] == Current_PU_Number ) return TRUE; 00484 } 00485 enabled = FALSE; 00486 } 00487 00488 if ( BB_Cnt > 0 ) { 00489 for ( i = 1; i <= BB_Cnt; i++ ) { 00490 if (TB_Enable[i] == bb_id) return TRUE; 00491 } 00492 return FALSE; 00493 } 00494 00495 /* If there are no -tf or -tb flags, everything is enabled: */ 00496 return enabled; 00497 } 00498 00499 /* ==================================================================== 00500 * 00501 * Get_Trace 00502 * 00503 * Determine whether the trace flag given by func/arg is set. 00504 * 00505 * ==================================================================== 00506 */ 00507 00508 BOOL 00509 Get_Trace ( INT func, INT arg ) 00510 { 00511 BOOL result; 00512 INT16 i; 00513 00514 /* Get the internal flag: */ 00515 switch ( func ) { 00516 /* INFO mask: */ 00517 case TKIND_INFO: 00518 result = (TI_Mask & arg) != 0; 00519 break; 00520 /* DEBUG mask: */ 00521 case TKIND_DEBUG: 00522 result = (TD_Mask & arg) != 0; 00523 break; 00524 /* IR phase: */ 00525 case TKIND_IR: 00526 result = TI_Phase[arg]; 00527 break; 00528 /* SYMTAB phase: */ 00529 case TKIND_SYMTAB: 00530 result = TS_Phase[arg]; 00531 break; 00532 /* TN phase: */ 00533 case TKIND_TN: 00534 result = TN_Phase[arg]; 00535 break; 00536 /* Control option: */ 00537 case TKIND_CTRL: 00538 result = TC_Enable[arg]; 00539 break; 00540 /* Memory stats: */ 00541 case TKIND_ALLOC: 00542 result = TA_Phase[arg]; 00543 break; 00544 /* fall-through to default case */ 00545 case TKIND_BB: 00546 case TKIND_XPHASE: 00547 /* Per-phase mask: */ 00548 default: 00549 result = (TP_Mask[func] & arg) != 0; 00550 break; 00551 } 00552 00553 if ( result && PU_Cnt > 0 ) { /* trace for certain PUs, by name */ 00554 for ( i = 1; i <= PU_Cnt; i++ ) { 00555 if ( strcmp(PU_Enable[i], Current_PU_Name) == 0 ) 00556 break; 00557 } 00558 if (i > PU_Cnt) 00559 result = FALSE; 00560 } 00561 00562 if ( result && PU_NCnt > 0 ) { /* trace for certain PUs, by number */ 00563 for ( i = 1; i <= PU_NCnt; i++ ) { 00564 if ( PU_Num_Enable[i] == Current_PU_Number ) 00565 break; 00566 } 00567 if (i > PU_NCnt) 00568 result = FALSE; 00569 } 00570 00571 if (result && REGION_NCnt > 0) { /* trace for certain regions, by number */ 00572 for ( i = 1; i <= REGION_NCnt; i++ ) { 00573 if ( Region_Num_Enable[i] == Current_Region_Number ) 00574 break; 00575 } 00576 if ( i > REGION_NCnt ) 00577 result = FALSE; 00578 } 00579 00580 return result; 00581 } 00582 00583 /* ==================================================================== 00584 * 00585 * Stop_Execution 00586 * 00587 * Determine whether the given phase number is beyond the specified 00588 * last execution phase. This is currently a simple linear sequence 00589 * of phase numbers, with no complications. 00590 * 00591 * ==================================================================== 00592 */ 00593 00594 BOOL 00595 Stop_Execution ( INT phase ) 00596 { 00597 return phase >= Xstop_Phase; 00598 } 00599 00600 /* ==================================================================== 00601 * 00602 * Set_Trace_File 00603 * 00604 * By default, traces are sent to stdout, which of course is open on 00605 * startup. If tracing is to be directed to another file (recommended 00606 * for permanence), this routine should be called before any tracing is 00607 * done. It will close the previous trace file (if not stdout) and 00608 * open the new one, setting TFile to the new file descriptor. 00609 * 00610 * ==================================================================== 00611 */ 00612 00613 void 00614 Set_Trace_File ( 00615 char *filename ) /* Name of new trace file */ 00616 { 00617 if ( Non_stdout_TFile && TFile_internal != NULL ) { 00618 #ifndef FRONT_END_F77 00619 fclose (TFile_internal); 00620 #endif 00621 Set_Error_Trace (NULL); 00622 } 00623 00624 if ( filename != NULL ) { 00625 #ifdef FRONT_END_F77 00626 TFile_internal = Kqqgso(); 00627 #else 00628 TFile_internal = fopen ( filename, "w" ); /* Truncate */ 00629 #endif 00630 if ( TFile_internal != NULL ) { 00631 TFile_Name = filename; 00632 Non_stdout_TFile = TRUE; 00633 Set_Error_Trace (TFile_internal); 00634 return; 00635 } 00636 ErrMsg ( EC_Trace_Open, filename, errno ); 00637 } 00638 TFile_internal = stdout; 00639 TFile_Name = NULL; 00640 Non_stdout_TFile = FALSE; 00641 Set_Error_Trace (NULL); 00642 } 00643 00644 void Set_Trace_File_internal(FILE *f) 00645 { 00646 TFile_internal = f; 00647 } 00648 00649 FILE *Get_Trace_File(void) 00650 { 00651 if (TFile_internal == NULL) 00652 TFile_internal = stdout; 00653 00654 return TFile_internal; 00655 } 00656 00657 void 00658 Trace_To_Stderr(void) 00659 { 00660 if ( Non_stdout_TFile && TFile_internal != NULL ) { 00661 #ifndef FRONT_END_F77 00662 fclose (TFile_internal); 00663 #endif 00664 Set_Error_Trace (NULL); 00665 } 00666 00667 TFile_internal = stderr; 00668 TFile_Name = NULL; 00669 Non_stdout_TFile = FALSE; 00670 Set_Error_Trace (NULL); 00671 } 00672 00673 00674 #ifndef MONGOOSE_BE 00675 /* ==================================================================== 00676 * 00677 * Nest_Indent 00678 * 00679 * Emit indenting spaces to the given file, based on the current 00680 * (compiler) stack depth. 00681 * 00682 * ==================================================================== 00683 */ 00684 00685 void 00686 Nest_Indent ( FILE *fp ) 00687 { 00688 fprintf ( fp, "%*c", ( INDENT * ( trace_stack(0,0) - 1 ) ), ' ' ); 00689 } 00690 #endif /* MONGOOSE_BE */