Home | History | Annotate | Download | only in Common
      1 /** @file
      2 EFI tools utility functions to display warning, error, and informational messages
      3 
      4 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 --*/
     14 
     15 #include <stdio.h>
     16 #include <string.h>
     17 #include <ctype.h>
     18 #include <stdarg.h>
     19 #include <time.h>
     20 
     21 #include "EfiUtilityMsgs.h"
     22 
     23 //
     24 // Declare module globals for keeping track of the the utility's
     25 // name and other settings.
     26 //
     27 STATIC STATUS mStatus                 = STATUS_SUCCESS;
     28 STATIC CHAR8  mUtilityName[50]        = { 0 };
     29 STATIC UINT64 mPrintLogLevel          = INFO_LOG_LEVEL;
     30 STATIC CHAR8  *mSourceFileName        = NULL;
     31 STATIC UINT32 mSourceFileLineNum      = 0;
     32 STATIC UINT32 mErrorCount             = 0;
     33 STATIC UINT32 mWarningCount           = 0;
     34 STATIC UINT32 mMaxErrors              = 0;
     35 STATIC UINT32 mMaxWarnings            = 0;
     36 STATIC UINT32 mMaxWarningsPlusErrors  = 0;
     37 STATIC INT8   mPrintLimitsSet         = 0;
     38 
     39 STATIC
     40 VOID
     41 PrintLimitExceeded (
     42   VOID
     43   );
     44 
     45 VOID
     46 Error (
     47   CHAR8   *FileName,
     48   UINT32  LineNumber,
     49   UINT32  MessageCode,
     50   CHAR8   *Text,
     51   CHAR8   *MsgFmt,
     52   ...
     53   )
     54 /*++
     55 
     56 Routine Description:
     57   Prints an error message.
     58 
     59 Arguments:
     60   All arguments are optional, though the printed message may be useless if
     61   at least something valid is not specified.
     62 
     63   FileName - name of the file or application. If not specified, then the
     64              utilty name (as set by the utility calling SetUtilityName()
     65              earlier) is used. Otherwise "Unknown utility" is used.
     66 
     67   LineNumber - the line number of error, typically used by parsers. If the
     68                utility is not a parser, then 0 should be specified. Otherwise
     69                the FileName and LineNumber info can be used to cause
     70                MS Visual Studio to jump to the error.
     71 
     72   MessageCode - an application-specific error code that can be referenced in
     73               other documentation.
     74 
     75   Text        - the text in question, typically used by parsers.
     76 
     77   MsgFmt - the format string for the error message. Can contain formatting
     78            controls for use with the varargs.
     79 
     80 Returns:
     81   None.
     82 
     83 Notes:
     84   We print the following (similar to the Warn() and Debug()
     85   W
     86   Typical error/warning message format:
     87 
     88   bin\VfrCompile.cpp(330) : error C2660: 'AddVfrDataStructField' : function does not take 2 parameters
     89 
     90   BUGBUG -- these three utility functions are almost identical, and
     91   should be modified to share code.
     92 
     93   Visual Studio does not find error messages with:
     94 
     95      " error :"
     96      " error 1:"
     97      " error c1:"
     98      " error 1000:"
     99      " error c100:"
    100 
    101   It does find:
    102      " error c1000:"
    103 --*/
    104 {
    105   va_list List;
    106   //
    107   // If limits have been set, then check that we have not exceeded them
    108   //
    109   if (mPrintLimitsSet) {
    110     //
    111     // See if we've exceeded our total count
    112     //
    113     if (mMaxWarningsPlusErrors != 0) {
    114       if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {
    115         PrintLimitExceeded ();
    116         return ;
    117       }
    118     }
    119     //
    120     // See if we've exceeded our error count
    121     //
    122     if (mMaxErrors != 0) {
    123       if (mErrorCount > mMaxErrors) {
    124         PrintLimitExceeded ();
    125         return ;
    126       }
    127     }
    128   }
    129 
    130   mErrorCount++;
    131   va_start (List, MsgFmt);
    132   PrintMessage ("ERROR", FileName, LineNumber, MessageCode, Text, MsgFmt, List);
    133   va_end (List);
    134 }
    135 
    136 VOID
    137 ParserError (
    138   UINT32  MessageCode,
    139   CHAR8   *Text,
    140   CHAR8   *MsgFmt,
    141   ...
    142   )
    143 /*++
    144 
    145 Routine Description:
    146   Print a parser error, using the source file name and line number
    147   set by a previous call to SetParserPosition().
    148 
    149 Arguments:
    150   MessageCode   - application-specific error code
    151   Text          - text to print in the error message
    152   MsgFmt        - format string to print at the end of the error message
    153 
    154 Returns:
    155   NA
    156 
    157 --*/
    158 {
    159   va_list List;
    160   //
    161   // If limits have been set, then check them
    162   //
    163   if (mPrintLimitsSet) {
    164     //
    165     // See if we've exceeded our total count
    166     //
    167     if (mMaxWarningsPlusErrors != 0) {
    168       if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {
    169         PrintLimitExceeded ();
    170         return ;
    171       }
    172     }
    173     //
    174     // See if we've exceeded our error count
    175     //
    176     if (mMaxErrors != 0) {
    177       if (mErrorCount > mMaxErrors) {
    178         PrintLimitExceeded ();
    179         return ;
    180       }
    181     }
    182   }
    183 
    184   mErrorCount++;
    185   va_start (List, MsgFmt);
    186   PrintMessage ("ERROR", mSourceFileName, mSourceFileLineNum, MessageCode, Text, MsgFmt, List);
    187   va_end (List);
    188 }
    189 
    190 VOID
    191 ParserWarning (
    192   UINT32  ErrorCode,
    193   CHAR8   *OffendingText,
    194   CHAR8   *MsgFmt,
    195   ...
    196   )
    197 /*++
    198 
    199 Routine Description:
    200   Print a parser warning, using the source file name and line number
    201   set by a previous call to SetParserPosition().
    202 
    203 Arguments:
    204   ErrorCode     - application-specific error code
    205   OffendingText - text to print in the warning message
    206   MsgFmt        - format string to print at the end of the warning message
    207 
    208 Returns:
    209   NA
    210 
    211 --*/
    212 {
    213   va_list List;
    214   //
    215   // If limits have been set, then check them
    216   //
    217   if (mPrintLimitsSet) {
    218     //
    219     // See if we've exceeded our total count
    220     //
    221     if (mMaxWarningsPlusErrors != 0) {
    222       if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {
    223         PrintLimitExceeded ();
    224         return ;
    225       }
    226     }
    227     //
    228     // See if we've exceeded our warning count
    229     //
    230     if (mMaxWarnings != 0) {
    231       if (mWarningCount > mMaxWarnings) {
    232         PrintLimitExceeded ();
    233         return ;
    234       }
    235     }
    236   }
    237 
    238   mWarningCount++;
    239   va_start (List, MsgFmt);
    240   PrintMessage ("WARNING", mSourceFileName, mSourceFileLineNum, ErrorCode, OffendingText, MsgFmt, List);
    241   va_end (List);
    242   //
    243   // Don't set warning status accordingly
    244   //
    245   //  if (mStatus < STATUS_WARNING) {
    246   //    mStatus = STATUS_WARNING;
    247   //  }
    248 }
    249 
    250 VOID
    251 Warning (
    252   CHAR8   *FileName,
    253   UINT32  LineNumber,
    254   UINT32  MessageCode,
    255   CHAR8   *Text,
    256   CHAR8   *MsgFmt,
    257   ...
    258   )
    259 /*++
    260 
    261 Routine Description:
    262   Print a warning message.
    263 
    264 Arguments:
    265   FileName    - name of the file where the warning was detected, or the name
    266                 of the application that detected the warning
    267 
    268   LineNumber  - the line number where the warning was detected (parsers).
    269                 0 should be specified if the utility is not a parser.
    270 
    271   MessageCode - an application-specific warning code that can be referenced in
    272                 other documentation.
    273 
    274   Text        - the text in question (parsers)
    275 
    276   MsgFmt      - the format string for the warning message. Can contain formatting
    277                 controls for use with varargs.
    278 
    279 Returns:
    280   None.
    281 
    282 --*/
    283 {
    284   va_list List;
    285 
    286   //
    287   // Current Print Level not output warning information.
    288   //
    289   if (WARNING_LOG_LEVEL < mPrintLogLevel) {
    290     return;
    291   }
    292   //
    293   // If limits have been set, then check them
    294   //
    295   if (mPrintLimitsSet) {
    296     //
    297     // See if we've exceeded our total count
    298     //
    299     if (mMaxWarningsPlusErrors != 0) {
    300       if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {
    301         PrintLimitExceeded ();
    302         return ;
    303       }
    304     }
    305     //
    306     // See if we've exceeded our warning count
    307     //
    308     if (mMaxWarnings != 0) {
    309       if (mWarningCount > mMaxWarnings) {
    310         PrintLimitExceeded ();
    311         return ;
    312       }
    313     }
    314   }
    315 
    316   mWarningCount++;
    317   va_start (List, MsgFmt);
    318   PrintMessage ("WARNING", FileName, LineNumber, MessageCode, Text, MsgFmt, List);
    319   va_end (List);
    320 }
    321 
    322 VOID
    323 DebugMsg (
    324   CHAR8   *FileName,
    325   UINT32  LineNumber,
    326   UINT64  MsgLevel,
    327   CHAR8   *Text,
    328   CHAR8   *MsgFmt,
    329   ...
    330   )
    331 /*++
    332 
    333 Routine Description:
    334   Print a Debug message.
    335 
    336 Arguments:
    337   FileName    - typically the name of the utility printing the debug message, but
    338                 can be the name of a file being parsed.
    339 
    340   LineNumber  - the line number in FileName (parsers)
    341 
    342   MsgLevel    - Debug message print level (0~9)
    343 
    344   Text        - the text in question (parsers)
    345 
    346   MsgFmt      - the format string for the debug message. Can contain formatting
    347                 controls for use with varargs.
    348 
    349 Returns:
    350   None.
    351 
    352 --*/
    353 {
    354   va_list List;
    355   //
    356   // If the debug level is less than current print level, then do nothing.
    357   //
    358   if (MsgLevel < mPrintLogLevel) {
    359     return ;
    360   }
    361 
    362   va_start (List, MsgFmt);
    363   PrintMessage ("DEBUG", FileName, LineNumber, 0, Text, MsgFmt, List);
    364   va_end (List);
    365 }
    366 
    367 VOID
    368 PrintMessage (
    369   CHAR8   *Type,
    370   CHAR8   *FileName,
    371   UINT32  LineNumber,
    372   UINT32  MessageCode,
    373   CHAR8   *Text,
    374   CHAR8   *MsgFmt,
    375   va_list List
    376   )
    377 /*++
    378 
    379 Routine Description:
    380   Worker routine for all the utility printing services. Prints the message in
    381   a format that Visual Studio will find when scanning build outputs for
    382   errors or warnings.
    383 
    384 Arguments:
    385   Type        - "warning" or "error" string to insert into the message to be
    386                 printed. The first character of this string (converted to uppercase)
    387                 is used to preceed the MessageCode value in the output string.
    388 
    389   FileName    - name of the file where the warning was detected, or the name
    390                 of the application that detected the warning
    391 
    392   LineNumber  - the line number where the warning was detected (parsers).
    393                 0 should be specified if the utility is not a parser.
    394 
    395   MessageCode - an application-specific warning code that can be referenced in
    396                 other documentation.
    397 
    398   Text        - part of the message to print
    399 
    400   MsgFmt      - the format string for the message. Can contain formatting
    401                 controls for use with varargs.
    402   List        - the variable list.
    403 
    404 Returns:
    405   None.
    406 
    407 Notes:
    408   If FileName == NULL then this utility will use the string passed into SetUtilityName().
    409 
    410   LineNumber is only used if the caller is a parser, in which case FileName refers to the
    411   file being parsed.
    412 
    413   Text and MsgFmt are both optional, though it would be of little use calling this function with
    414   them both NULL.
    415 
    416   Output will typically be of the form:
    417     <FileName>(<LineNumber>) : <Type> <Type[0]><MessageCode>: <Text> : <MsgFmt>
    418 
    419     Parser (LineNumber != 0)
    420       VfrCompile.cpp(330) : error E2660: AddVfrDataStructField : function does not take 2 parameters
    421     Generic utility (LineNumber == 0)
    422       UtilityName : error E1234 : Text string : MsgFmt string and args
    423 
    424 --*/
    425 {
    426   CHAR8       Line[MAX_LINE_LEN];
    427   CHAR8       Line2[MAX_LINE_LEN];
    428   CHAR8       *Cptr;
    429   struct tm   *NewTime;
    430   time_t      CurrentTime;
    431 
    432   //
    433   // init local variable
    434   //
    435   Line[0] = '\0';
    436   Line2[0] = '\0';
    437 
    438   //
    439   // If given a filename, then add it (and the line number) to the string.
    440   // If there's no filename, then use the program name if provided.
    441   //
    442   if (FileName != NULL) {
    443     Cptr = FileName;
    444   } else {
    445     Cptr = NULL;
    446   }
    447 
    448   if (strcmp (Type, "DEBUG") == 0) {
    449     //
    450     // Debug Message requires current time.
    451     //
    452     time (&CurrentTime);
    453     NewTime = localtime (&CurrentTime);
    454     fprintf (stdout, "%04d-%02d-%02d %02d:%02d:%02d",
    455                      NewTime->tm_year + 1900,
    456                      NewTime->tm_mon + 1,
    457                      NewTime->tm_mday,
    458                      NewTime->tm_hour,
    459                      NewTime->tm_min,
    460                      NewTime->tm_sec
    461                      );
    462     if (Cptr != NULL) {
    463       sprintf (Line, ": %s", Cptr);
    464       if (LineNumber != 0) {
    465         sprintf (Line2, "(%u)", (unsigned) LineNumber);
    466         strcat (Line, Line2);
    467       }
    468     }
    469   } else {
    470     //
    471     // Error and Warning Information.
    472     //
    473     if (Cptr != NULL) {
    474       if (mUtilityName[0] != '\0') {
    475         fprintf (stdout, "%s...\n", mUtilityName);
    476       }
    477       sprintf (Line, "%s", Cptr);
    478       if (LineNumber != 0) {
    479         sprintf (Line2, "(%u)", (unsigned) LineNumber);
    480         strcat (Line, Line2);
    481       }
    482     } else {
    483       if (mUtilityName[0] != '\0') {
    484         sprintf (Line, "%s", mUtilityName);
    485       }
    486     }
    487 
    488     if (strcmp (Type, "ERROR") == 0) {
    489       //
    490       // Set status accordingly for ERROR information.
    491       //
    492       if (mStatus < STATUS_ERROR) {
    493         mStatus = STATUS_ERROR;
    494       }
    495     }
    496   }
    497 
    498   //
    499   // Have to print an error code or Visual Studio won't find the
    500   // message for you. It has to be decimal digits too.
    501   //
    502   if (MessageCode != 0) {
    503     sprintf (Line2, ": %s %04u", Type, (unsigned) MessageCode);
    504   } else {
    505     sprintf (Line2, ": %s", Type);
    506   }
    507   strcat (Line, Line2);
    508   fprintf (stdout, "%s", Line);
    509   //
    510   // If offending text was provided, then print it
    511   //
    512   if (Text != NULL) {
    513     fprintf (stdout, ": %s", Text);
    514   }
    515   fprintf (stdout, "\n");
    516 
    517   //
    518   // Print formatted message if provided
    519   //
    520   if (MsgFmt != NULL) {
    521     vsprintf (Line2, MsgFmt, List);
    522     fprintf (stdout, "  %s\n", Line2);
    523   }
    524 
    525 }
    526 
    527 STATIC
    528 VOID
    529 PrintSimpleMessage (
    530   CHAR8   *MsgFmt,
    531   va_list List
    532   )
    533 /*++
    534 Routine Description:
    535   Print message into stdout.
    536 
    537 Arguments:
    538   MsgFmt      - the format string for the message. Can contain formatting
    539                 controls for use with varargs.
    540   List        - the variable list.
    541 
    542 Returns:
    543   None.
    544 --*/
    545 {
    546   CHAR8       Line[MAX_LINE_LEN];
    547   //
    548   // Print formatted message if provided
    549   //
    550   if (MsgFmt != NULL) {
    551     vsprintf (Line, MsgFmt, List);
    552     fprintf (stdout, "%s\n", Line);
    553   }
    554 }
    555 
    556 VOID
    557 ParserSetPosition (
    558   CHAR8   *SourceFileName,
    559   UINT32  LineNum
    560   )
    561 /*++
    562 
    563 Routine Description:
    564   Set the position in a file being parsed. This can be used to
    565   print error messages deeper down in a parser.
    566 
    567 Arguments:
    568   SourceFileName - name of the source file being parsed
    569   LineNum        - line number of the source file being parsed
    570 
    571 Returns:
    572   NA
    573 
    574 --*/
    575 {
    576   mSourceFileName     = SourceFileName;
    577   mSourceFileLineNum  = LineNum;
    578 }
    579 
    580 VOID
    581 SetUtilityName (
    582   CHAR8   *UtilityName
    583   )
    584 /*++
    585 
    586 Routine Description:
    587   All printed error/warning/debug messages follow the same format, and
    588   typically will print a filename or utility name followed by the error
    589   text. However if a filename is not passed to the print routines, then
    590   they'll print the utility name if you call this function early in your
    591   app to set the utility name.
    592 
    593 Arguments:
    594   UtilityName  -  name of the utility, which will be printed with all
    595                   error/warning/debug messags.
    596 
    597 Returns:
    598   NA
    599 
    600 --*/
    601 {
    602   //
    603   // Save the name of the utility in our local variable. Make sure its
    604   // length does not exceed our buffer.
    605   //
    606   if (UtilityName != NULL) {
    607     if (strlen (UtilityName) >= sizeof (mUtilityName)) {
    608       Error (UtilityName, 0, 0, "application error", "utility name length exceeds internal buffer size");
    609       strncpy (mUtilityName, UtilityName, sizeof (mUtilityName) - 1);
    610       mUtilityName[sizeof (mUtilityName) - 1] = 0;
    611       return ;
    612     } else {
    613       strcpy (mUtilityName, UtilityName);
    614     }
    615   } else {
    616     Error (NULL, 0, 0, "application error", "SetUtilityName() called with NULL utility name");
    617   }
    618 }
    619 
    620 STATUS
    621 GetUtilityStatus (
    622   VOID
    623   )
    624 /*++
    625 
    626 Routine Description:
    627   When you call Error() or Warning(), this module keeps track of it and
    628   sets a local mStatus to STATUS_ERROR or STATUS_WARNING. When the utility
    629   exits, it can call this function to get the status and use it as a return
    630   value.
    631 
    632 Arguments:
    633   None.
    634 
    635 Returns:
    636   Worst-case status reported, as defined by which print function was called.
    637 
    638 --*/
    639 {
    640   return mStatus;
    641 }
    642 
    643 VOID
    644 SetPrintLevel (
    645   UINT64  LogLevel
    646   )
    647 /*++
    648 
    649 Routine Description:
    650   Set the printing message Level. This is used by the PrintMsg() function
    651   to determine when/if a message should be printed.
    652 
    653 Arguments:
    654   LogLevel  - 0~50 to specify the different level message.
    655 
    656 Returns:
    657   NA
    658 
    659 --*/
    660 {
    661   mPrintLogLevel = LogLevel;
    662 }
    663 
    664 VOID
    665 VerboseMsg (
    666   CHAR8   *MsgFmt,
    667   ...
    668   )
    669 /*++
    670 
    671 Routine Description:
    672   Print a verbose level message.
    673 
    674 Arguments:
    675   MsgFmt      - the format string for the message. Can contain formatting
    676                 controls for use with varargs.
    677   List        - the variable list.
    678 
    679 Returns:
    680   NA
    681 
    682 --*/
    683 {
    684   va_list List;
    685   //
    686   // If the debug level is less than current print level, then do nothing.
    687   //
    688   if (VERBOSE_LOG_LEVEL < mPrintLogLevel) {
    689     return ;
    690   }
    691 
    692   va_start (List, MsgFmt);
    693   PrintSimpleMessage (MsgFmt, List);
    694   va_end (List);
    695 }
    696 
    697 VOID
    698 NormalMsg (
    699   CHAR8   *MsgFmt,
    700   ...
    701   )
    702 /*++
    703 
    704 Routine Description:
    705   Print a default level message.
    706 
    707 Arguments:
    708   MsgFmt      - the format string for the message. Can contain formatting
    709                 controls for use with varargs.
    710   List        - the variable list.
    711 
    712 Returns:
    713   NA
    714 
    715 --*/
    716 {
    717   va_list List;
    718   //
    719   // If the debug level is less than current print level, then do nothing.
    720   //
    721   if (INFO_LOG_LEVEL < mPrintLogLevel) {
    722     return ;
    723   }
    724 
    725   va_start (List, MsgFmt);
    726   PrintSimpleMessage (MsgFmt, List);
    727   va_end (List);
    728 }
    729 
    730 VOID
    731 KeyMsg (
    732   CHAR8   *MsgFmt,
    733   ...
    734   )
    735 /*++
    736 
    737 Routine Description:
    738   Print a key level message.
    739 
    740 Arguments:
    741   MsgFmt      - the format string for the message. Can contain formatting
    742                 controls for use with varargs.
    743   List        - the variable list.
    744 
    745 Returns:
    746   NA
    747 
    748 --*/
    749 {
    750   va_list List;
    751   //
    752   // If the debug level is less than current print level, then do nothing.
    753   //
    754   if (KEY_LOG_LEVEL < mPrintLogLevel) {
    755     return ;
    756   }
    757 
    758   va_start (List, MsgFmt);
    759   PrintSimpleMessage (MsgFmt, List);
    760   va_end (List);
    761 }
    762 
    763 VOID
    764 SetPrintLimits (
    765   UINT32  MaxErrors,
    766   UINT32  MaxWarnings,
    767   UINT32  MaxWarningsPlusErrors
    768   )
    769 /*++
    770 
    771 Routine Description:
    772   Set the limits of how many errors, warnings, and errors+warnings
    773   we will print.
    774 
    775 Arguments:
    776   MaxErrors       - maximum number of error messages to print
    777   MaxWarnings     - maximum number of warning messages to print
    778   MaxWarningsPlusErrors
    779                   - maximum number of errors+warnings to print
    780 
    781 Returns:
    782   NA
    783 
    784 --*/
    785 {
    786   mMaxErrors              = MaxErrors;
    787   mMaxWarnings            = MaxWarnings;
    788   mMaxWarningsPlusErrors  = MaxWarningsPlusErrors;
    789   mPrintLimitsSet         = 1;
    790 }
    791 
    792 STATIC
    793 VOID
    794 PrintLimitExceeded (
    795   VOID
    796   )
    797 {
    798   STATIC INT8 mPrintLimitExceeded = 0;
    799   //
    800   // If we've already printed the message, do nothing. Otherwise
    801   // temporarily increase our print limits so we can pass one
    802   // more message through.
    803   //
    804   if (mPrintLimitExceeded == 0) {
    805     mPrintLimitExceeded++;
    806     mMaxErrors++;
    807     mMaxWarnings++;
    808     mMaxWarningsPlusErrors++;
    809     Error (NULL, 0, 0, "error/warning print limit exceeded", NULL);
    810     mMaxErrors--;
    811     mMaxWarnings--;
    812     mMaxWarningsPlusErrors--;
    813   }
    814 }
    815 
    816 #if 0
    817 VOID
    818 TestUtilityMessages (
    819   VOID
    820   )
    821 {
    822   CHAR8 *ArgStr = "ArgString";
    823   int   ArgInt;
    824 
    825   ArgInt  = 0x12345678;
    826   //
    827   // Test without setting utility name
    828   //
    829   fprintf (stdout, "* Testing without setting utility name\n");
    830   fprintf (stdout, "** Test debug message not printed\n");
    831   DebugMsg (NULL, 0, 0x00000001, NULL, NULL);
    832   fprintf (stdout, "** Test warning with two strings and two args\n");
    833   Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
    834   fprintf (stdout, "** Test error with two strings and two args\n");
    835   Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
    836   fprintf (stdout, "** Test parser warning with nothing\n");
    837   ParserWarning (0, NULL, NULL);
    838   fprintf (stdout, "** Test parser error with nothing\n");
    839   ParserError (0, NULL, NULL);
    840   //
    841   // Test with utility name set now
    842   //
    843   fprintf (stdout, "** Testingin with utility name set\n");
    844   SetUtilityName ("MyUtilityName");
    845   //
    846   // Test debug prints
    847   //
    848   SetDebugMsgMask (2);
    849   fprintf (stdout, "** Test debug message with one string\n");
    850   DebugMsg (NULL, 0, 0x00000002, "Text1", NULL);
    851   fprintf (stdout, "** Test debug message with one string\n");
    852   DebugMsg (NULL, 0, 0x00000002, NULL, "Text2");
    853   fprintf (stdout, "** Test debug message with two strings\n");
    854   DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2");
    855   fprintf (stdout, "** Test debug message with two strings and two args\n");
    856   DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
    857   //
    858   // Test warning prints
    859   //
    860   fprintf (stdout, "** Test warning with no strings\n");
    861   Warning (NULL, 0, 1234, NULL, NULL);
    862   fprintf (stdout, "** Test warning with one string\n");
    863   Warning (NULL, 0, 1234, "Text1", NULL);
    864   fprintf (stdout, "** Test warning with one string\n");
    865   Warning (NULL, 0, 1234, NULL, "Text2");
    866   fprintf (stdout, "** Test warning with two strings and two args\n");
    867   Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
    868   //
    869   // Test error prints
    870   //
    871   fprintf (stdout, "** Test error with no strings\n");
    872   Error (NULL, 0, 1234, NULL, NULL);
    873   fprintf (stdout, "** Test error with one string\n");
    874   Error (NULL, 0, 1234, "Text1", NULL);
    875   fprintf (stdout, "** Test error with one string\n");
    876   Error (NULL, 0, 1234, NULL, "Text2");
    877   fprintf (stdout, "** Test error with two strings and two args\n");
    878   Error (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
    879   //
    880   // Test parser prints
    881   //
    882   fprintf (stdout, "** Test parser errors\n");
    883   ParserSetPosition (__FILE__, __LINE__ + 1);
    884   ParserError (1234, NULL, NULL);
    885   ParserSetPosition (__FILE__, __LINE__ + 1);
    886   ParserError (1234, "Text1", NULL);
    887   ParserSetPosition (__FILE__, __LINE__ + 1);
    888   ParserError (1234, NULL, "Text2");
    889   ParserSetPosition (__FILE__, __LINE__ + 1);
    890   ParserError (1234, "Text1", "Text2");
    891   ParserSetPosition (__FILE__, __LINE__ + 1);
    892   ParserError (1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
    893 
    894   fprintf (stdout, "** Test parser warnings\n");
    895   ParserSetPosition (__FILE__, __LINE__ + 1);
    896   ParserWarning (4321, NULL, NULL);
    897   ParserSetPosition (__FILE__, __LINE__ + 1);
    898   ParserWarning (4321, "Text1", NULL);
    899   ParserSetPosition (__FILE__, __LINE__ + 1);
    900   ParserWarning (4321, NULL, "Text2");
    901   ParserSetPosition (__FILE__, __LINE__ + 1);
    902   ParserWarning (4321, "Text1", "Text2");
    903   ParserSetPosition (__FILE__, __LINE__ + 1);
    904   ParserWarning (4321, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
    905 }
    906 #endif
    907