LTP GCOV extension - code coverage report
Current view: directory - fcode-utils/toke - errhandler.c
Test: toke.info
Date: 2006-08-18 Instrumented lines: 133
Code covered: 96.2 % Executed lines: 128

       1                 : /*
       2                 :  *                     OpenBIOS - free your system!
       3                 :  *                         ( FCode tokenizer )
       4                 :  *
       5                 :  *  This program is part of a free implementation of the IEEE 1275-1994
       6                 :  *  Standard for Boot (Initialization Configuration) Firmware.
       7                 :  *
       8                 :  *  Copyright (C) 2001-2005 Stefan Reinauer, <stepan@openbios.org>
       9                 :  *
      10                 :  *  This program is free software; you can redistribute it and/or modify
      11                 :  *  it under the terms of the GNU General Public License as published by
      12                 :  *  the Free Software Foundation; version 2 of the License.
      13                 :  *
      14                 :  *  This program is distributed in the hope that it will be useful,
      15                 :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      16                 :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17                 :  *  GNU General Public License for more details.
      18                 :  *
      19                 :  *  You should have received a copy of the GNU General Public License
      20                 :  *  along with this program; if not, write to the Free Software
      21                 :  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
      22                 :  *
      23                 :  */
      24                 : 
      25                 : /* **************************************************************************
      26                 :  *
      27                 :  *      Error-Handler for Tokenizer
      28                 :  *
      29                 :  *      Controls printing of various classes of errors
      30                 :  *
      31                 :  *      (C) Copyright 2005 IBM Corporation.  All Rights Reserved.
      32                 :  *      Module Author:  David L. Paktor    dlpaktor@us.ibm.com
      33                 :  *
      34                 :  **************************************************************************** */
      35                 : 
      36                 : /* **************************************************************************
      37                 :  *
      38                 :  *      Functions Exported:
      39                 :  *          init_error_handler  Initialize the error-counts,
      40                 :  *                                  announce the file names.
      41                 :  *          tokenization_error  Handle an error of the given class,
      42                 :  *                                  print the given message in the 
      43                 :  *                                  standard format.
      44                 :  *          started_at          Supplemental message, giving a back-reference
      45                 :  *                                  to the "starting"  point of a compound
      46                 :  *                                  error, including last-colon identification.
      47                 :  *          just_started_at     Supplemental back-reference to "starting"  point
      48                 :  *                                  of compound error, but without last-colon
      49                 :  *                                  identification.
      50                 :  *          where_started       Supplemental message, giving a more terse back-
      51                 :  *                                  -reference to "start" of compound-error.
      52                 :  *          just_where_started Supplemental message, more terse back-reference,
      53                 :  *                                  without last-colon identification.
      54                 :  *          in_last_colon      Supplemental back-reference message,
      55                 :  *                                  identifying last Colon-definition.
      56                 :  *          safe_malloc         malloc with built-in failure test.
      57                 :  *          error_summary       Summarize final error-message status
      58                 :  *                                  before completing tokenization.
      59                 :  *
      60                 :  **************************************************************************** */
      61                 : 
      62                 : 
      63                 : /* **************************************************************************
      64                 :  *
      65                 :  *          We will define a set of bit-valued error-types and a
      66                 :  *          global bit-mask.  Each error-message will be associated
      67                 :  *          with one of the bit-valued error-types.  The bit-mask,
      68                 :  *          which will be set by a combination of defaults and user
      69                 :  *          inputs (mainly command-line arguments), will control
      70                 :  *          whether an error-message of any given type is printed.
      71                 :  *          
      72                 :  *          Another bit-mask variable will accumulate the error-
      73                 :  *          types that occur within any given run; at the end of
      74                 :  *          the run, it will be examined to determine if the run
      75                 :  *          failed, i.e., if the output should be suppressed.
      76                 :  *
      77                 :  **************************************************************************** */
      78                 : 
      79                 : /* **************************************************************************
      80                 :  *
      81                 :  *          Error-types fall into the following broad categories:
      82                 :  *              FATAL           Cause to immediately stop activity
      83                 :  *              TKERROR         Sufficient to make the run a failure,
      84                 :  *                                  but not to stop activity.
      85                 :  *              WARNING         Not necessarily an error, but something
      86                 :  *                                  to avoid.  E.g., it might rely on
      87                 :  *                                  assumptions that are not necessarily
      88                 :  *                                  what the user/programmer wants.  Or:
      89                 :  *                                  It's a deprecated feature, or one
      90                 :  *                                  that might be incompatible with
      91                 :  *                                  other standard tokenizers.
      92                 :  *              INFO            Nothing is changed in processing, but
      93                 :  *                                  an advisory is still in order.
      94                 :  *              MESSAGE         Message generated by the user.  (Complete;
      95                 :  *                                  new-line will be added by display routine.)
      96                 :  *              P_MESSAGE       Partial Message -- Instigated by user, but
      97                 :  *                                  pre-formatted and not complete.  New-line
      98                 :  *                                  will be added by follow-up routine.
      99                 :  *
     100                 :  **************************************************************************** */
     101                 : 
     102                 : #include <stdio.h>
     103                 : #include <stdarg.h>
     104                 : #include <stdlib.h>
     105                 : #include <string.h>
     106                 : #include <errno.h>
     107                 : 
     108                 : #include "types.h"
     109                 : #include "toke.h"
     110                 : #include "stream.h"
     111                 : #include "errhandler.h"
     112                 : #include "scanner.h"
     113                 : 
     114                 : /* **************************************************************************
     115                 :  *
     116                 :  *          Global Variables Imported
     117                 :  *              iname           Name of file currently being processed
     118                 :  *              lineno          Current line-number being processed
     119                 :  *              noerrors        "Ignore Errors" flag, set by "-i" switch
     120                 :  *              opc             FCode Output Buffer Position Counter
     121                 :  *              verbose         If true, enable Advisory Messages
     122                 :  *
     123                 :  **************************************************************************** */
     124                 : 
     125                 : /* **************************************************************************
     126                 :  *
     127                 :  *              Internal Static Variables
     128                 :  *          print_msg               Whether beginning of a message was printed;
     129                 :  *                                      therefore, whether to print the rest.
     130                 :  *          errs_to_print           Error Verbosity Mask.  Bits set correspond
     131                 :  *                                      to message-types that will be printed
     132                 :  *                                      May be altered by Command-Line switches.
     133                 :  *          err_types_found         Accumulated Error-types.  Bits
     134                 :  *                                      set correspond to error-types
     135                 :  *                                      that have occurred.
     136                 :  *          message_dest            Message Dest'n.  Usually ERRMSG_DESTINATION
     137                 :  *                                      (stdout) except when we need to switch.
     138                 :  *          err_count               Count of Error Messages
     139                 :  *          warn_count              Count of Warning Messages
     140                 :  *          info_count              Count of "Advisory" Messages
     141                 :  *          user_msg_count          Count of User-generated Messages
     142                 :  *          fatal_err_exit          Exit code to be used for "Fatal" error.
     143                 :  *                                       This is a special accommodation
     144                 :  *                                       for the  safe_malloc  routine.
     145                 :  *
     146                 :  **************************************************************************** */
     147                 : 
     148                 : static bool  print_msg ;
     149                 : static int errs_to_print = ( FATAL | TKERROR | WARNING | 
     150                 :                              MESSAGE | P_MESSAGE | FORCE_MSG ) ;
     151                 : static int err_types_found =  0 ;
     152                 : static int err_count       =  0 ;
     153                 : static int warn_count      =  0 ;
     154                 : static int info_count      =  0 ;
     155                 : static int user_msg_count  =  0 ;
     156                 : static int fatal_err_exit  = -1 ;
     157                 : static FILE *message_dest;     /*  Would like to init to  ERRMSG_DESTINATION
     158                 :                                 *      here, but the compiler complains...
     159                 :                                 */
     160                 : 
     161                 : /* **************************************************************************
     162                 :  *
     163                 :  *              Internal Static Constant Structure
     164                 :  *          err_category            Correlate each error-type code with its
     165                 :  *                                      Counter-variable and the printable
     166                 :  *                                      form of its name.
     167                 :  *          num_categories          Number of entries in the err_category table
     168                 :  *
     169                 :  **************************************************************************** */
     170                 : 
     171                 : typedef struct {
     172                 :     int  type_bit ;             /*  Error-type single-bit code        */
     173                 :     char *category_name ;       /*  Printable-name base               */
     174                 :     char *single ;              /*  Suffix to print singular of name  */
     175                 :     char *plural ;              /*  Suffix to print plural of name    */
     176                 :     int  *counter ;             /*  Associated Counter-variable       */
     177                 :     bool new_line ;             /*  Whether to print new-line at end  */
     178                 : } err_category ;
     179                 : 
     180                 : static const err_category  error_categories[] = {
     181                 :     /*  FATAL  must be the first entry in the table.   */
     182                 :     /*  No plural is needed; only one is allowed....   */
     183                 :     { FATAL,    "Fatal Error", "", "",     &err_count      , TRUE  },
     184                 : 
     185                 :     { TKERROR,    "Error"     , "", "s",    &err_count      , FALSE },
     186                 :     { WARNING,    "Warning"   , "", "s",    &warn_count     , FALSE },
     187                 :     { INFO,       "Advisor"   , "y", "ies", &info_count     , FALSE },
     188                 :     { MESSAGE ,   "Message"   , "", "s",    &user_msg_count , TRUE  },
     189                 :     { P_MESSAGE , "Message"   , "", "s",    &user_msg_count , FALSE }
     190                 : };
     191                 : 
     192                 : static const int num_categories =
     193                 :     ( sizeof(error_categories) / sizeof(err_category) );
     194                 : 
     195                 : 
     196                 : #ifdef NEEDS_STRUPR
     197                 : 
     198                 : /* **************************************************************************
     199                 :  *
     200                 :  *      Function name:  toup
     201                 :  *      Synopsis:       Support function for  strupper
     202                 :  *                      Converts one character
     203                 :  *
     204                 :  *      Inputs:
     205                 :  *         Parameters:
     206                 :  *             chr_ptr                 Pointer to the character
     207                 :  *
     208                 :  *      Outputs:
     209                 :  *         Returned Value:             None
     210                 :  *         Supplied Pointers:
     211                 :  *             The character pointed to is changed
     212                 :  *
     213                 :  *      Process Explanation:
     214                 :  *          Because this fills in a lack in the host system, we cannot
     215                 :  *              rely on the functions  islower  or  toupper , which are
     216                 :  *              usually built-in but might be similarly missing.
     217                 :  *
     218                 :  **************************************************************************** */
     219                 : 
     220                 : static void toup( char *chr_ptr)
     221           11222 : {
     222           11222 :     const unsigned char upcas_diff = ( 'a' - 'A' );
     223           11222 :     if ( ( *chr_ptr >= 'a' ) && ( *chr_ptr <= 'z' ) )
     224                 :     {
     225            9053 :         *chr_ptr -= upcas_diff ;
     226                 :     }
     227           11222 : }
     228                 : 
     229                 : /* **************************************************************************
     230                 :  *
     231                 :  *      Function name:  strupper
     232                 :  *      Synopsis:       Replacement for  strupr  on systems that don't 
     233                 :  *                      seem to have it.  A necessary hack.
     234                 :  *
     235                 :  *      Inputs:
     236                 :  *         Parameters:
     237                 :  *             strung              Pointer to the string to be changed
     238                 :  *
     239                 :  *      Outputs:
     240                 :  *         Returned Value:         Same pointer that was passed in
     241                 :  *         Supplied Pointers:
     242                 :  *             The string pointed to will be converted to upper case
     243                 :  *
     244                 :  *      Process Explanation:
     245                 :  *          Because it fills in a lack in the host system, this routine
     246                 :  *              does not rely on the functions  islower  or  toupper
     247                 :  *              which are usually built-in but might be missing.
     248                 :  *
     249                 :  **************************************************************************** */
     250                 : 
     251                 : char *strupper( char *strung)
     252            1477 : {
     253                 :     char *strindx;
     254           12699 :     for (strindx = strung; *strindx != 0; strindx++)
     255                 :     {
     256           11222 :         toup( strindx);
     257                 :     }
     258            1477 :     return strung;
     259                 : }
     260                 : 
     261                 : /* **************************************************************************
     262                 :  *
     263                 :  *     If  strupr  is missing, it's a good bet that so is  strlwr 
     264                 :  *
     265                 :  **************************************************************************** */
     266                 : 
     267                 : /* **************************************************************************
     268                 :  *
     269                 :  *      Function name:  tolow
     270                 :  *      Synopsis:       Support function for  strlower
     271                 :  *                      Converts one character
     272                 :  *
     273                 :  *      Inputs:
     274                 :  *         Parameters:
     275                 :  *             chr_ptr                 Pointer to the character
     276                 :  *
     277                 :  *      Outputs:
     278                 :  *         Returned Value:             None
     279                 :  *         Supplied Pointers:
     280                 :  *             The character pointed to is changed
     281                 :  *
     282                 :  *      Process Explanation:
     283                 :  *          Because this fills in a lack in the host system, we cannot
     284                 :  *              rely on the functions  isupper  or  tolower , which are
     285                 :  *              usually built-in but might be similarly missing.
     286                 :  *
     287                 :  **************************************************************************** */
     288                 : 
     289                 : static void tolow( char *chr_ptr)
     290             178 : {
     291             178 :     const unsigned char lowcas_diff = ( 'A' - 'a' );
     292             178 :     if ( ( *chr_ptr >= 'A' ) && ( *chr_ptr <= 'Z' ) )
     293                 :     {
     294              38 :         *chr_ptr -= lowcas_diff ;
     295                 :     }
     296             178 : }
     297                 : 
     298                 : /* **************************************************************************
     299                 :  *
     300                 :  *      Function name:  strlower
     301                 :  *      Synopsis:       Replacement for  strlwr  on systems that don't 
     302                 :  *                      seem to have it.  A necessary hack.
     303                 :  *
     304                 :  *      Inputs:
     305                 :  *         Parameters:
     306                 :  *             strung              Pointer to the string to be changed
     307                 :  *
     308                 :  *      Outputs:
     309                 :  *         Returned Value:         Same pointer that was passed in
     310                 :  *         Supplied Pointers:
     311                 :  *             The string pointed to will be converted to lower case
     312                 :  *
     313                 :  *      Process Explanation:
     314                 :  *          Because it fills in a lack in the host system, this routine
     315                 :  *              does not rely on the functions  isupper  or  tolower
     316                 :  *              which are usually built-in but might be missing.
     317                 :  *
     318                 :  **************************************************************************** */
     319                 : 
     320                 : char *strlower( char *strung)
     321              15 : {
     322                 :     char *strindx;
     323             193 :     for (strindx = strung; *strindx != 0; strindx++)
     324                 :     {
     325             178 :         tolow( strindx);
     326                 :     }
     327              15 :     return strung;
     328                 : }
     329                 : 
     330                 : 
     331                 : #endif  /*   NEEDS_STRUPR   */
     332                 :  
     333                 : /* **************************************************************************
     334                 :  *
     335                 :  *      Function name:  init_error_handler
     336                 :  *      Synopsis:       Initialize the error-handler before starting a
     337                 :  *                          new tokenization; both the aspects that will
     338                 :  *                          persist across the entire run and those that
     339                 :  *                          need to be reset, such as error-counts.
     340                 :  *
     341                 :  *      Inputs:
     342                 :  *         Parameters:                 NONE
     343                 :  *         Global Variables: 
     344                 :  *              verbose                Set by "-v" switch
     345                 :  *         Macro:
     346                 :  *             ERRMSG_DESTINATION      Error message destination;
     347                 :  *                                         (Set by development-time switch)
     348                 :  *             FFLUSH_STDOUT           Flush STDOUT if err-msg-dest is STDERR
     349                 :  *
     350                 :  *      Outputs:
     351                 :  *         Returned Value:             NONE
     352                 :  *         Global Variables:
     353                 :  *             errs_to_print           Add the INFO bit if verbose is set
     354                 :  *         Local Static Variables:
     355                 :  *             message_dest            Point it at ERRMSG_DESTINATION (stderr)
     356                 :  *           Reset the following to zero:
     357                 :  *             err_types_found         Accumulated Error-types.
     358                 :  *             err_count               Count of Error Messages
     359                 :  *             warn_count              Count of Warning Messages
     360                 :  *             info_count              Count of "Advisory" Messages
     361                 :  *             user_msg_count          Count of User-generated Messages
     362                 :  *         Other Exotic Effects:
     363                 :  *             Flush stdout if Error message destination is not stdout, to
     364                 :  *                 avoid collisions with stderr once Error Messaging begins.
     365                 :  *
     366                 :  *      Extraneous Remarks:
     367                 :  *          This needs to be done before attempting to read the input file,
     368                 :  *              so that any Messages that occur there can be properly counted.
     369                 :  *
     370                 :  **************************************************************************** */
     371                 : 
     372                 : void init_error_handler( void)
     373             171 : {
     374             171 :     message_dest  =  ERRMSG_DESTINATION;
     375             171 :     if ( verbose )  errs_to_print |= INFO ;
     376             171 :     err_types_found = 0 ;
     377             171 :     err_count = 0 ;
     378             171 :     warn_count = 0 ;
     379             171 :     info_count = 0 ;
     380             171 :     user_msg_count = 0 ;
     381             171 :     FFLUSH_STDOUT
     382             171 : }
     383                 : 
     384                 : /* **************************************************************************
     385                 :  *
     386                 :  *      Function name:    tokenization_error
     387                 :  *      Synopsis:         Handle an error of the given class,
     388                 :  *                            print the given message in the standard format.
     389                 :  *      
     390                 :  *      Inputs:
     391                 :  *         Parameters:
     392                 :  *             err_type       int        One of the bit-valued error-types
     393                 :  *             The remaining parameters are a format string and corresponding
     394                 :  *                 data objects such as would be sent to  printf() 
     395                 :  *         Global Variables:
     396                 :  *             errs_to_print        Error Verbosity Mask.
     397                 :  *             iname                Name of file currently being processed
     398                 :  *             lineno               Current line-number being processed
     399                 :  *             fatal_err_exit       Exit code for "Fatal" error, if applicable.
     400                 :  *         Macro:
     401                 :  *             ERRMSG_DESTINATION        Error message destination;
     402                 :  *                                           (Development-time switch)
     403                 :  *         Note:  Whether this routine will or will not supply a new-line
     404                 :  *             at the end of the printout depends on the category of the
     405                 :  *             message.  The new-line is included for a FATAL or a User-
     406                 :  *             Generated Message, and excluded for the rest.  For those,
     407                 :  *             the calling routine must be responsible for including a
     408                 :  *             new-line at the end of the format string or for otherwise
     409                 :  *             finishing the line, as by calling started_at()
     410                 :  *
     411                 :  *      Outputs:
     412                 :  *         Returned Value:                 NONE
     413                 :  *         Local Static Variables:
     414                 :  *             err_types_found             Accumulated Error-types.
     415                 :  *             print_msg                   Whether this message was printed;
     416                 :  *                                             may be used by started_at()
     417                 :  *                    One of the following Category Counters
     418                 :  *                         will be incremented, as applicable:
     419                 :  *             err_count
     420                 :  *             warn_count
     421                 :  *             info_count 
     422                 :  *             user_msg_count
     423                 :  *         Printout:    Directed to  stdout or stderr 
     424                 :  *                          (see definition of ERRMSG_DESTINATION)
     425                 :  *
     426                 :  *      Error Detection:
     427                 :  *              Err_type not in list
     428                 :  *                      Print special message; treat cause as an Error.
     429                 :  *                      Force printout.
     430                 :  *
     431                 :  *      Process Explanation:
     432                 :  *          Accumulated the Error-type into  err_types_found 
     433                 :  *          Identify the Error-Category:
     434                 :  *              Check the Error-Type against the bit-code.
     435                 :  *                  The Error-type may have more than one bit set,
     436                 :  *                  but if it matches the Category bit-code, it's it.
     437                 :  *              If it doesn't match any Error-Category bit-code, print
     438                 :  *                  a special message and treat it as an ERROR code.
     439                 :  *          Check the Error-Type against the Error Verbosity Mask;
     440                 :  *          If it has a bit set, print the Error-Category, together
     441                 :  *                  with the source-file name and line number, and
     442                 :  *                  the rest of the message as supplied.
     443                 :  *              The table that translates the Error-type into a printable
     444                 :  *                  Error-Category string also identifies the applicable
     445                 :  *                  Category Counter; increment it.
     446                 :  *          Of course, there's no return from a FATAL error; it exits.
     447                 :  *
     448                 :  **************************************************************************** */
     449                 : 
     450                 : void tokenization_error( int err_type, char* msg, ... )
     451            3959 : {
     452                 :     int indx ;
     453                 : 
     454                 :     /*  Initial settings:  treat as an Error.  */
     455            3959 :     char *catgy_name = "Error";
     456            3959 :     char *catgy_suffx = "";
     457            3959 :     int *catgy_counter = &err_count;
     458            3959 :     bool print_new_line = FALSE;
     459                 : 
     460                 :     /*  Accumulated the Error-type into  err_types_found  */
     461            3959 :     err_types_found |= err_type;
     462                 : 
     463                 :     /*  Identify the Error-Category.  */
     464           14234 :     for ( indx = 0 ; indx < num_categories ; indx ++ )
     465                 :     {
     466           14234 :         if ( ( error_categories[indx].type_bit & err_type ) != 0 )
     467                 :         {
     468            3959 :             catgy_name = error_categories[indx].category_name;
     469            3959 :             catgy_suffx = error_categories[indx].single;
     470            3959 :             catgy_counter = error_categories[indx].counter;
     471            3959 :             print_new_line = error_categories[indx].new_line;
     472            3959 :             break;
     473                 :         }
     474                 :     }
     475                 : 
     476                 :     /*  Special message if  err_type  not in list; treat as an Error.  */
     477            3959 :     if ( catgy_name == NULL )
     478                 :     {
     479               0 :          fprintf(ERRMSG_DESTINATION,
     480                 :               "Program error: Unknown Error-Type, 0x%08x.  "
     481                 :               "  Will treat as Error.\n", err_type) ;
     482               0 :          err_types_found |= TKERROR;
     483               0 :          print_msg = TRUE ;
     484                 :     } else {
     485                 :          /*  Check the Error-Type against the Error Verbosity Mask  */
     486            3959 :          print_msg = BOOLVAL( ( errs_to_print & err_type ) != 0 );
     487                 :     }
     488                 : 
     489            3959 :     if ( print_msg )
     490                 :     {
     491                 :         va_list argp;
     492                 : 
     493            3933 :         if ( iname != NULL )
     494                 :         {
     495            3889 :             fprintf(ERRMSG_DESTINATION, "%s%s:  File %s, Line %d.  ",
     496                 :                  catgy_name, catgy_suffx, iname, lineno);
     497                 :         }else{
     498                 :             /*  Don't print iname or lineno if no file opened.  */
     499              44 :             fprintf(ERRMSG_DESTINATION, "%s%s:  ",
     500                 :                  catgy_name, catgy_suffx);
     501                 :         }
     502                 : 
     503            3933 :         va_start(argp, msg);
     504            3933 :         vfprintf(ERRMSG_DESTINATION, msg, argp);
     505            3933 :         va_end(argp);
     506            3933 :         if ( print_new_line ) fprintf(ERRMSG_DESTINATION, "\n");
     507                 : 
     508                 :         /*   Increment the category-counter.  */
     509            3933 :         *catgy_counter += 1;
     510                 :     }
     511            3959 :     if ( err_type == FATAL )
     512                 :     {
     513               1 :         fprintf(ERRMSG_DESTINATION, "Tokenization terminating.\n");
     514               1 :         error_summary();
     515               1 :         exit ( fatal_err_exit );
     516                 :     }
     517            3958 : }
     518                 : 
     519                 : /* **************************************************************************
     520                 :  *
     521                 :  *      Function name:  print_where_started
     522                 :  *      Synopsis:       Supplemental message, following a tokenization_error,
     523                 :  *                          giving a back-reference to the "start" point of
     524                 :  *                          the compound-error being reported.
     525                 :  *                      This is a retro-fit; it does the heavy lifting for
     526                 :  *                          the routines  started_at() ,  just_started_at() , 
     527                 :  *                           where_started() ,  just_where_started() and
     528                 :  *                           in_last_colon() .
     529                 :  *
     530                 :  *      Inputs:
     531                 :  *         Parameters:
     532                 :  *             show_started         Whether to print a phrase about "started"
     533                 :  *             show_that_st         Whether to print "that started" as opposed
     534                 :  *                                      to " , which started"
     535                 :  *             saved_ifile          File-name saved for "back-reference"
     536                 :  *             saved_lineno         Line-number saved for "back-reference"
     537                 :  *             may_show_incolon     Whether to allow a call to  in_last_colon()
     538                 :  *                                      Needed to prevent infinite recursion...
     539                 :  *         Global Variables:        
     540                 :  *             iname                Name of file currently being processed
     541                 :  *             lineno               Current line-number being processed
     542                 :  *         Local Static Variables:
     543                 :  *             print_msg            Whether the beginning part of the message
     544                 :  *                                      was printed by tokenization_error()
     545                 :  *             message_dest         Message Destination. Is ERRMSG_DESTINATION
     546                 :  *                                      (stdout) usually, except sometimes...
     547                 :  *
     548                 :  *      Outputs:
     549                 :  *         Returned Value:          None
     550                 :  *         Printout:
     551                 :  *             The remainder of a message:  the location of a back-reference.
     552                 :  *                 The phrase "that started" is switchable.  This routine
     553                 :  *                 will supply the leading space and a new-line; the routines
     554                 :  *                 that call this can be used to finish the line.
     555                 :  *
     556                 :  *      Process Explanation:
     557                 :  *          This routine is called immediately after tokenization_error()
     558                 :  *              If tokenization_error() didn't print, neither will we.
     559                 :  *              The residual state of  print_msg  will tell us that.
     560                 :  *          If the preceding message ended with something general about a
     561                 :  *              "Colon Definition" or "Device-Node" or the like, we want
     562                 :  *              the message to read:  "that started on line ... [in file ...]"
     563                 :  *          If the end of the preceding message was something more specific,
     564                 :  *              we just want the message to read:  "on line ... [in file ...]"
     565                 :  *          If the saved input file name doesn't match our current input
     566                 :  *              file name, we will print it and the saved line-number.
     567                 :  *          If the file name hasn't changed, we will print only the saved
     568                 :  *              line-number.
     569                 :  *          If neither is changed, there's no point in printing any of the
     570                 :  *              above-mentioned text.    
     571                 :  *          If a Colon-definition is in progress, show its name and the
     572                 :  *              line on which it started.  Protect against infinite loop!
     573                 :  *          End the line.
     574                 :  *
     575                 :  *      Extraneous Remarks:
     576                 :  *          This is a retrofit.  Earlier, it was just  started_at() .  Later,
     577                 :  *              I generated more specific messages, and needed a way to leave
     578                 :  *              out the "that started".  I could, theoretically, have added
     579                 :  *              the extra parameter to  started_at() , but by now there are
     580                 :  *              so many of calls to it that I'd rather leave them as is, and
     581                 :  *              just change the name of the routine in the few places that
     582                 :  *              need the terser form of the message.
     583                 :  *
     584                 :  **************************************************************************** */
     585                 : 
     586                 : static void print_where_started( bool show_started,
     587                 :                                    bool show_that_st,
     588                 :                                    char * saved_ifile,
     589                 :                                        unsigned int saved_lineno,
     590                 :                                            bool may_show_incolon)
     591            1033 : {
     592            1033 :     if ( print_msg )
     593                 :     {
     594                 :         bool fil_is_diff;
     595                 :         bool lin_is_diff;
     596                 : 
     597                 :         /*  File names are case-sensitive  */
     598            1033 :         fil_is_diff = BOOLVAL(strcmp(saved_ifile, iname) != 0 );
     599            1033 :         lin_is_diff = BOOLVAL(saved_lineno != lineno );
     600            1033 :         if ( fil_is_diff || lin_is_diff )
     601                 :         {
     602            1010 :             if ( show_started )
     603                 :             {
     604             624 :                 if ( show_that_st )
     605                 :                 {
     606             444 :                     fprintf(message_dest, " that");
     607                 :                 }else{
     608             180 :                     fprintf(message_dest, " , which");
     609                 :                 }
     610             624 :                 fprintf(message_dest, " started");
     611                 :             }
     612            1010 :             fprintf(message_dest, " on line %d", saved_lineno);
     613            1010 :             if ( fil_is_diff )
     614                 :             {
     615              20 :                 fprintf(message_dest, " of file %s", saved_ifile);
     616                 :             }
     617                 :         }
     618                 : 
     619            1033 :         if ( may_show_incolon )
     620                 :         {
     621             538 :             in_last_colon();
     622                 :         }else{
     623             495 :             fprintf(message_dest, "\n");
     624                 :         }
     625                 :     }
     626            1033 : }
     627                 : 
     628                 : /* **************************************************************************
     629                 :  *
     630                 :  *      Function name:  started_at
     631                 :  *      Synopsis:       Supplemental back-reference message,
     632                 :  *                          with the "that started"  phrase,
     633                 :  *                          and with last-colon identification.
     634                 :  *
     635                 :  *      Inputs:
     636                 :  *         Parameters:
     637                 :  *             saved_ifile          File-name saved for "back-reference"
     638                 :  *             saved_lineno         Line-number saved for "back-reference"
     639                 :  *
     640                 :  *      Outputs:
     641                 :  *         Returned Value:          None
     642                 :  *         Global Variables:
     643                 :  *         Printout:
     644                 :  *             The "...started at..." remainder of a message, giving a back-
     645                 :  *                 -reference to the  "start" point supplied in the params,
     646                 :  *                 and the start of the current Colon-definition if one is
     647                 :  *                 in effect.
     648                 :  *             Will supply a new-line and can be used to finish the line.
     649                 :  *
     650                 :  **************************************************************************** */
     651                 : 
     652                 : void started_at( char * saved_ifile, unsigned int saved_lineno)
     653             289 : {
     654             289 :     print_where_started( TRUE, TRUE, saved_ifile, saved_lineno, TRUE);
     655             289 : }
     656                 : 
     657                 : 
     658                 : /* **************************************************************************
     659                 :  *
     660                 :  *      Function name:  print_started_at
     661                 :  *      Synopsis:       Same as started_at() except output will be directed
     662                 :  *                          to  stdout  instead of to ERRMSG_DESTINATION
     663                 :  *
     664                 :  *      Extraneous Remarks:
     665                 :  *          A retrofit.  Can you tell?
     666                 :  *
     667                 :  **************************************************************************** */
     668                 :  
     669                 : void print_started_at( char * saved_ifile, unsigned int saved_lineno)
     670              83 : {
     671              83 :     message_dest = stdout;
     672              83 :         started_at( saved_ifile, saved_lineno);
     673              83 :     message_dest = ERRMSG_DESTINATION;
     674              83 : }
     675                 : 
     676                 : 
     677                 : /* **************************************************************************
     678                 :  *
     679                 :  *      Function name:  just_started_at
     680                 :  *      Synopsis:       Supplemental back-reference message,
     681                 :  *                          with the "that started"  phrase,
     682                 :  *                          but without last-colon identification.
     683                 :  *
     684                 :  *      Inputs:
     685                 :  *         Parameters:
     686                 :  *             saved_ifile          File-name saved for "back-reference"
     687                 :  *             saved_lineno         Line-number saved for "back-reference"
     688                 :  *
     689                 :  *      Outputs:
     690                 :  *         Returned Value:          None
     691                 :  *         Global Variables:
     692                 :  *         Printout:
     693                 :  *             The "...started at..." remainder of a message, giving a back-
     694                 :  *                 -reference to the  "start" point supplied in the params,
     695                 :  *                 and no more.
     696                 :  *             Will supply a new-line and can be used to finish the line.
     697                 :  *
     698                 :  **************************************************************************** */
     699                 : 
     700                 : void just_started_at( char * saved_ifile, unsigned int saved_lineno)
     701             172 : {
     702             172 :     print_where_started( TRUE, TRUE, saved_ifile, saved_lineno, FALSE);
     703             172 : }
     704                 : 
     705                 : /* **************************************************************************
     706                 :  *
     707                 :  *      Function name:  where_started
     708                 :  *      Synopsis:       Supplemental back-reference message,
     709                 :  *                          without the "that started"  phrase,
     710                 :  *                          but with last-colon identification.
     711                 :  *
     712                 :  *      Inputs:
     713                 :  *         Parameters:
     714                 :  *             saved_ifile          File-name saved for "back-reference"
     715                 :  *             saved_lineno         Line-number saved for "back-reference"
     716                 :  *
     717                 :  *      Outputs:
     718                 :  *         Returned Value:          None
     719                 :  *         Global Variables:
     720                 :  *         Printout:
     721                 :  *             The remainder of a message, giving a back-reference to the
     722                 :  *                 "start" point supplied in the parameters, and the start
     723                 :  *                 of the current Colon-definition if one is in effect.
     724                 :  *             Will supply a new-line and can be used to finish the line.
     725                 :  *
     726                 :  **************************************************************************** */
     727                 : 
     728                 : void where_started( char * saved_ifile, unsigned int saved_lineno)
     729             249 : {
     730             249 :     print_where_started( FALSE, FALSE, saved_ifile, saved_lineno, TRUE);
     731             249 : }
     732                 : 
     733                 : /* **************************************************************************
     734                 :  *
     735                 :  *      Function name:  just_where_started
     736                 :  *      Synopsis:       Supplemental back-reference message,
     737                 :  *                          without the "that started"  phrase,
     738                 :  *                          and without last-colon identification.
     739                 :  *
     740                 :  *      Inputs:
     741                 :  *         Parameters:
     742                 :  *             saved_ifile          File-name saved for "back-reference"
     743                 :  *             saved_lineno         Line-number saved for "back-reference"
     744                 :  *
     745                 :  *      Outputs:
     746                 :  *         Returned Value:          None
     747                 :  *         Global Variables:
     748                 :  *         Printout:
     749                 :  *             The remainder of a message, giving a back-reference to the
     750                 :  *                 "start" point supplied in the parameters, and no more.
     751                 :  *             Will supply a new-line and can be used to finish the line.
     752                 :  *
     753                 :  **************************************************************************** */
     754                 : 
     755                 : void just_where_started( char * saved_ifile, unsigned int saved_lineno)
     756             141 : {
     757             141 :     print_where_started( FALSE, FALSE, saved_ifile, saved_lineno, FALSE);
     758             141 : }
     759                 : 
     760                 : /* **************************************************************************
     761                 :  *
     762                 :  *      Function name:  in_last_colon
     763                 :  *      Synopsis:       Supplemental back-reference message, identifying
     764                 :  *                          last Colon-definition if one is in effect.
     765                 :  *                      Can be used to finish the line in either case.
     766                 :  *
     767                 :  *      Inputs:
     768                 :  *         Parameters:                   NONE
     769                 :  *         Global Variables:
     770                 :  *             incolon                   TRUE if Colon-definition is in progress
     771                 :  *             last_colon_defname        Name of last colon-definition
     772                 :  *             last_colon_filename       File where last colon-def'n made
     773                 :  *             last_colon_lineno         Line number of last colon-def'n
     774                 :  *         Local Static Variables:
     775                 :  *             print_msg            Whether the beginning part of the message
     776                 :  *                                      was printed by tokenization_error()
     777                 :  *             message_dest         Message Destination. Is ERRMSG_DESTINATION
     778                 :  *                                      (stdout) usually, except sometimes...
     779                 :  *
     780                 :  *      Outputs:
     781                 :  *         Returned Value:                  NONE
     782                 :  *         Printout:
     783                 :  *             Remainder of a message:
     784                 :  *                "in definition of  ... , which started ..."
     785                 :  *
     786                 :  *      Process Explanation:
     787                 :  *          Because this routine does some of its own printing, it needs
     788                 :  *              to check the residual state of  print_msg  first.
     789                 :  *          The calling routine does not need to test   incolon ; it can
     790                 :  *              call this to end the line in either case.
     791                 :  *
     792                 :  **************************************************************************** */
     793                 : 
     794                 : void in_last_colon( void )
     795             616 : {
     796             616 :     if ( print_msg )
     797                 :     {
     798             616 :         if ( incolon )
     799                 :         {
     800             182 :             fprintf( message_dest, " in definition of  %s ",
     801                 :                 strupr( last_colon_defname) );
     802             182 :             print_where_started( TRUE, FALSE,
     803                 :                 last_colon_filename, last_colon_lineno, FALSE);
     804                 :         }else{
     805             434 :             fprintf(message_dest, "\n");
     806                 :         }
     807                 :     }
     808             616 : }
     809                 : 
     810                 : 
     811                 : /* **************************************************************************
     812                 :  *
     813                 :  *      Function name:  safe_malloc
     814                 :  *      Synopsis:       malloc with built-in failure test.
     815                 :  *      
     816                 :  *      Inputs:
     817                 :  *         Parameters:
     818                 :  *             size       size_t     Size of memory-chunk to allocate
     819                 :  *             phrase     char *     Phrase to print after "... while "
     820                 :  *                                       in case of failure.
     821                 :  *
     822                 :  *      Outputs:
     823                 :  *         Returned Value:           Pointer to allocated memory
     824                 :  *         Global Variables:
     825                 :  *             fatal_err_exit       On memory allocation failure, change
     826                 :  *                                       to a special system-defined value
     827                 :  *
     828                 :  *      Error Detection:
     829                 :  *          On memory allocation failure, declare a FATAL error.  Set up
     830                 :  *              for a special system-defined EXIT value that indicates
     831                 :  *              insufficient memory.
     832                 :  *
     833                 :  *      Process Explanation:
     834                 :  *          It is the responsibility of the calling routine to be sure
     835                 :  *              the "phrase" is unique within the program.  It is intended
     836                 :  *              as a debugging aid, to help localize the point of failure.
     837                 :  *
     838                 :  **************************************************************************** */
     839                 : 
     840                 : _PTR safe_malloc( size_t size, char *phrase)
     841           16897 : {
     842                 :     _PTR retval ;
     843           16897 :     retval = malloc (size);
     844           16897 :     if ( !retval )
     845                 :     {
     846               0 :         fatal_err_exit = -ENOMEM ;
     847               0 :         tokenization_error( FATAL, "Out of memory while %s.", phrase);
     848                 :     }
     849           16897 :     return ( retval );
     850                 : }
     851                 : 
     852                 : /* **************************************************************************
     853                 :  *
     854                 :  *      Function name:         error_summary
     855                 :  *      Synopsis:              Summarize final error-message status
     856                 :  *                                 before completing tokenization.
     857                 :  *                             Indicate if OK to produce output.
     858                 :  *      
     859                 :  *      Inputs:
     860                 :  *         Parameters:                   NONE
     861                 :  *         Global Variables:        
     862                 :  *             noerrors             "Ignore Errors" flag, set by "-i" switch
     863                 :  *             err_types_found      Accumulated Error-types.
     864                 :  *             error_categories     Table of Error-types, Message-Counters
     865                 :  *                                      and their printable names.
     866                 :  *             opc                  FCode Output Buffer Position Counter
     867                 :  *                                      (zero means there was no output).
     868                 :  *
     869                 :  *      Outputs:
     870                 :  *         Returned Value:          True = OK to produce output (But caller
     871                 :  *                                      must still verify non-zero opc)
     872                 :  *         Printout:
     873                 :  *             Various messages.
     874                 :  *
     875                 :  *      Process Explanation:
     876                 :  *          The first entry in the error_categories table is FATAL    
     877                 :  *              We won't need to print a tally of that...
     878                 :  *      
     879                 :  **************************************************************************** */
     880                 : 
     881                 : bool error_summary( void )
     882             165 : {
     883                 :     /*  Bit-mask of error-types that require suppressing output   */
     884                 :     static const int suppress_mask = ( FATAL | TKERROR );
     885             165 :     bool retval = TRUE;
     886             165 :     bool suppressing = FALSE;
     887                 : 
     888                 :     /*  There's no escaping a FATAL error   */
     889             165 :     if ( ( err_types_found & FATAL ) != 0 )
     890                 :     {
     891                 :         /*   FATAL error.  Don't even bother with the tally.   */
     892               1 :         suppressing = TRUE;
     893                 :     } else {
     894                 : 
     895             164 :         if ( opc == 0 )
     896                 :         {
     897              22 :             printf ( "Nothing Tokenized");
     898                 :         }else{
     899             142 :             printf ( "Tokenization Completed");
     900                 :         }
     901                 : 
     902             164 :         if ( err_types_found != 0 )
     903                 :         {
     904                 :             int indx;
     905             164 :             bool tally_started = FALSE ;
     906             164 :             printf (". ");
     907                 :             /*
     908                 :              *  Print a tally of the error-types;
     909                 :              *  handle plurals and punctuation appropriately.
     910                 :              */
     911                 :             /*  Start at indx = 1 to skip examining FATALs   */
     912             984 :             for ( indx = 1; indx < num_categories ; indx ++ )
     913                 :             {
     914             820 :                 if ( *(error_categories[indx].counter) > 0 )
     915                 :                 {
     916             413 :                     printf ("%s %d %s%s",
     917                 :                         tally_started ? "," : "" ,
     918                 :                             *(error_categories[indx].counter),
     919                 :                                 error_categories[indx].category_name,
     920                 :                                     *(error_categories[indx].counter) > 1 ?
     921                 :                                          error_categories[indx].plural :
     922                 :                                              error_categories[indx].single );
     923                 :                     /*  Zero out the counter, to prevent displaying the
     924                 :                      *      number of Messages twice, since it's shared
     925                 :                      *      by the "Messages" and "P_Messages" categories.
     926                 :                      */
     927             413 :                     *(error_categories[indx].counter) = 0;
     928             413 :                     tally_started = TRUE;
     929                 :                 }
     930                 :             }
     931                 :         }
     932             164 :         printf (".\n");
     933                 : 
     934             164 :         if ( ( err_types_found & suppress_mask ) != 0 )
     935                 :         {    /*  Errors found.  Not  OK to produce output    */
     936                 :              /*  Unless "Ignore Errors" flag set...          */
     937              82 :             if ( INVERSE(noerrors) )
     938                 :             {
     939              17 :                 suppressing = TRUE;
     940                 :             }else{
     941              65 :                 if ( opc > 0 )
     942                 :                 {
     943              64 :                     printf ("Error-detection over-ridden; "
     944                 :                                 "producing binary output.\n");
     945                 :                 }
     946                 :             }
     947                 :         }
     948                 :     }
     949             165 :     if ( suppressing )
     950                 :     {
     951              18 :         retval = FALSE ;
     952              18 :         printf ("Suppressing binary output.\n");
     953                 :     }
     954             165 :     return ( retval );
     955                 : }
     956                 : 

Generated by: LTP GCOV extension version 1.5