Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
messages.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 static char USMID[] = "\n@(#)5.0_pl/sources/messages.c  5.9     10/14/99 14:08:59\n";
00038 
00039 # include <stdarg.h>
00040 # include <stdlib.h> /* for putenv() */
00041 
00042 # include "defines.h"           /* Machine dependent ifdefs */
00043 
00044 
00045 # define  __NLS_INTERNALS  1
00046 
00047 # if defined(_HOST_OS_LINUX)
00048 /*  typedef __int32_t;  */
00049 # include <nl_types.h>
00050 # include <nlcatmsg.h>
00051 
00052 # else
00053 # include "nl_types.h"
00054 # endif
00055 
00056 
00057 
00058 # include "host.m"              /* Host machine dependent macros.*/
00059 # include "host.h"              /* Host machine dependent header.*/
00060 # include "target.m"            /* Target machine dependent macros.*/
00061 # include "target.h"            /* Target machine dependent header.*/
00062 
00063 # include "globals.m"
00064 # include "tokens.m"
00065 # include "sytb.m"
00066 # include "debug.m"
00067 # include "messages.m"
00068 
00069 # include "globals.h"
00070 # include "tokens.h"
00071 # include "sytb.h"
00072 # include "messages.h"
00073 
00074 #  define        CIF_VERSION           3    /* Must be defined before         */
00075                                             /*   including cif.h              */
00076 
00077 # include "cif.h"
00078 
00079 
00080 /*****************************************************************\
00081 |* Function prototypes of static functions declared in this file *|
00082 \*****************************************************************/
00083 
00084 static int      compare_message_recs(const void *, const void *);
00085 static void     flush_msg_file(void);
00086 
00087 
00088 /******************************************************************************\
00089 |*                                                                            *|
00090 |* Description:                                                               *|
00091 |*      init_msg_processing is called by compiler initialization in main to   *|
00092 |*      determine the name used when the compiler was invoked.  It can either *|
00093 |*      be passed by a script via an environment variable or is the name used *|
00094 |*      when the compiler is directly invoked.                                *|
00095 |*                                                                            *|
00096 |* Input parameters:                                                          *|
00097 |*      *argv - pointer to command line argument string                       *|
00098 |*                                                                            *|
00099 |* Output parameters:                                                         *|
00100 |*      NONE                                                                  *|
00101 |*                                                                            *|
00102 |* Returns:                                                                   *|
00103 |*      NOTHING                                                               *|
00104 |*                                                                            *|
00105 \******************************************************************************/
00106 
00107 void init_msg_processing (char *argv[])
00108 
00109 {
00110    static char        *allocstr;
00111 
00112    TRACE (Func_Entry, "init_msg_processing", NULL);
00113 
00114    /* Unconditionally open the message system */
00115 
00116 #if defined(GENERATE_WHIRL)
00117 
00118   if (getenv("NLSPATH") == NULL) {
00119     /* NLSPATH is not set. */
00120     const char * const toolroot = getenv("TOOLROOT");
00121     const char * const env_name = "NLSPATH=";
00122     const char * const env_val = "/usr/lib/locale/C/LC_MESSAGES/%N.cat";
00123     int len = strlen(env_name) + strlen(env_val) + 1;
00124     char * new_env;
00125     if (toolroot != NULL) len += strlen(toolroot);
00126     new_env = malloc(len);
00127     if (toolroot == NULL)
00128       sprintf(new_env, "%s%s", env_name, env_val);
00129     else
00130       sprintf(new_env, "%s%s%s", env_name, toolroot, env_val);
00131     putenv(new_env);
00132     free(new_env);
00133   }
00134 
00135 #endif
00136 
00137 /* cf90.cat needs to be installed in /usr/lib/locale/C/LC_MESSAGES,
00138  * another way is just to give it an explicit pathname - we can define
00139  * a macro in Makefile for this purpose.
00140  */
00141    msg_sys = catopen(CF90CATPATHNAME, 0); 
00142 
00143    if (msg_sys == (nl_catd) -1) {  /* (nl_catd) is msg_sys's type. */
00144 
00145 # if defined(_HOST_OS_LINUX)
00146       fprintf (stderr, "sgif90 INTERNAL: Unable to open message system.\n");
00147 # else
00148       fprintf (stderr, "cf90 INTERNAL: Unable to open message system.\n");
00149 # endif
00150       exit_compiler(RC_USER_ERROR);
00151 
00152    }
00153 
00154    save_glb_line_num = 0;
00155    save_column_num   = 0;
00156 
00157 
00158    /* Determine the command name used to access the compiler.  This is        */
00159    /* needed for message processing and therefore must be done                */
00160    /* before any messages are printed.                                        */
00161    /* See if ORIG_CMD_NAME environment variable exists                        */
00162 
00163    command_name = getenv ("ORIG_CMD_NAME");
00164 
00165    if (command_name == NULL) {  /* ORIG_CMD_NAME is not defined; set it.  */ 
00166       command_name = argv[0];
00167       command_name = strrchr (argv[0], SLASH);  /* search for rightmost slash */
00168       command_name = (command_name == NULL) ? argv[0] : command_name+1;
00169    }
00170    else {  /* ORIG_CMD_NAME is defined */
00171       /* Copy it.  Note that allocstr gets the result of memory allocation    */
00172       /* not command_name.  If an error occurs during memory allocation,      */
00173       /* command_name is still valid and the message printed will have the    */
00174       /* correct command name.                                                */
00175       MEM_ALLOC (allocstr, char, strlen(command_name)+1);
00176 
00177       if (allocstr != NULL) {  /* if no memory allocation error... */
00178          strcpy (allocstr, command_name); 
00179 
00180          /* copy is necessary since allocstr could be over written later.     */
00181          command_name = allocstr;  
00182       }
00183    }
00184 
00185    TRACE (Func_Exit, "init_msg_processing", NULL);
00186 
00187    return;
00188 
00189 }  /* init_msg_processing */
00190 
00191 
00192 /******************************************************************************\
00193 |*                                                                            *|
00194 |* Description:                                                               *|
00195 |*      This routine is the 'common message processor' for f90.  It is        *|
00196 |*      called by the f90 front-end.                            
00197 |*                                                                            *|
00198 |* Input parameters:                                                          *|
00199 |*      glb_line_num     If non-zero:  Global line number of source; this     *|
00200 |*                         number maps onto a line number within the current  *|
00201 |*                         file.                                              *|
00202 |*                       If zero    :  Indicates that a message header should *|
00203 |*                         should not be output.                              *|
00204 |*      msg_num          The message number of the text to be output.         *|
00205 |*      msg_severity     The severity level.                                  *|
00206 |*      column_num       If non-zero:  Column is put into the header.         *|
00207 |*                       If zero    :  Column is not put into header.         *|
00208 |*      arg1, arg2,      Four optional arguments that can be inserted into    *|
00209 |*      arg3, arg4       into the message text.                               *|
00210 |*                                                                            *|
00211 |*                       Notes:                                               *|
00212 |*                         - No validation check is made for missing or extra *|
00213 |*                           arguments in the message text.  It is up to the  *|
00214 |*                           developer to insure that the same number of      *|
00215 |*                           arguments passed to PRINTMSG are in the message  *|
00216 |*                           text.                                            *|
00217 |*                                                                            *|
00218 |*                         - Function cif_message_rec must scan the message   *|
00219 |*                           text for the format descriptors.  To make its    *|
00220 |*                           life easier, the formats are restricted to:      *|
00221 |*                             %c  %d  %f  %s                                 *|
00222 |*                                                                            *|
00223 |* Output parameters:                                                         *|
00224 |*      NONE                                                                  *|
00225 |*                                                                            *|
00226 |* Returns:                                                                   *|
00227 |*      NOTHING                                                               *|
00228 |*                                                                            *|
00229 \******************************************************************************/
00230 
00231 void PRINTMSG (int                      glb_line_num,
00232                int                      msg_num,
00233                msg_severities_type      msg_severity, 
00234                int                      column_num, 
00235                ... )
00236 
00237 {
00238    long         arg1;
00239    long         arg2;
00240    long         arg3;
00241    long         arg4;
00242    va_list      arg_ptr;
00243    boolean      error;
00244    boolean      exit_now;
00245    boolean      warning;
00246 
00247 # if defined(_DEBUG)
00248    boolean      issue_line_out_of_range_msg     = FALSE;
00249 # endif
00250 
00251 
00252 /* END_UNIT is stolen from fecif.m so that the whole header need not be       */
00253 /* included.                                                                  */
00254 
00255 # define END_UNIT                18             /* End Unit                   */
00256 
00257 
00258    TRACE (Func_Entry, "PRINTMSG", NULL);
00259 
00260 # ifdef _DEBUG
00261    /* Validate message number range. */
00262 
00263    if (msg_num > MAX_MSG || msg_num < 0) {
00264       PRINTMSG (glb_line_num, 1, Internal, 0, msg_num);
00265    }
00266 
00267 # endif
00268 
00269    exit_now = TRUE;
00270 
00271    error        = GET_MESSAGE_TBL(message_error_tbl, msg_num);
00272    warning      = GET_MESSAGE_TBL(message_warning_tbl, msg_num);
00273 
00274    if ((error && (msg_severity != Error)) || 
00275        (warning && msg_severity != Warning)) {  /* Switching msg_severity */
00276 
00277       switch (msg_severity) {
00278       case Ansi:
00279       case Comment:
00280       case Note:
00281       case Caution:
00282       case Warning:
00283          msg_severity = (error) ? Error : Warning;
00284          break;
00285 
00286       case Error:
00287 
00288          if (warning) {
00289             PRINTMSG (glb_line_num, 1653, Warning, 0, msg_num, "warning");
00290          }
00291          error = FALSE; /* This is already an error level */
00292          break;
00293 
00294       case Vector:
00295       case Scalar:
00296       case Table:
00297       case Inline:
00298       case Info:
00299       case Tasking:
00300       case Optimization:
00301       case Stream:
00302 
00303       case Internal:
00304       case Limit:
00305       case Log_Error:
00306       case Log_Warning:
00307       case Log_Summary:
00308          PRINTMSG (glb_line_num, 1653, Warning, 0, msg_num, 
00309                    (error) ? "error" : "warning");
00310          break;
00311       }
00312    }
00313 
00314    if (msg_severity != Log_Warning  &&
00315        msg_severity != Log_Error    &&
00316        msg_severity != Log_Summary) {
00317 
00318       /* If the line number for the message is 0, it needs extra          */
00319       /* considerations.  If the message was produced by the front-end,   */
00320       /* issue the 0 line number message and then issue message 296 to    */
00321       /* diagnose the 0 line number.  If the message was produced by any  */
00322       /* component OTHER THAN the front-end and it's an Internal or Limit */
00323       /* message, just issue the 0 line number message. If it's NOT an    */
00324       /* Internal or Limit message, also issue 296.  In all 0 line number */
00325       /* cases, use stmt_start_line for the line number.  Note that a     */
00326       /* line number of 0 is acceptable for the Log_ messages.            */
00327 
00328 
00329       if (glb_line_num == 0) {
00330 
00331          if (msg_num <= MAX_FE_MSG  ||
00332              (msg_severity != Limit  &&  msg_severity != Internal)) {
00333 
00334             glb_line_num = (stmt_start_line > 0) ? stmt_start_line : 1;
00335 
00336             /* Set exit_now to FALSE in the event the message is an Internal  */
00337             /* or Limit message to prevent the call to exit_compiler.         */
00338             /* exit_compiler will be called when message 296 is issued later. */
00339      
00340             exit_now = FALSE;
00341          }
00342 # if defined(_DEBUG)
00343 
00344          if (dump_flags.msg_checking) {
00345 
00346             /* We are doing extra message checking.      */
00347             /* Issue an abort for all zero line numbers. */
00348 
00349             exit_now = FALSE;
00350          }
00351 # endif
00352       }
00353       else if (glb_line_num < pgm_unit_start_line && msg_num > MAX_FE_MSG) {
00354 
00355          /* In some cases, a line number outside of the current program unit  */
00356          /* may be sent to the frontend.  Technically this should be fixed,   */
00357          /* but to prevent an internal abort we will adjust the line number   */
00358          /* to be set the the start of the current program unit for a non     */
00359          /* frontend message.                                                 */
00360 
00361          glb_line_num = pgm_unit_start_line;
00362 
00363 # if defined(_DEBUG)
00364 
00365          /* We are doing extra message checking.         */
00366          /* Issue a message about bad line number later. */
00367 
00368          issue_line_out_of_range_msg = (dump_flags.msg_checking) ? TRUE : FALSE;
00369 # endif
00370       }
00371    }
00372 
00373    switch (msg_severity) {
00374 
00375       case Ansi:
00376 
00377          if (on_off_flags.issue_ansi_messages) {
00378 
00379             if (GET_MESSAGE_TBL(message_suppress_tbl, msg_num)) {
00380                break;
00381             }
00382 
00383             if (cif_tmp_so_no_msg) {
00384                break;
00385             }
00386 
00387             num_ansi++;
00388             va_start (arg_ptr, column_num);
00389             arg1 = va_arg (arg_ptr, long);
00390             arg2 = va_arg (arg_ptr, long);
00391             arg3 = va_arg (arg_ptr, long);
00392             arg4 = va_arg (arg_ptr, long);
00393             va_end (arg_ptr);
00394             output_msg (glb_line_num, msg_num, msg_severity,
00395                         column_num, arg1, arg2, arg3, arg4);
00396 
00397 # ifdef _DEBUG
00398             if (dump_flags.abort_on_ansi) {
00399 
00400                output_msg (glb_line_num, 597, Limit, 0, 0, 0, 0, 0);
00401    
00402                exit_compiler(RC_USER_ERROR);
00403             }
00404 # endif
00405 
00406          }
00407 
00408          break;
00409          
00410 
00411       case Comment:
00412 
00413          if (cmd_line_flags.msg_lvl_suppressed <= Comment_Lvl) {
00414 
00415             if (GET_MESSAGE_TBL(message_suppress_tbl, msg_num)) {
00416                break;
00417             }
00418 
00419             if (cif_tmp_so_no_msg) {
00420                break;
00421             }
00422 
00423             num_comments++;
00424             va_start (arg_ptr, column_num);
00425             arg1 = va_arg (arg_ptr, long);
00426             arg2 = va_arg (arg_ptr, long);
00427             arg3 = va_arg (arg_ptr, long);
00428             arg4 = va_arg (arg_ptr, long);
00429             va_end (arg_ptr);
00430             output_msg (glb_line_num, msg_num, msg_severity,  /*PRINTMSG */
00431                         column_num, arg1, arg2, arg3, arg4);
00432          }
00433 
00434          break;
00435 
00436          
00437       case Note:
00438 
00439          if (cmd_line_flags.msg_lvl_suppressed <= Note_Lvl) {
00440 
00441             if (GET_MESSAGE_TBL(message_suppress_tbl, msg_num)) {
00442                break;
00443             }
00444 
00445             if (cif_tmp_so_no_msg) {
00446                break;
00447             }
00448 
00449             num_notes++;
00450             va_start (arg_ptr, column_num);
00451             arg1 = va_arg (arg_ptr, long);
00452             arg2 = va_arg (arg_ptr, long);
00453             arg3 = va_arg (arg_ptr, long);
00454             arg4 = va_arg (arg_ptr, long);
00455             va_end (arg_ptr);
00456             output_msg (glb_line_num, msg_num, msg_severity,  
00457                         column_num, arg1, arg2, arg3, arg4);
00458          }
00459 
00460          break;
00461 
00462          
00463       case Caution:
00464 
00465          if (cmd_line_flags.msg_lvl_suppressed <= Caution_Lvl) {
00466 
00467             if (GET_MESSAGE_TBL(message_suppress_tbl, msg_num)) {
00468                break;
00469             }
00470 
00471             if (cif_tmp_so_no_msg) {
00472                break;
00473             }
00474 
00475             num_cautions++;
00476             va_start (arg_ptr, column_num);
00477             arg1 = va_arg (arg_ptr, long);
00478             arg2 = va_arg (arg_ptr, long);
00479             arg3 = va_arg (arg_ptr, long);
00480             arg4 = va_arg (arg_ptr, long);
00481             va_end (arg_ptr);
00482             output_msg (glb_line_num, msg_num, msg_severity,
00483                         column_num, arg1, arg2, arg3, arg4);
00484          }
00485 
00486          break;
00487 
00488 
00489       case Warning:
00490 
00491          if (cmd_line_flags.msg_lvl_suppressed <=  Warning_Lvl) {
00492 
00493             if (GET_MESSAGE_TBL(message_suppress_tbl, msg_num)) {
00494                break;
00495             }
00496 
00497             if (cif_tmp_so_no_msg) {
00498                break;
00499             }
00500 
00501             num_warnings++;
00502             va_start (arg_ptr, column_num);
00503             arg1 = va_arg (arg_ptr, long);
00504             arg2 = va_arg (arg_ptr, long);
00505             arg3 = va_arg (arg_ptr, long);
00506             arg4 = va_arg (arg_ptr, long);
00507             va_end (arg_ptr);
00508             output_msg (glb_line_num, msg_num, msg_severity,
00509                         column_num, arg1, arg2, arg3, arg4);
00510          }
00511 
00512          break;
00513 
00514 
00515       case Error:
00516 
00517          if (cif_tmp_so_no_msg) {
00518             break;
00519          }
00520 
00521          num_errors++;
00522          num_prog_unit_errors++;
00523 
00524          va_start (arg_ptr, column_num);
00525          arg1 = va_arg (arg_ptr, long);
00526          arg2 = va_arg (arg_ptr, long);
00527          arg3 = va_arg (arg_ptr, long);
00528          arg4 = va_arg (arg_ptr, long);
00529          va_end (arg_ptr);
00530          output_msg (glb_line_num, msg_num, msg_severity,  /*PRINTMSG */
00531                          column_num, arg1, arg2, arg3, arg4);
00532 
00533          if (!error                                         &&
00534              curr_stmt_sh_idx > NULL_IDX                    && 
00535              curr_stmt_sh_idx <= sh_tbl_idx                 &&
00536              glb_line_num >= SH_GLB_LINE(curr_stmt_sh_idx)) {
00537 
00538             /* only set error flag if have statement header to set it on. */
00539             /* Since src_input delays issuing messages until the correct  */
00540             /* line is seen, there will be no header for this line if not */
00541             /* already created.                                           */
00542 
00543             /* Do not set if this is a forced error with -M option.       */
00544 
00545             SH_ERR_FLG(curr_stmt_sh_idx) = TRUE;
00546          }
00547 
00548          if (on_off_flags.abort_if_any_errors) {
00549 
00550             if (c_i_f != NULL) {
00551                flush_msg_file();
00552             }
00553 
00554             /* Put the option into the message as a string substitution       */
00555             /* because our Technology Partners might use a different option.  */
00556 
00557             output_msg (glb_line_num, 1226, Limit, 0, 0, 0, 0, 0);
00558 
00559             PRINT_GL_TBL;      /* Prints to dump_file ifdef _DEBUG and -u glt */
00560 
00561 
00562             /* Output a dummy Summary record signalling the abort because     */
00563             /* libcif has a very difficult time dealing with a "truncated"    */
00564             /* CIF.  The CIF must be reopened and c_i_f must be reset so that */
00565             /* cif_summary_rec will work.  The CIF was closed and c_i_f was   */
00566             /* set to NULL when flush_msg_file (just above) called            */
00567             /* print_buffered_messages.  It needs to be reset to NULL to      */
00568             /* signal to exit_compiler that the messages have been printed.   */
00569 
00570             c_i_f = fopen(cif_name, "a+");
00571 
00572             cif_summary_rec("Ignore this",
00573                             "Ignore this",
00574                             "Ignore this",
00575                             0,
00576                             0,
00577                             -1);                               /* Abort flag. */
00578 
00579             c_i_f = NULL;
00580 
00581             exit_compiler(RC_USER_ERROR);
00582          }
00583 
00584          if (on_off_flags.abort_on_100_errors  &&
00585              num_errors >= MAX_ERR_LIMIT) {
00586 
00587             if (c_i_f != NULL) {
00588                flush_msg_file();
00589             }
00590 
00591             output_msg(glb_line_num, 214, Limit, 0, MAX_ERR_LIMIT, 0, 0, 0);
00592 
00593             PRINT_GL_TBL;      /* Prints to dump_file ifdef _DEBUG and -u glt */
00594 
00595 
00596             /* Output a dummy Summary record signalling the abort because     */
00597             /* libcif has a very difficult time dealing with a "truncated"    */
00598             /* CIF.  The CIF must be reopened and c_i_f must be reset so that */
00599             /* cif_summary_rec will work.  The CIF was closed and c_i_f was   */
00600             /* set to NULL when flush_msg_file (just above) called            */
00601             /* print_buffered_messages.  It needs to be reset to NULL to      */
00602             /* signal to exit_compiler that the messages have been printed.   */
00603 
00604             c_i_f = fopen(cif_name, "a+");
00605 
00606             cif_summary_rec("Ignore this",
00607                             "Ignore this",
00608                             "Ignore this",
00609                             0,
00610                             0,
00611                             -1);                               /* Abort flag. */
00612 
00613             c_i_f = NULL;
00614 
00615             exit_compiler(RC_USER_ERROR);
00616          }
00617 
00618          break;
00619 
00620 
00621       case Log_Error:
00622 
00623          /* Log_Error is seperate from Error because we do not want to do     */
00624          /* most of the checks that are done in Error, like -ea.              */
00625 
00626          num_errors++;
00627          num_prog_unit_errors++;
00628 
00629          va_start (arg_ptr, column_num);
00630          arg1 = va_arg (arg_ptr, long);
00631          arg2 = va_arg (arg_ptr, long);
00632          arg3 = va_arg (arg_ptr, long);
00633          arg4 = va_arg (arg_ptr, long);
00634          va_end (arg_ptr);
00635          output_msg (glb_line_num, msg_num, msg_severity,  /*PRINTMSG */
00636                      column_num, arg1, arg2, arg3, arg4);
00637 
00638          /* VERY SPECIAL CASE:  If message 49                                 */
00639          /*                                                                   */
00640          /*                Cannot open source file "%s".                      */
00641          /*                                                                   */
00642          /* is being issued, it means there is no source file so there is no  */
00643          /* information we can use to construct a valid message file.  So     */
00644          /* just dump the message file entirely so no other part of the       */
00645          /* compiler tries to do anything with it.                            */
00646 
00647          if (msg_num == 49) {
00648             fclose(cif_actual_file);
00649             remove(cif_name);
00650             c_i_f = NULL;
00651             cif_actual_file = NULL;
00652             fclose(cif_tmp_file);
00653             remove(cif_tmp_file_name);
00654             cif_tmp_file = NULL;
00655          }
00656 
00657          break;
00658 
00659 
00660       case Internal:
00661       case Limit:
00662 
00663          if (c_i_f != NULL) {
00664             flush_msg_file();
00665          }
00666 
00667          va_start (arg_ptr, column_num);
00668          arg1 = va_arg (arg_ptr, long);
00669          arg2 = va_arg (arg_ptr, long);
00670          arg3 = va_arg (arg_ptr, long);
00671          arg4 = va_arg (arg_ptr, long);
00672          va_end (arg_ptr);
00673          output_msg (glb_line_num, msg_num, msg_severity,  /*PRINTMSG */
00674                          column_num, arg1, arg2, arg3, arg4);
00675 
00676 
00677          if (comp_phase == Cmdline_Parsing) {
00678 
00679             /* This message is found in commandline parsing before all */
00680             /* proper start up is done.  Just abort compilation here.  */
00681 
00682             exit_compiler(RC_INTERNAL_ERROR);
00683             break;
00684          }
00685 
00686          /* Output a dummy Summary record signalling the abort because libcif */
00687          /* has a very difficult time dealing with a "truncated" CIF.         */
00688          /* The CIF must be reopened and c_i_f must be reset so that          */
00689          /* cif_summary_rec will work.  The CIF was closed and c_i_f was set  */
00690          /* to NULL when flush_msg_file (just above) called print_buffered_   */
00691          /* _messages.  It needs to be reset to NULL to signal to             */
00692          /* exit_compiler that the messages have been printed.                */
00693       
00694          c_i_f = fopen(cif_name, "a+");
00695 
00696          cif_summary_rec("Ignore this", 
00697                          "Ignore this",
00698                          "Ignore this",
00699                          0,
00700                          0,
00701                          -2);                                  /* Abort flag. */
00702 
00703          c_i_f = NULL;
00704 
00705 
00706 # ifdef _DEBUG
00707 
00708          /* Will dump tables, if cmdline option -u requests any dumps and */
00709          /* the dump calls have not been hit int p_driver.c yet.          */
00710 
00711          if (comp_phase < Pdg_Conversion) {
00712             PRINT_ALL_SYM_TBLS;
00713             PRINT_BLK_STK;
00714             PRINT_CMD_LINE_TBLS;
00715             PRINT_GL_TBL;
00716             PRINT_GN_TBL;
00717 
00718             while (curr_scp_idx != NULL_IDX) {
00719                PRINT_DBG_SYTB;
00720                PRINT_DBG_STMT;
00721                curr_scp_idx = SCP_PARENT_IDX(curr_scp_idx);
00722             }
00723 
00724             if (dump_flags.mem_report) {
00725                free_tables();  /* See what the tables look at, at abort. */
00726             }
00727          }
00728 # endif
00729 
00730 # ifdef _DEBUG
00731 # if defined(_HOST_OS_UNICOS) || defined(_HOST_OS_MAX)
00732          if (msg_severity == Internal) {
00733             TRBK ();    
00734          }
00735 # endif
00736 # endif
00737 
00738          /* Do not exit yet if the message has a 0 line number and it was     */
00739          /* produced by the front-end.                                        */
00740 
00741          if (exit_now) {
00742             exit_compiler(RC_INTERNAL_ERROR);
00743          }
00744 
00745          break;
00746 
00747 
00748       case Log_Warning:
00749 
00750          if (GET_MESSAGE_TBL(message_suppress_tbl, msg_num)) {
00751             break;
00752          }
00753 
00754          num_warnings++;
00755 
00756          va_start (arg_ptr, column_num);
00757          arg1 = va_arg (arg_ptr, long);
00758          arg2 = va_arg (arg_ptr, long);
00759          arg3 = va_arg (arg_ptr, long);
00760          arg4 = va_arg (arg_ptr, long);
00761          va_end (arg_ptr);
00762          output_msg (glb_line_num, msg_num, msg_severity,  /*PRINTMSG */
00763                          column_num, arg1, arg2, arg3, arg4);
00764          break;
00765 
00766 
00767       case Log_Summary:
00768 
00769          if (GET_MESSAGE_TBL(message_suppress_tbl, msg_num)) {
00770             break;
00771          }
00772 
00773          va_start (arg_ptr, column_num);
00774          arg1 = va_arg (arg_ptr, long);
00775          arg2 = va_arg (arg_ptr, long);
00776          arg3 = va_arg (arg_ptr, long);
00777          arg4 = va_arg (arg_ptr, long);
00778          va_end (arg_ptr);
00779          output_msg (glb_line_num, msg_num, msg_severity,  /*PRINTMSG */
00780                          column_num, arg1, arg2, arg3, arg4);
00781          break;
00782 
00783 
00784       case Vector:
00785       case Scalar:
00786       case Table:
00787       case Inline:
00788       case Info:
00789       case Tasking:
00790       case Optimization:
00791       case Stream:
00792 
00793          if (GET_MESSAGE_TBL(message_suppress_tbl, msg_num)) {
00794             break;
00795          }
00796 
00797          num_optz_msgs++;
00798          
00799          if ((cif_flags & MESSAGE_RECS) || opt_flags.msgs) {
00800             va_start (arg_ptr, column_num);
00801             arg1 = va_arg (arg_ptr, long);
00802             arg2 = va_arg (arg_ptr, long);
00803             arg3 = va_arg (arg_ptr, long);
00804             arg4 = va_arg (arg_ptr, long);
00805             va_end (arg_ptr);
00806             output_msg (glb_line_num, 
00807                         msg_num,
00808                         msg_severity,
00809                         column_num,
00810                         arg1,
00811                         arg2,
00812                         arg3,
00813                         arg4);
00814          }
00815 
00816          break;
00817 
00818 
00819       default:   /* Invalid message severity */
00820          PRINTMSG (glb_line_num, 2, Internal, 0, msg_severity);
00821          break;
00822    }  /* switch */
00823 
00824 
00825    /* If the message had a 0 line number and the message was produced by the  */
00826    /* front-end, complain about the 0 line number.                            */
00827 
00828    if (! exit_now) {
00829       exit_now = TRUE;
00830       PRINTMSG (glb_line_num, 296, Internal, 0, msg_num, 0);
00831    }
00832 
00833 # if defined(_DEBUG)
00834    if (issue_line_out_of_range_msg) {
00835       PRINTMSG (glb_line_num, 626, Internal, 0, "valid line number","PRINTMSG");
00836    }
00837 # endif
00838 
00839    TRACE (Func_Exit, "PRINTMSG", NULL);
00840 
00841    return; 
00842 
00843 }  /* PRINTMSG */
00844 
00845 
00846 /******************************************************************************\
00847 |*                                                                            *|
00848 |* Description:                                                               *|
00849 |*      This routine is called by PRINTMSG.  It formats the message and       *|
00850 |*      outputs it to stderr.                                                 *|
00851 |*                                                                            *|
00852 |* Input parameters:                                                          *|
00853 |*      glb_line_num     If non-zero:  Global line number of source; this     *|
00854 |*                         number maps onto a line number within the current  *|
00855 |*                         file.                                              *|
00856 |*                       If zero    :  Indicates that a message header should *|
00857 |*                         should not be output.                              *|
00858 |*      msg_num          The message number of the text to be output.         *|
00859 |*      msg_severity     The severity level.                                  *|
00860 |*      column_num       If non-zero:  Column is put into the header.         *|
00861 |*                       If zero    :  Column is not put into header.         *|
00862 |*      arg1, arg2,      Four optional arguments that can be inserted into    *|
00863 |*      arg3, arg4       into the message text.                               *|
00864 |*                                                                            *|
00865 |*                       Note: no validation check is made for missing or     *|
00866 |*                             or extra arguments in the message text.  It is *|
00867 |*                             up to the developer to insure that the same    *|
00868 |*                             number of arguments passed to PRINTMSG are in  *|
00869 |*                             the message text.                              *|
00870 |*                                                                            *|
00871 |* Output parameters:                                                         *|
00872 |*      NONE                                                                  *|
00873 |*                                                                            *|
00874 |* Returns:                                                                   *|
00875 |*      NOTHING                                                               *|
00876 |*                                                                            *|
00877 \******************************************************************************/
00878 
00879 void output_msg (int                            glb_line_num,
00880                  int                            msg_num,
00881                  msg_severities_type            msg_severity, 
00882                  int                            column_num, 
00883                  long                           arg1,
00884                  long                           arg2,
00885                  long                           arg3,
00886                  long                           arg4)
00887 
00888 {
00889           int                    act_file_line;
00890           char                  *act_file_name;
00891           char                   expanded_text[EXPANDED_MSG_SIZE];
00892           char                   final_text[FINAL_MSG_SIZE];
00893           int                    glb_idx;
00894    static int                    last_msg_idx                   = NULL_IDX;
00895           int                    msg_idx;
00896           char                   orig_text[ORIG_MSG_SIZE];
00897           char                   position_buff[MAX_HDR_SIZE];
00898           boolean                print_directly_to_stderr;
00899           char                  *scoping_unit_name;
00900           char                  *text_ptr;
00901 /*
00902    fprintf (stderr, "output_msg: line = %d, num = %d, severity = %d, col = %d\n",
00903             glb_line_num, msg_num, msg_severity, column_num);
00904    return;
00905 */
00906 # if defined(_HOST_OS_UNICOS) || defined(_HOST_OS_MAX)
00907           last_msg_queue_type    msg_desc;
00908 # endif
00909 
00910 
00911    TRACE (Func_Entry, "output_msg", NULL);
00912 
00913    if (comp_phase == Lex_Parsing) {
00914 
00915       /* See if message has already been issued. */
00916 
00917 # if defined(_HOST_OS_UNICOS) || defined(_HOST_OS_MAX)
00918       msg_desc.msg_num  = msg_num;
00919       msg_desc.line_num = glb_line_num;
00920       msg_desc.col_num  = column_num;
00921 # endif
00922 
00923       for (msg_idx = 0; msg_idx < LAST_MSG_QUEUE_SIZE; msg_idx++) {
00924 
00925 # if defined(_HOST_OS_UNICOS) || defined(_HOST_OS_MAX)
00926          if (*((long *) (&msg_desc)) == 
00927              *((long *) (&last_msg_queue[msg_idx]))){
00928             TRACE (Func_Exit, "output_msg", NULL);
00929             return;
00930          }
00931 # else
00932          if (last_msg_queue[msg_idx].msg_num  == msg_num &&
00933              last_msg_queue[msg_idx].line_num == glb_line_num &&
00934              last_msg_queue[msg_idx].col_num  == column_num) {
00935             TRACE (Func_Exit, "output_msg", NULL);
00936             return;
00937          }
00938 # endif
00939       }
00940 
00941       last_msg_queue[last_msg_idx].msg_num      = msg_num;
00942       last_msg_queue[last_msg_idx].line_num     = glb_line_num;
00943       last_msg_queue[last_msg_idx].col_num      = column_num;
00944 
00945       if (++last_msg_idx == LAST_MSG_QUEUE_SIZE) {
00946          last_msg_idx = NULL_IDX;
00947       }
00948    }
00949 
00950 
00951    /* The Syntax Pass depends on the messages coming out in the same order    */
00952    /* they were issued.  Since the sort routine used to sort messages by line,*/
00953    /* column, and message number has different internal algorithms on         */
00954    /* different architectures, we need to use the "relative order" field of   */
00955    /* the Message record to keep Syntax Pass messages in the intended order.  */
00956 
00957    if (comp_phase == Pass1_Parsing) {
00958 
00959       if (save_glb_line_num == glb_line_num  &&
00960           save_column_num == column_num) {
00961          ++relative_order;
00962       }
00963       else {
00964          save_glb_line_num = glb_line_num;
00965          save_column_num   = column_num;
00966          relative_order    = 1;
00967       }
00968    }
00969    else {
00970       relative_order = 0;
00971    }
00972 
00973 
00974    switch (msg_severity) {
00975 
00976       case Log_Warning:
00977       case Log_Error:
00978          print_directly_to_stderr = TRUE;
00979          sprintf (position_buff, "in command line"); 
00980          break;
00981 
00982       case Log_Summary:
00983          print_directly_to_stderr = TRUE;
00984          break;
00985 
00986       default:
00987 
00988          if (comp_phase == Cmdline_Parsing) {
00989             print_directly_to_stderr = TRUE;
00990             sprintf (position_buff, "in command line"); 
00991             break;
00992          }
00993 
00994          print_directly_to_stderr =
00995 
00996 # ifdef _DEBUG
00997             dump_flags.std_err             ||
00998 # endif
00999             (msg_severity == Internal  ||  msg_severity == Limit);
01000 
01001          if (print_directly_to_stderr) {
01002 
01003             /* Print source line and ^ before printing the message.     */
01004 
01005             print_err_line(glb_line_num, column_num);
01006          }
01007 
01008          GLOBAL_LINE_TO_FILE_LINE(glb_line_num, glb_idx, act_file_line);
01009          act_file_name = GL_FILE_NAME_PTR(glb_idx);
01010 
01011          if (scp_tbl == NULL_IDX) {
01012             scoping_unit_name = program_unit_name;
01013 
01014             /* Error condition exists before init_parser has been       */
01015             /* invoked or the tables have already been freed.           */
01016 
01017             if (print_directly_to_stderr) {
01018                sprintf (position_buff, "%s, File = %s, Line = %d ",
01019                         program_unit_name,
01020                         act_file_name,
01021                         act_file_line);
01022             }
01023          }
01024          else {
01025             scoping_unit_name = AT_OBJ_NAME_PTR(SCP_ATTR_IDX(curr_scp_idx));
01026 
01027             if (print_directly_to_stderr) {
01028 
01029                if (column_num == 0) {
01030                   sprintf (position_buff, "%s, File = %s, Line = %d ",
01031                            AT_OBJ_NAME_PTR(SCP_ATTR_IDX(curr_scp_idx)), 
01032                            act_file_name,
01033                            act_file_line);
01034                }
01035                else {
01036                   sprintf (position_buff,
01037                            "%s, File = %s, Line = %d, Column = %d ",
01038                            AT_OBJ_NAME_PTR(SCP_ATTR_IDX(curr_scp_idx)), 
01039                            act_file_name,
01040                            act_file_line,
01041                            column_num);
01042                }
01043             }
01044          }
01045 
01046    }  /* End switch */
01047 
01048 
01049    text_ptr = (char *) catgetmsg(msg_sys,
01050                                  NL_SETD,
01051                                  msg_num,
01052                                  orig_text,
01053                                  ORIG_MSG_SIZE);
01054              
01055    if (*text_ptr == (char) NULL) {      /* Unable to retrieve message. */
01056 
01057       if (msg_num == 3) {
01058 
01059          /* The message catalog must really be messed up, because we cannot   */
01060          /* find the message that says we cannot find the message.  fprintf   */
01061          /* to stderr and abort compilation.  If the driver provided the      */
01062          /* message file, get rid of it so the driver won't get confused.     */
01063          /* exit_compiler will handle the rest.                               */
01064          /*                                                                   */
01065          /* LRR   4/10/97                                                     */
01066          /* SPRs 704082 and 700504 complained about message 3 being issued    */
01067          /* when the compiler ran out of memory and not giving the user a     */
01068          /* clue as to what happened.  I enhanced message 3 to give users     */
01069          /* more of a clue as to what could possibly have happened and then   */
01070          /* added the specific check later for the "out of memory" case.      */
01071 
01072 # if defined(_HOST_OS_LINUX)
01073          fprintf(stderr, "sgif90 INTERNAL: "
01074 #else       
01075          fprintf(stderr, "cft90 INTERNAL: "
01076 #endif
01077                          "Message system failed trying to issue message %ld\n",
01078                          arg1);
01079          fprintf(stderr, "  Possible reasons include:\n");
01080          fprintf(stderr, "   * The message catalog has been corrupted.\n");
01081          fprintf(stderr, "   * The message catalog is out of date or "
01082                          "does not match the compiler release.\n");
01083 
01084          if (c_i_f != NULL  &&  (cif_C_opts & CMD_PROVIDED_CIF)) {
01085             fclose(cif_actual_file);
01086             cif_actual_file = NULL;
01087             remove(cif_name);
01088          }
01089 
01090          exit_compiler(RC_USER_ERROR);
01091       }
01092 
01093       /* LRR   4/22/97                                                        */
01094       /* SPRs 704082 and 700504 complained about message 3 being issued when  */
01095       /* the compiler ran out of memory and not giving the user a clue as to  */
01096       /* what happened.  Jeff Drummond and Brian Forney implemented error     */
01097       /* codes and the entry points to retrieve them but only in UNICOS 9.2   */
01098       /* and later.  Because Jon and other SL's decided they wanted to use    */
01099       /* the entry points, MWM changed the build script to copy nl_types.h to */
01100       /* the local build directory so that we can build for releases prior to */
01101       /* 9.2.                                                                 */
01102       /* The code below currently only checks for the "out of memory" case.   */
01103       /* If, in the future, someone really wants to get fancy with this, then */
01104       /* the "if" should be changed to a "switch" on the codes returned from  */
01105       /* __catgetmsg_error_code().                                            */
01106 
01107 # if !defined(_HOST_OS_LINUX)
01108 
01109       if (__catgetmsg_error_code() == NL_CAT_LOCALE) {
01110          fprintf(stderr, "cft90 INTERNAL: "
01111                          "Message system failed trying to issue message %d\n",
01112                          msg_num);
01113          fprintf(stderr, "  User memory space has been exhausted - the "
01114                          "message system has no space in which to work.\n");
01115 
01116          if (c_i_f != NULL  &&  (cif_C_opts & CMD_PROVIDED_CIF)) {
01117             fclose(cif_actual_file);
01118             cif_actual_file = NULL;
01119             remove(cif_name);
01120          }
01121 
01122          exit_compiler(RC_USER_ERROR);
01123       }
01124       else {
01125          PRINTMSG (glb_line_num, 3, Internal, 0, msg_num); 
01126       }
01127 # else
01128       PRINTMSG (glb_line_num, 3, Internal, 0, msg_num); 
01129 # endif
01130    }
01131 
01132    if (print_directly_to_stderr) {
01133 
01134       /* Expand optional arguments, if any, into the message text.            */
01135 
01136       sprintf (expanded_text, orig_text, arg1, arg2, arg3, arg4);
01137    }
01138 
01139 
01140    /* Format and output the message header and text (unless the message is */
01141    /* type Log_Summary; then just output the message text).                */
01142 
01143    if (msg_severity != Log_Summary) {
01144 
01145       if (print_directly_to_stderr) {
01146          text_ptr = expanded_text;
01147          catmsgfmt (command_name,
01148                     message_prefix,
01149                     msg_num, 
01150                     msg_severity_name[msg_severity],
01151                     text_ptr,
01152                     final_text,
01153                     FINAL_MSG_SIZE,
01154                     position_buff,
01155                     (char *) NULL);
01156          fputs (final_text, stderr);
01157       }
01158    }
01159    else {
01160       fputs (expanded_text, stderr);
01161       fputc (NEWLINE, stderr);
01162    }
01163 
01164    if (msg_severity != Log_Warning  &&
01165        msg_severity != Log_Error    &&
01166        msg_severity != Log_Summary  &&
01167        msg_severity != Internal     &&
01168        msg_severity != Limit) {
01169       cif_message_rec(msg_num,
01170                       glb_line_num,
01171                       column_num,
01172                       msg_severity,
01173                       orig_text,
01174                       arg1,
01175                       arg2,
01176                       arg3,
01177                       arg4,
01178                       scoping_unit_name,
01179                       relative_order);
01180    }
01181 
01182    TRACE (Func_Exit, "output_msg", NULL);
01183 
01184    return;
01185 
01186 }  /* output_msg */ 
01187 
01188 
01189 /******************************************************************************\
01190 |*                                                                            *|
01191 |* Description:                                                               *|
01192 |*      Routine that closes necessary files and exits from the compiler       *|
01193 |*                                                                            *|
01194 |* Input parameters:                                                          *|
01195 |*      Number that is output with exit                                       *|
01196 |*                                                                            *|
01197 |* Output parameters:                                                         *|
01198 |*      NONE                                                                  *|
01199 |*                                                                            *|
01200 |* Returns:                                                                   *|
01201 |*      NOTHING                                                               *|
01202 |*                                                                            *|
01203 \******************************************************************************/
01204 
01205 void exit_compiler (int         code)
01206 
01207 {
01208 
01209    TRACE (Func_Entry, "exit_compiler", NULL);
01210 
01211    if (cif_tmp_file != NULL  &&  c_i_f == cif_tmp_file) {
01212       flush_msg_file();
01213    }
01214 
01215    if (c_i_f != NULL) {
01216       print_buffered_messages();
01217    }
01218 
01219    if (cif_actual_file) {
01220       fclose(cif_actual_file);
01221    }
01222 
01223    if (cif_flags == 0) {
01224       remove(cif_name);
01225    }
01226 
01227    catclose (msg_sys);
01228 
01229    clean_up_module_files();
01230 
01231    if (cif_flags != 0) {
01232       close_cif();
01233    }
01234 
01235 
01236 # ifdef _DEBUG
01237 
01238 # if defined(_HOST_OS_SOLARIS) || (defined(_HOST_OS_IRIX) || defined(_HOST_OS_LINUX))
01239 
01240    /* Abort if this is a Limit or an Internal error.                          */
01241 
01242    if (code == RC_INTERNAL_ERROR) {
01243       abort();
01244    }
01245 
01246 # endif
01247 
01248 # endif
01249 
01250    exit (code);
01251 
01252    TRACE (Func_Exit, "exit_compiler", NULL);
01253 
01254 }  /* exit_compiler */
01255 
01256 
01257 /******************************************************************************\
01258 |*                                                                            *|
01259 |* Description:                                                               *|
01260 |*      Routine that finds the file to which a line belongs.  This is needed  *|
01261 |*      for SPARCs.                                                           *|
01262 |*                                                                            *|
01263 |* Input parameters:                                                          *|
01264 |*      search_line : the global line number                                  *|
01265 |*                                                                            *|
01266 |* Output parameters:                                                         *|
01267 |*      NONE                                                                  *|
01268 |*                                                                            *|
01269 |* Returns:                                                                   *|
01270 |*      NOTHING                                                               *|
01271 |*                                                                            *|
01272 \******************************************************************************/
01273 
01274 char *global_to_local_file (int search_line)
01275 {
01276    int           idx;
01277    int           line;
01278    char         *act_file_name;
01279 
01280 
01281    TRACE (Func_Entry, "global_to_local_file", NULL);
01282 
01283    GLOBAL_LINE_TO_FILE_LINE(search_line, idx, line);
01284    act_file_name = GL_FILE_NAME_PTR(idx);
01285 
01286    TRACE (Func_Exit, "global_to_local_file", NULL);
01287 
01288    return(act_file_name);
01289 
01290 }  /* global_to_local_file */
01291 
01292 
01293 
01294 /******************************************************************************\
01295 |*                                                                            *|
01296 |* Description:                                                               *|
01297 |*      Routine that finds the path to which a global line belongs.           *|
01298 |*                                                                            *|
01299 |* Input parameters:                                                          *|
01300 |*      search_line : the global line number                                  *|
01301 |*                                                                            *|
01302 |* Output parameters:                                                         *|
01303 |*      NONE                                                                  *|
01304 |*                                                                            *|
01305 |* Returns:                                                                   *|
01306 |*      NOTHING                                                               *|
01307 |*                                                                            *|
01308 \******************************************************************************/
01309 
01310 char *global_to_local_path (int search_line)
01311 {
01312    int           idx;
01313    int           line;
01314    char         *act_path_name;
01315 
01316 
01317    TRACE (Func_Entry, "global_to_local_path", NULL);
01318 
01319    GLOBAL_LINE_TO_FILE_LINE(search_line, idx, line);
01320    act_path_name = GL_PATH_NAME_PTR(idx);
01321 
01322    TRACE (Func_Exit, "global_to_local_path", NULL);
01323 
01324    return(act_path_name);
01325 
01326 }  /* global_to_local_path */
01327 
01328 
01329 
01330 
01331 
01332 /******************************************************************************\
01333 |*                                                                            *|
01334 |*         * * *   THE FRONTEND DOES NOT USE THIS ROUTINE.   * * *            *|
01335 |*                                                                            *|
01336 |* Description:                                                               *|
01337 |*      Routine that finds a CIF file id for a file containing a given        *|
01338 |*      global line number.                                                   *|
01339 |*                                                                            *|
01340 |* Input parameters:                                                          *|
01341 |*      search_line : the global line number                                  *|
01342 |*                                                                            *|
01343 |* Output parameters:                                                         *|
01344 |*      NONE                                                                  *|
01345 |*                                                                            *|
01346 |* Returns:                                                                   *|
01347 |*      The CIF file id.                                                      *|
01348 |*                                                                            *|
01349 \******************************************************************************/
01350 
01351 int global_to_file_id (int      search_line)
01352 {
01353    int           idx;
01354    int           line;
01355 
01356 
01357    TRACE (Func_Entry, "global_to_file_id", NULL);
01358 
01359    GLOBAL_LINE_TO_FILE_LINE(search_line, idx, line);
01360 
01361    TRACE (Func_Exit, "global_to_file_id", NULL);
01362 
01363    return(GL_CIF_FILE_ID(idx));
01364 
01365 }  /* global_to_file_id */
01366 
01367 
01368 /******************************************************************************\
01369 |*                                                                            *|
01370 |*         * * *   THE FRONTEND DOES NOT USE THIS ROUTINE.   * * *            *|
01371 |*                                                                            *|
01372 |* Description:                                                               *|
01373 |*      This routine converts a global line number to a file line number.     *|
01374 |*      It is called by PDGCS to convert the global line for inserts in       *|
01375 |*      optimization messages.  It is called by CCG for line numbers for      *|
01376 |*      CAL listings and the traceback.                                       *|
01377 |*                                                                            *|
01378 |* Input parameters:                                                          *|
01379 |*      search_line : a global line number                                    *|
01380 |*                                                                            *|
01381 |* Output parameters:                                                         *|
01382 |*      NONE                                                                  *|
01383 |*                                                                            *|
01384 |* Returns:                                                                   *|
01385 |*      The file line number.                                                 *|
01386 |*                                                                            *|
01387 \******************************************************************************/
01388 
01389 int global_to_file_line_number (int     search_line)
01390 {
01391    int  idx;
01392    int  line;
01393 
01394 
01395    TRACE (Func_Entry, "global_to_file_line_number", NULL);
01396 
01397    GLOBAL_LINE_TO_FILE_LINE(search_line, idx, line);
01398 
01399    TRACE (Func_Exit, "global_to_file_line_number", NULL);
01400 
01401    return(line);
01402 
01403 }  /* global_to_file_line_number */
01404 
01405 
01406 /******************************************************************************\
01407 |*                                                                            *|
01408 |*         * * *   THE FRONTEND DOES NOT USE THIS ROUTINE.   * * *            *|
01409 |*                                                                            *|
01410 |* Description:                                                               *|
01411 |*      This routine converts a global line number to a file line number.     *|
01412 |*      It is called by PDGCS and code-gen routines that need to convert the  *|
01413 |*      global line number for optional arguments to PRINTMSG.                *|
01414 |*                                                                            *|
01415 |*      This is simply a different name for global_to_file_line_number.       *|
01416 |*                                                                            *|
01417 |* Input parameters:                                                          *|
01418 |*      search_line : a global line number                                    *|
01419 |*                                                                            *|
01420 |* Output parameters:                                                         *|
01421 |*      NONE                                                                  *|
01422 |*                                                                            *|
01423 |* Returns:                                                                   *|
01424 |*      The file line number.                                                 *|
01425 |*                                                                            *|
01426 \******************************************************************************/
01427 
01428 int global_to_local_line_number (int    search_line)
01429 {
01430    int  idx;
01431    int  line;
01432 
01433 
01434    TRACE (Func_Entry, "global_to_local_line_number", NULL);
01435 
01436    GLOBAL_LINE_TO_FILE_LINE(search_line, idx, line);
01437 
01438    TRACE (Func_Exit, "global_to_local_line_number", NULL);
01439 
01440    return(line);
01441 
01442 }  /* global_to_local_line_number */
01443 
01444 
01445 /******************************************************************************\
01446 |*                                                                            *|
01447 |* Description:                                                               *|
01448 |*      The compiler has encountered a condition where it must terminate the  *|
01449 |*      the compilation.  Output all the messages that have been sent to the  *|
01450 |*      message file first.                                                   *|
01451 |*                                                                            *|
01452 |* Input parameters:                                                          *|
01453 |*      NONE                                                                  *|
01454 |*                                                                            *|
01455 |* Output parameters:                                                         *|
01456 |*      NONE                                                                  *|
01457 |*                                                                            *|
01458 |* Returns:                                                                   *|
01459 |*      NOTHING                                                               *|
01460 |*                                                                            *|
01461 \******************************************************************************/
01462 
01463 static void flush_msg_file(void)
01464 {
01465    int        scp_idx;
01466 
01467 
01468    TRACE (Func_Entry, "flush_msg_file", NULL);
01469 
01470    if (c_i_f == cif_tmp_file) {
01471       cif_fake_a_unit();
01472    }
01473 
01474    if (last_msg_file_rec != END_UNIT) {
01475 
01476       if (curr_scp_idx == 0) {
01477          cif_end_unit_rec(program_unit_name);
01478       }
01479       else {
01480          scp_idx = curr_scp_idx;
01481 
01482          while (SCP_PARENT_IDX(scp_idx) != 0) {
01483             scp_idx = SCP_PARENT_IDX(scp_idx);
01484          }
01485 
01486          cif_end_unit_rec(AT_OBJ_NAME_PTR(SCP_ATTR_IDX(scp_idx)));
01487       }
01488    }
01489 
01490    print_buffered_messages();
01491 
01492    TRACE (Func_Exit, "flush_msg_file", NULL);
01493 
01494    return;
01495 
01496 }  /* flush_msg_file */
01497 
01498 
01499 
01500 /******************************************************************************\
01501 |*                                                                            *|
01502 |* Description:                                                               *|
01503 |*      Print the message file.                                               *|
01504 |*                                                                            *|
01505 |* Input parameters:                                                          *|
01506 |*      NONE                                                                  *|
01507 |*                                                                            *|
01508 |* Output parameters:                                                         *|
01509 |*      NONE                                                                  *|
01510 |*                                                                            *|
01511 |* Returns:                                                                   *|
01512 |*      NOTHING                                                               *|
01513 |*                                                                            *|
01514 \******************************************************************************/
01515 
01516 void print_buffered_messages(void)
01517 {
01518 
01519 
01520 #  define        FILE_STK_MAX        500    /* Just make something up.        */
01521 #  define        MAX_SRC_LINE_SIZE   256    /* Stolen from src_input.m        */
01522 
01523    char          carat[MAX_SRC_LINE_SIZE];
01524    char          expanded_text[EXPANDED_MSG_SIZE];
01525    int           fd;
01526    int           file_line;
01527    char          final_text[FINAL_MSG_SIZE];
01528    int           global_idx;
01529    int           i;
01530    int           line_num;
01531    nl_catd       message_catalog;
01532    char          message_hdr[MAX_HDR_SIZE];
01533    int           msg_idx;
01534    char         *msg_insert;
01535    int           my_file_id;
01536    int           num_msgs;
01537    int           num_recs;
01538    char          orig_text[ORIG_MSG_SIZE];
01539    int           rec_type;
01540    int           search_idx;
01541    char          source_line[MAX_SRC_LINE_SIZE];
01542    int           stk_idx;
01543    int           unit_idx;
01544 
01545    struct        file_stk_frame {int    file_id;
01546                                  int    file_line;
01547                                  FILE  *file_ptr;
01548                                 };
01549 
01550    typedef  struct  file_stk_frame      file_stk_type;
01551 
01552    file_stk_type file_stk[FILE_STK_MAX];
01553 
01554 
01555    struct        Cif_filedir    *filedir;
01556    struct        Cif_unitdir    *unitdir;
01557 
01558    struct        Cif_cifhdr     *header_rec;
01559    struct        Cif_file       *file_rec;
01560    struct        Cif_message    *message_rec;
01561 
01562 
01563 # ifdef _DEBUG
01564 
01565    int                          dbg_global_line;
01566    struct        Cif_message    dbg_message_rec;
01567 
01568 # endif
01569 
01570 
01571    TRACE (Func_Entry, "print_buffered_messages", NULL);
01572 
01573    if (c_i_f == cif_actual_file) {
01574       /* prevent closing the same file twice. Linux does not handle it */
01575       cif_actual_file = NULL;
01576    }
01577 
01578    fclose(c_i_f);
01579 
01580    stk_idx = 0;
01581 
01582 
01583    num_msgs = num_ansi  + num_cautions + num_comments + num_errors +
01584               num_notes + num_warnings;
01585 
01586    if (opt_flags.msgs) {
01587       num_msgs += num_optz_msgs;
01588    }
01589 
01590 
01591    /* It is possible for num_msgs to be nonzero but also have no messages in  */
01592    /* in the message file.  This happens when a Log_ message is the only kind */
01593    /* of message issued (they are counted in num_errors and num_warnings).    */
01594    /* One of the cases where this can happen is when the compiler is asked to */
01595    /* compile a file that does not exist.  The next check weeds this case out.*/
01596    /* If it's not this particular case, we'll just exercise the code in this  */
01597    /* procedure up to the point it figures out there are no Message records   */
01598    /* in the file and then it'll just exit.                                   */
01599 
01600    if (global_line_tbl_idx == 0) {
01601       goto EXIT;
01602    }
01603 
01604 
01605 # ifdef _DEBUG
01606 
01607    if (dump_flags.std_err) {
01608       TRACE (Func_Exit, "print_buffered_messages", NULL);
01609       return;
01610    }
01611 
01612    if (num_msgs == 0) {
01613 
01614       if (dump_flags.stmt_dmp) {
01615          dbg_global_line    = 1;
01616          message_rec        = &dbg_message_rec;
01617          message_rec->uline = GL_GLOBAL_LINE(global_line_tbl_idx) + 1;
01618          goto INIT_FILE_STK;
01619       }
01620       else {
01621          goto EXIT;
01622       }
01623    }
01624 
01625 # else
01626 
01627    if (num_msgs == 0) {
01628       goto EXIT;
01629    }
01630 
01631 # endif
01632 
01633 
01634    /* Convert the ASCII CIF to the more efficient binary form and open the    */
01635    /* binary form of the CIF.  The last argument to Cif_Cifconv being FALSE   */
01636    /* means that the binary output file will be deleted by Cif_Close.         */
01637    /* DEBUG note:  When a scoping unit has problems to the point that         */
01638    /* SCP_IN_ERR is set to TRUE, we set a field in the CIF Summary record to  */
01639    /* -3 to indicate that the CIF is incomplete.  However, Cif_Cifconv does   */
01640    /* not read to the end of the CIF first to read the Summary record, so it  */
01641    /* will likely print out a bunch of messages complaining about sym id's    */
01642    /* not being resolved.  The 0x100 flag allows these messages to come out   */
01643    /* (in a debug compiler); if this flag is FALSE, it tells Cif_Cifconv not  */
01644    /* to print them.                                                          */
01645   
01646 #ifdef _DEBUG
01647 
01648    fd = Cif_Cifconv(cif_name,
01649                     "r",
01650                     NULL,
01651                     CIF_VERSION,
01652                     0x100);
01653 
01654 #else
01655 
01656    fd = Cif_Cifconv(cif_name,
01657                     "r",
01658                     NULL,
01659                     CIF_VERSION,
01660                     FALSE);
01661 
01662 #endif
01663 
01664 
01665    if (fd < 0) {
01666       if (c_i_f == cif_actual_file) {
01667          /* prevent closing the same file twice. Linux does not handle it */
01668          cif_actual_file = NULL;
01669       }
01670       fclose(c_i_f);
01671       c_i_f = NULL;
01672       remove(cif_name);
01673       fclose(cif_tmp_file);
01674       remove(cif_tmp_file_name);
01675       PRINTMSG(1, 1060, Internal, 0, Cif_Errstring(fd));
01676    }
01677 
01678 
01679    /* Set up the memory management and get the initial records.               */
01680 
01681    Cif_Memmode(fd, CIF_MEM_MANAGED);
01682 
01683    rec_type = Cif_Getrecord(fd, (struct Cif_generic **) &header_rec);
01684 
01685    if (rec_type != CIF_CIFHDR) {
01686       line_num = 1;
01687       msg_insert = "first rec is not hdr rec.";
01688       goto EMERGENCY_EXIT;
01689    }
01690 
01691 #if defined(GENERATE_WHIRL)
01692   if (getenv("NLSPATH") == NULL) {
01693     /* NLSPATH is not set. */
01694     const char * const toolroot = getenv("TOOLROOT");
01695     const char * const env_name = "NLSPATH=";
01696     const char * const env_val = "/usr/lib/locale/C/LC_MESSAGES/%N.cat";
01697     int len = strlen(env_name) + strlen(env_val) + 1;
01698     char * new_env;
01699     if (toolroot != NULL) len += strlen(toolroot);
01700     new_env = malloc(len);
01701     if (toolroot == NULL)
01702       sprintf(new_env, "%s%s", env_name, env_val);
01703     else
01704       sprintf(new_env, "%s%s%s", env_name, toolroot, env_val);
01705     putenv(new_env);
01706     free(new_env);
01707   }
01708 #endif
01709 
01710 
01711 /* this catopen also has to be changed, otherwise the final print
01712  * of error messages will be uncorrect (either no detailed message
01713  * or print some nonsense). SGI is okay.
01714  */
01715    message_catalog = catopen(CF90CATPATHNAME, 0);
01716 
01717    Cif_Getfiledir(fd, &filedir);
01718 
01719 
01720    /* File Name records are grouped outside of the Unit records.              */
01721 
01722    Cif_Recgroup(fd, 
01723                 NULL,                  
01724                 CIF_FILE,
01725                 (struct Cif_generic **) &file_rec);
01726 
01727 
01728    /* Initialize the first file stack frame with the information about the    */
01729    /* source file.                                                            */
01730 
01731 INIT_FILE_STK:
01732 
01733    global_idx            = 1;
01734 
01735    file_stk[0].file_id   = GL_CIF_FILE_ID(1);
01736    file_stk[0].file_line = 0;
01737 
01738    if ((file_stk[0].file_ptr = fopen(GL_FILE_NAME_PTR(1), "r")) == NULL) {
01739       line_num = 1;
01740       msg_insert = "can not open source file.";
01741       goto EMERGENCY_EXIT;
01742    }
01743          
01744 
01745 # ifdef _DEBUG
01746 
01747    if (dump_flags.stmt_dmp  &&  num_msgs == 0) {
01748       goto NO_MSGS_STMT_DUMP;
01749    }
01750 
01751 # endif
01752       
01753 
01754    /* Go through all the Unitdir records in order to process the messages     */
01755    /* associated with each program unit.                                      */
01756 
01757    for (unit_idx = 0;  unit_idx < filedir->nunits;  ++unit_idx) {
01758 
01759       Cif_Getunitdir(fd, &filedir->ut[unit_idx], &unitdir);
01760 
01761       num_recs = Cif_Recgroup(fd,
01762                               unitdir,
01763                               CIF_MESSAGE,
01764                               (struct Cif_generic **) &message_rec);
01765 
01766       /* Sort the records by global line and column.                          */
01767       /* Note:  Any Message records that precede the first Unit record are    */
01768       /*        included with the first unit by Cif_Cifconv.                  */
01769 
01770       if (num_recs > 1) {
01771          (void) qsort ( (char *) message_rec,
01772                         num_recs,
01773                         sizeof(struct Cif_message),
01774                        &compare_message_recs);
01775       }
01776 
01777 
01778       /* Go through all the Message records associated with this program      */
01779       /* unit.                                                                */
01780 
01781       for (msg_idx = 0;  msg_idx < num_recs;  ++msg_idx) {
01782 
01783          if ((message_rec->severity == Vector   ||
01784               message_rec->severity == Scalar   ||
01785               message_rec->severity == Table    ||
01786               message_rec->severity == Inline   ||
01787               message_rec->severity == Info     ||
01788               message_rec->severity == Tasking  ||
01789               message_rec->severity == Stream   ||
01790               message_rec->severity == Optimization)  && 
01791              ! opt_flags.msgs) {
01792             ++message_rec;
01793             continue;
01794          }
01795 
01796 # ifdef _DEBUG
01797 
01798          if (dump_flags.stmt_dmp) {
01799             goto CHECK_GL_IDX;
01800          }
01801 
01802 # endif
01803          /* KAY - file_line is set in macro but never used.  Bug???? */
01804 
01805          GLOBAL_LINE_TO_FILE_LINE(message_rec->uline,
01806                                   global_idx,
01807                                   file_line);       
01808          my_file_id = GL_CIF_FILE_ID(global_idx);
01809 
01810          if (my_file_id != file_stk[stk_idx].file_id) {
01811 
01812             for (search_idx = stk_idx - 1;  search_idx >= 0;  --search_idx) {
01813            
01814                if (my_file_id == file_stk[search_idx].file_id) {
01815 
01816                   while (stk_idx != search_idx) {
01817                      fclose(file_stk[stk_idx--].file_ptr);
01818                   }
01819 
01820                   goto HAVE_FILE;
01821                }
01822             }
01823 
01824             ++stk_idx;
01825 
01826             if (stk_idx < FILE_STK_MAX) {
01827                file_stk[stk_idx].file_id = my_file_id;
01828 
01829                for (i = 2;  i < filedir->nfiles;  ++i) {
01830 
01831                   if (file_rec[i].fid == my_file_id) {
01832                      break;
01833                   }
01834                }
01835 
01836                if ((file_stk[stk_idx].file_ptr =
01837                        fopen(file_rec[i].name, "r")) != NULL) { 
01838                   file_stk[stk_idx].file_line = 0;
01839                }
01840                else {
01841                   line_num = message_rec->uline;
01842                   msg_insert = "can not open INCLUDE file.";
01843                   goto EMERGENCY_EXIT;
01844                }
01845             }
01846             else {
01847                line_num = message_rec->uline;
01848                msg_insert = "file_stk size exceeded.";
01849                goto EMERGENCY_EXIT;
01850             }
01851          }
01852 
01853 # ifdef _DEBUG
01854 
01855 CHECK_GL_IDX:
01856 
01857          if (global_idx < global_line_tbl_idx) {
01858         
01859             if (message_rec->uline >= GL_GLOBAL_LINE(global_idx + 1)) {
01860 
01861                while (dbg_global_line < GL_GLOBAL_LINE(global_idx + 1)) {
01862 
01863                   if (fgets(source_line,
01864                              MAX_SRC_LINE_SIZE,
01865                              file_stk[stk_idx].file_ptr) != NULL) {
01866                      ++dbg_global_line;
01867                      ++file_stk[stk_idx].file_line;
01868                      fprintf(stderr, "%s", source_line);
01869                   }
01870                   else {
01871                      line_num = dbg_global_line;
01872                      msg_insert = "can not read source file.";
01873                      goto EMERGENCY_EXIT;
01874                   }
01875                }
01876 
01877                ++global_idx;
01878 
01879                for (search_idx = stk_idx - 1;  search_idx >=0;  --search_idx) {
01880       
01881                   if (GL_CIF_FILE_ID(global_idx) ==
01882                          file_stk[search_idx].file_id) {
01883 
01884                      while (stk_idx != search_idx) {
01885                         fclose(file_stk[stk_idx--].file_ptr);
01886                      }
01887   
01888                      goto CHECK_GL_IDX;
01889                   }
01890                }
01891 
01892                ++stk_idx;
01893 
01894                if (stk_idx < FILE_STK_MAX) {
01895                   file_stk[stk_idx].file_id = GL_CIF_FILE_ID(global_idx);
01896 
01897                   for (i = 2;  i < filedir->nfiles;  ++i) {
01898 
01899                      if (file_rec[i].fid == file_stk[stk_idx].file_id) {
01900                         break;
01901                      }
01902                   }
01903 
01904                   if ((file_stk[stk_idx].file_ptr =
01905                           fopen(file_rec[i].name, "r")) != NULL) {
01906                      file_stk[stk_idx].file_line = 0;
01907                   }
01908                   else {
01909                      line_num = message_rec->uline;
01910                      msg_insert = "can not open INCLUDE file.";
01911                      goto EMERGENCY_EXIT;
01912                   }
01913                }
01914                else {
01915                   line_num = message_rec->uline;
01916                   msg_insert = "file_stk size exceeded.";
01917                   goto EMERGENCY_EXIT;
01918                }
01919 
01920                goto CHECK_GL_IDX;
01921             }
01922          }
01923 
01924 # endif
01925 
01926 
01927          /* We have the file, now find the line within the file.              */
01928          /* If the message line number matches the file line number, we're    */
01929          /* done.  If the message line number is greater than the file line   */
01930          /* number and we're processing an INCLUDE file, then the user must   */
01931          /* have included the file more than once so rewind it and start over.*/
01932          /* If it's not an INCLUDE file, abort.                               */
01933 
01934 HAVE_FILE:
01935 
01936          if (file_stk[stk_idx].file_line != message_rec->fline) {
01937 
01938             if (file_stk[stk_idx].file_line > message_rec->fline  &&
01939                 stk_idx > 0) {
01940                rewind(file_stk[stk_idx].file_ptr);
01941                file_stk[stk_idx].file_line = 0;
01942             }
01943 
01944             while (file_stk[stk_idx].file_line != message_rec->fline) {
01945 
01946                if (fgets(source_line,
01947                          MAX_SRC_LINE_SIZE,
01948                          file_stk[stk_idx].file_ptr) != NULL) {
01949                   ++file_stk[stk_idx].file_line;
01950 
01951 # ifdef _DEBUG
01952                   if (dump_flags.stmt_dmp) {
01953                      fprintf(stderr, "%s", source_line);
01954                      ++dbg_global_line;
01955                   }
01956 # endif
01957 
01958                }
01959                else {
01960                   line_num = message_rec->uline;
01961                   sprintf(final_text, 
01962                          "hit EOF while trying to issue message %d at line %d.",
01963                          message_rec->msgno,
01964                          line_num);
01965                   msg_insert = final_text;
01966                   goto EMERGENCY_EXIT;
01967                }
01968             }
01969    
01970             fprintf(stderr, "\n%s", source_line);
01971          }
01972 
01973 
01974          /* If a character position was given in the record, output the "^".  */
01975          /* The algorithm is pretty stupid.  It should be changed to just     */
01976          /* blank the line from 0 to (message_rec->cpos - 1) but because it   */
01977          /* was originally written to blank to the NULL character, it would   */
01978          /* really annoy Testing to change it now because every test that has */
01979          /* a message with a carat would have to have a new base because the  */
01980          /* carat line would have fewer blanks in it.  So the algorithm       */
01981          /* is this:  blank out the carat line to the same length as the      */
01982          /* source line.  If the character position is beyond that (this      */
01983          /* should only happen if the user did something like forget to close */
01984          /* a character string), then continue blanking to the character      */
01985          /* position.                                                         */
01986      
01987          if (message_rec->cpos != 0) {
01988 
01989             for (i = 0;  source_line[i] != '\0';  ++i) {
01990                carat[i] = (source_line[i] == '\t') ? '\t' : ' ';
01991             }
01992 
01993             for ( ;  i < message_rec->cpos;  ++i) {
01994                carat[i] = ' ';
01995             }
01996 
01997             carat[i]                     = '\0';
01998             carat[message_rec->cpos - 1] = '^';
01999             fprintf(stderr, "%s\n", carat);
02000          }
02001 
02002          catgetmsg(message_catalog,
02003                    NL_SETD,
02004                    message_rec->msgno,
02005                    orig_text,
02006                    ORIG_MSG_SIZE);
02007 
02008          Cif_Msginsert(orig_text,
02009                        (struct Cif_generic *) message_rec,
02010                        expanded_text,
02011                        EXPANDED_MSG_SIZE);
02012             
02013          if (message_rec->cpos == 0) {
02014             sprintf(message_hdr, "%s, File = %s, Line = %d ",
02015                     message_rec->name,
02016                     GL_FILE_NAME_PTR(global_idx),
02017                     message_rec->fline);
02018          }
02019          else {
02020             sprintf(message_hdr, "%s, File = %s, Line = %d, Column = %d ",
02021                     message_rec->name,
02022                     GL_FILE_NAME_PTR(global_idx),
02023                     message_rec->fline,
02024                     message_rec->cpos);
02025          }
02026 
02027          catmsgfmt(command_name,
02028                    message_prefix,
02029                    message_rec->msgno,
02030                    msg_severity_name[message_rec->severity],
02031                    expanded_text,
02032                    final_text,
02033                    FINAL_MSG_SIZE,
02034                    message_hdr,
02035                    (char *) NULL);
02036 
02037          fputs(final_text, stderr);
02038 
02039 # ifdef _DEBUG
02040          if (dump_flags.stmt_dmp) {
02041             fprintf(stderr, "\n");
02042          }
02043 # endif
02044 
02045          ++message_rec;
02046 
02047       }  /* End Message record loop. */
02048 
02049    }  /* End Unitdir record loop. */
02050 
02051 
02052 # ifdef _DEBUG
02053 
02054 NO_MSGS_STMT_DUMP:
02055 
02056    if (dump_flags.stmt_dmp) {
02057    
02058 CHECK_GL_IDX_AGAIN:
02059 
02060       if (global_idx < global_line_tbl_idx) {
02061         
02062          while (dbg_global_line < GL_GLOBAL_LINE(global_idx + 1)) {
02063 
02064             if (fgets(source_line,
02065                        MAX_SRC_LINE_SIZE,
02066                        file_stk[stk_idx].file_ptr) != NULL) {
02067                ++dbg_global_line;
02068                fprintf(stderr, "%s", source_line);
02069             }
02070             else {
02071                line_num = dbg_global_line;
02072                msg_insert = "can not read source file.";
02073                goto EMERGENCY_EXIT;
02074             }
02075          }
02076 
02077          ++global_idx;
02078 
02079          for (search_idx = stk_idx - 1;  search_idx >=0;  --search_idx) {
02080       
02081             if (GL_CIF_FILE_ID(global_idx) == file_stk[search_idx].file_id) {
02082 
02083                while (stk_idx != search_idx) {
02084                   fclose(file_stk[stk_idx--].file_ptr);
02085                }
02086   
02087                goto CHECK_GL_IDX_AGAIN;
02088             }
02089          }
02090 
02091          ++stk_idx;
02092 
02093          if (stk_idx < FILE_STK_MAX) {
02094             file_stk[stk_idx].file_id = GL_CIF_FILE_ID(global_idx);
02095 
02096             for (i = 2;  i < filedir->nfiles;  ++i) {
02097 
02098                if (file_rec[i].fid == file_stk[stk_idx].file_id) {
02099                   break;
02100                }
02101             }
02102 
02103             if ((file_stk[stk_idx].file_ptr =
02104                     fopen(file_rec[i].name, "r")) != NULL) {
02105                file_stk[stk_idx].file_line = 0;
02106             }
02107             else {
02108                line_num = message_rec->uline;
02109                msg_insert = "can not open INCLUDE file.";
02110                goto EMERGENCY_EXIT;
02111             }
02112          }
02113          else {
02114             line_num = message_rec->uline;
02115             msg_insert = "file_stk size exceeded.";
02116             goto EMERGENCY_EXIT;
02117          }
02118 
02119          goto CHECK_GL_IDX_AGAIN;
02120       }
02121 
02122       while (feof(file_stk[0].file_ptr) == 0) {
02123 
02124          if (fgets(source_line,
02125                    MAX_SRC_LINE_SIZE,
02126                    file_stk[0].file_ptr) != NULL  && 
02127              feof(file_stk[0].file_ptr) == 0) {
02128             fprintf(stderr, "%s", source_line);
02129          }
02130       }
02131    }
02132 
02133 # endif
02134 
02135 
02136    fprintf(stderr, "\n");
02137 
02138 
02139 # ifdef _DEBUG
02140 
02141    if (num_msgs != 0) { 
02142       Cif_Close(fd, CIF_MEM_FREE);
02143    }
02144 
02145 # else
02146 
02147    Cif_Close(fd, CIF_MEM_FREE);
02148 
02149 # endif
02150 
02151 
02152    while (stk_idx >= 0) {
02153       fclose(file_stk[stk_idx--].file_ptr);
02154    }
02155 
02156 EXIT:
02157    
02158    /* Set c_i_f to NULL to indicate the messages have been output but DON'T   */
02159    /* close it or delete it yet because if the compilation is being           */
02160    /* terminated by an Internal or Limit error, we need to output a special   */
02161    /* Summary record yet.                                                     */
02162 
02163    c_i_f = NULL;
02164 
02165 
02166    fclose(cif_tmp_file);
02167    remove(cif_tmp_file_name);
02168 
02169    TRACE (Func_Exit, "print_buffered_messages", NULL);
02170 
02171    return;
02172 
02173 
02174 EMERGENCY_EXIT:
02175 
02176    if (c_i_f == cif_actual_file) {
02177       /* prevent closing the same file twice. Linux does not handle it */
02178       cif_actual_file = NULL;
02179    }
02180    fclose(c_i_f);
02181    c_i_f = NULL;
02182    remove(cif_name);
02183    remove(cif_tmp_file_name);
02184    Cif_Close(fd, CIF_MEM_FREE);
02185    PRINTMSG(line_num, 995, Internal, 0, msg_insert);
02186 
02187 } /*  print_buffered_messages */
02188 
02189 
02190 /******************************************************************************\
02191 |*                                                                            *|
02192 |* Description:                                                               *|
02193 |*      This is a compare routine for qsort to get the Message records        *|
02194 |*      sorted in global line number then column number order.                *|
02195 |*                                                                            *|
02196 |* Input parameters:                                                          *|
02197 |*      NONE                                                                  *|
02198 |*                                                                            *|
02199 |* Output parameters:                                                         *|
02200 |*      NONE                                                                  *|
02201 |*                                                                            *|
02202 |* Returns:                                                                   *|
02203 |*      NOTHING                                                               *|
02204 |*                                                                            *|
02205 \******************************************************************************/
02206 
02207 static int compare_message_recs(const void       *p1,
02208                                 const void       *p2)
02209 {
02210    register int result;
02211    register int order1;
02212    register int order2;
02213 
02214 
02215    TRACE (Func_Entry, "compare_message_recs", NULL);
02216 
02217    result = ((struct Cif_message *) p1)->uline -
02218             ((struct Cif_message *) p2)->uline; 
02219 
02220    if (result == 0) {
02221       result = ((struct Cif_message *) p1)->cpos -
02222                ((struct Cif_message *) p2)->cpos;
02223 
02224 
02225       /* If both the line number and column number are the same, use the      */
02226       /* relative order field if it is set to break the tie.  If it's not set,*/
02227       /* use the message number to break the tie to avoid different "same     */
02228       /* key" algorithms across platforms.  This presumes, of course, that    */
02229       /* there will (almost?) never be a case where the same message is       */
02230       /* issued for the same line and column.                                 */
02231       /* Careful!  The messages could come from different phases.             */
02232 
02233       if (result == 0) {
02234          order1 = ((struct Cif_message *) p1)->order;
02235          order2 = ((struct Cif_message *) p2)->order;
02236 
02237          if ( (order1 == order2)  ||  (order1 == 0)  ||  (order2 == 0) ) {
02238             result = ((struct Cif_message *) p1)->msgno -
02239                      ((struct Cif_message *) p2)->msgno;
02240          }
02241          else {
02242             result = ((struct Cif_message *) p1)->order -
02243                      ((struct Cif_message *) p2)->order;
02244          }
02245       }
02246    }
02247 
02248    TRACE (Func_Exit, "compare_message_recs", NULL);
02249 
02250    return (result);
02251 
02252 }  /* compare_message_recs */
02253 # if defined(_USE_FOLD_DOT_f)
02254 
02255 /******************************************************************************\
02256 |*                                                                            *|
02257 |* Description:                                                               *|
02258 |*      <description>                                                         *|
02259 |*                                                                            *|
02260 |* Input parameters:                                                          *|
02261 |*      NONE                                                                  *|
02262 |*                                                                            *|
02263 |* Output parameters:                                                         *|
02264 |*      NONE                                                                  *|
02265 |*                                                                            *|
02266 |* Returns:                                                                   *|
02267 |*      NOTHING                                                               *|
02268 |*                                                                            *|
02269 \******************************************************************************/
02270 
02271 void fold_f_abort_(int *oper)
02272 
02273 {
02274 
02275 
02276    TRACE (Func_Entry, "fold_f_abort_", NULL);
02277 
02278    PRINTMSG(stmt_start_line, 626, Internal, *oper,
02279             "supported operator or type", "FOLD_OPERATION");
02280 
02281    TRACE (Func_Exit, "fold_f_abort_", NULL);
02282 
02283    return;
02284 
02285 }  /* fold_f_abort_ */
02286 
02287 
02288 void fold_f_abort__(int *oper)
02289 
02290 {
02291   fold_f_abort_(oper);
02292 }
02293 
02294 # endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines