LTP GCOV extension - code coverage report
Current view: directory - fcode-utils/toke - errhandler.c
Test: Toke 1.0.2
Date: 2006-10-30 Instrumented lines: 135
Code covered: 96.3 % Executed lines: 130
Legend: not executed executed converted-only

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

Generated by: LTP GCOV extension version 1.5