Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
tracing.c
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  * ====================================================================
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 */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines