• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 EFI tools utility functions to display warning, error, and informational messages
3 
4 Copyright (c) 2004 - 2016, 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
Error(CHAR8 * FileName,UINT32 LineNumber,UINT32 MessageCode,CHAR8 * Text,CHAR8 * MsgFmt,...)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
ParserError(UINT32 MessageCode,CHAR8 * Text,CHAR8 * MsgFmt,...)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
ParserWarning(UINT32 ErrorCode,CHAR8 * OffendingText,CHAR8 * MsgFmt,...)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
Warning(CHAR8 * FileName,UINT32 LineNumber,UINT32 MessageCode,CHAR8 * Text,CHAR8 * MsgFmt,...)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
DebugMsg(CHAR8 * FileName,UINT32 LineNumber,UINT64 MsgLevel,CHAR8 * Text,CHAR8 * MsgFmt,...)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
PrintMessage(CHAR8 * Type,CHAR8 * FileName,UINT32 LineNumber,UINT32 MessageCode,CHAR8 * Text,CHAR8 * MsgFmt,va_list List)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     if (NewTime != NULL) {
455       fprintf (stdout, "%04d-%02d-%02d %02d:%02d:%02d",
456                        NewTime->tm_year + 1900,
457                        NewTime->tm_mon + 1,
458                        NewTime->tm_mday,
459                        NewTime->tm_hour,
460                        NewTime->tm_min,
461                        NewTime->tm_sec
462                        );
463     }
464     if (Cptr != NULL) {
465       sprintf (Line, ": %s", Cptr);
466       if (LineNumber != 0) {
467         sprintf (Line2, "(%u)", (unsigned) LineNumber);
468         strcat (Line, Line2);
469       }
470     }
471   } else {
472     //
473     // Error and Warning Information.
474     //
475     if (Cptr != NULL) {
476       if (mUtilityName[0] != '\0') {
477         fprintf (stdout, "%s...\n", mUtilityName);
478       }
479       sprintf (Line, "%s", Cptr);
480       if (LineNumber != 0) {
481         sprintf (Line2, "(%u)", (unsigned) LineNumber);
482         strcat (Line, Line2);
483       }
484     } else {
485       if (mUtilityName[0] != '\0') {
486         sprintf (Line, "%s", mUtilityName);
487       }
488     }
489 
490     if (strcmp (Type, "ERROR") == 0) {
491       //
492       // Set status accordingly for ERROR information.
493       //
494       if (mStatus < STATUS_ERROR) {
495         mStatus = STATUS_ERROR;
496       }
497     }
498   }
499 
500   //
501   // Have to print an error code or Visual Studio won't find the
502   // message for you. It has to be decimal digits too.
503   //
504   if (MessageCode != 0) {
505     sprintf (Line2, ": %s %04u", Type, (unsigned) MessageCode);
506   } else {
507     sprintf (Line2, ": %s", Type);
508   }
509   strcat (Line, Line2);
510   fprintf (stdout, "%s", Line);
511   //
512   // If offending text was provided, then print it
513   //
514   if (Text != NULL) {
515     fprintf (stdout, ": %s", Text);
516   }
517   fprintf (stdout, "\n");
518 
519   //
520   // Print formatted message if provided
521   //
522   if (MsgFmt != NULL) {
523     vsprintf (Line2, MsgFmt, List);
524     fprintf (stdout, "  %s\n", Line2);
525   }
526 
527 }
528 
529 STATIC
530 VOID
PrintSimpleMessage(CHAR8 * MsgFmt,va_list List)531 PrintSimpleMessage (
532   CHAR8   *MsgFmt,
533   va_list List
534   )
535 /*++
536 Routine Description:
537   Print message into stdout.
538 
539 Arguments:
540   MsgFmt      - the format string for the message. Can contain formatting
541                 controls for use with varargs.
542   List        - the variable list.
543 
544 Returns:
545   None.
546 --*/
547 {
548   CHAR8       Line[MAX_LINE_LEN];
549   //
550   // Print formatted message if provided
551   //
552   if (MsgFmt != NULL) {
553     vsprintf (Line, MsgFmt, List);
554     fprintf (stdout, "%s\n", Line);
555   }
556 }
557 
558 VOID
ParserSetPosition(CHAR8 * SourceFileName,UINT32 LineNum)559 ParserSetPosition (
560   CHAR8   *SourceFileName,
561   UINT32  LineNum
562   )
563 /*++
564 
565 Routine Description:
566   Set the position in a file being parsed. This can be used to
567   print error messages deeper down in a parser.
568 
569 Arguments:
570   SourceFileName - name of the source file being parsed
571   LineNum        - line number of the source file being parsed
572 
573 Returns:
574   NA
575 
576 --*/
577 {
578   mSourceFileName     = SourceFileName;
579   mSourceFileLineNum  = LineNum;
580 }
581 
582 VOID
SetUtilityName(CHAR8 * UtilityName)583 SetUtilityName (
584   CHAR8   *UtilityName
585   )
586 /*++
587 
588 Routine Description:
589   All printed error/warning/debug messages follow the same format, and
590   typically will print a filename or utility name followed by the error
591   text. However if a filename is not passed to the print routines, then
592   they'll print the utility name if you call this function early in your
593   app to set the utility name.
594 
595 Arguments:
596   UtilityName  -  name of the utility, which will be printed with all
597                   error/warning/debug messags.
598 
599 Returns:
600   NA
601 
602 --*/
603 {
604   //
605   // Save the name of the utility in our local variable. Make sure its
606   // length does not exceed our buffer.
607   //
608   if (UtilityName != NULL) {
609     if (strlen (UtilityName) >= sizeof (mUtilityName)) {
610       Error (UtilityName, 0, 0, "application error", "utility name length exceeds internal buffer size");
611       strncpy (mUtilityName, UtilityName, sizeof (mUtilityName) - 1);
612       mUtilityName[sizeof (mUtilityName) - 1] = 0;
613       return ;
614     } else {
615       strcpy (mUtilityName, UtilityName);
616     }
617   } else {
618     Error (NULL, 0, 0, "application error", "SetUtilityName() called with NULL utility name");
619   }
620 }
621 
622 STATUS
GetUtilityStatus(VOID)623 GetUtilityStatus (
624   VOID
625   )
626 /*++
627 
628 Routine Description:
629   When you call Error() or Warning(), this module keeps track of it and
630   sets a local mStatus to STATUS_ERROR or STATUS_WARNING. When the utility
631   exits, it can call this function to get the status and use it as a return
632   value.
633 
634 Arguments:
635   None.
636 
637 Returns:
638   Worst-case status reported, as defined by which print function was called.
639 
640 --*/
641 {
642   return mStatus;
643 }
644 
645 VOID
SetPrintLevel(UINT64 LogLevel)646 SetPrintLevel (
647   UINT64  LogLevel
648   )
649 /*++
650 
651 Routine Description:
652   Set the printing message Level. This is used by the PrintMsg() function
653   to determine when/if a message should be printed.
654 
655 Arguments:
656   LogLevel  - 0~50 to specify the different level message.
657 
658 Returns:
659   NA
660 
661 --*/
662 {
663   mPrintLogLevel = LogLevel;
664 }
665 
666 VOID
VerboseMsg(CHAR8 * MsgFmt,...)667 VerboseMsg (
668   CHAR8   *MsgFmt,
669   ...
670   )
671 /*++
672 
673 Routine Description:
674   Print a verbose level message.
675 
676 Arguments:
677   MsgFmt      - the format string for the message. Can contain formatting
678                 controls for use with varargs.
679   List        - the variable list.
680 
681 Returns:
682   NA
683 
684 --*/
685 {
686   va_list List;
687   //
688   // If the debug level is less than current print level, then do nothing.
689   //
690   if (VERBOSE_LOG_LEVEL < mPrintLogLevel) {
691     return ;
692   }
693 
694   va_start (List, MsgFmt);
695   PrintSimpleMessage (MsgFmt, List);
696   va_end (List);
697 }
698 
699 VOID
NormalMsg(CHAR8 * MsgFmt,...)700 NormalMsg (
701   CHAR8   *MsgFmt,
702   ...
703   )
704 /*++
705 
706 Routine Description:
707   Print a default level message.
708 
709 Arguments:
710   MsgFmt      - the format string for the message. Can contain formatting
711                 controls for use with varargs.
712   List        - the variable list.
713 
714 Returns:
715   NA
716 
717 --*/
718 {
719   va_list List;
720   //
721   // If the debug level is less than current print level, then do nothing.
722   //
723   if (INFO_LOG_LEVEL < mPrintLogLevel) {
724     return ;
725   }
726 
727   va_start (List, MsgFmt);
728   PrintSimpleMessage (MsgFmt, List);
729   va_end (List);
730 }
731 
732 VOID
KeyMsg(CHAR8 * MsgFmt,...)733 KeyMsg (
734   CHAR8   *MsgFmt,
735   ...
736   )
737 /*++
738 
739 Routine Description:
740   Print a key level message.
741 
742 Arguments:
743   MsgFmt      - the format string for the message. Can contain formatting
744                 controls for use with varargs.
745   List        - the variable list.
746 
747 Returns:
748   NA
749 
750 --*/
751 {
752   va_list List;
753   //
754   // If the debug level is less than current print level, then do nothing.
755   //
756   if (KEY_LOG_LEVEL < mPrintLogLevel) {
757     return ;
758   }
759 
760   va_start (List, MsgFmt);
761   PrintSimpleMessage (MsgFmt, List);
762   va_end (List);
763 }
764 
765 VOID
SetPrintLimits(UINT32 MaxErrors,UINT32 MaxWarnings,UINT32 MaxWarningsPlusErrors)766 SetPrintLimits (
767   UINT32  MaxErrors,
768   UINT32  MaxWarnings,
769   UINT32  MaxWarningsPlusErrors
770   )
771 /*++
772 
773 Routine Description:
774   Set the limits of how many errors, warnings, and errors+warnings
775   we will print.
776 
777 Arguments:
778   MaxErrors       - maximum number of error messages to print
779   MaxWarnings     - maximum number of warning messages to print
780   MaxWarningsPlusErrors
781                   - maximum number of errors+warnings to print
782 
783 Returns:
784   NA
785 
786 --*/
787 {
788   mMaxErrors              = MaxErrors;
789   mMaxWarnings            = MaxWarnings;
790   mMaxWarningsPlusErrors  = MaxWarningsPlusErrors;
791   mPrintLimitsSet         = 1;
792 }
793 
794 STATIC
795 VOID
PrintLimitExceeded(VOID)796 PrintLimitExceeded (
797   VOID
798   )
799 {
800   STATIC INT8 mPrintLimitExceeded = 0;
801   //
802   // If we've already printed the message, do nothing. Otherwise
803   // temporarily increase our print limits so we can pass one
804   // more message through.
805   //
806   if (mPrintLimitExceeded == 0) {
807     mPrintLimitExceeded++;
808     mMaxErrors++;
809     mMaxWarnings++;
810     mMaxWarningsPlusErrors++;
811     Error (NULL, 0, 0, "error/warning print limit exceeded", NULL);
812     mMaxErrors--;
813     mMaxWarnings--;
814     mMaxWarningsPlusErrors--;
815   }
816 }
817 
818 #if 0
819 VOID
820 TestUtilityMessages (
821   VOID
822   )
823 {
824   CHAR8 *ArgStr = "ArgString";
825   int   ArgInt;
826 
827   ArgInt  = 0x12345678;
828   //
829   // Test without setting utility name
830   //
831   fprintf (stdout, "* Testing without setting utility name\n");
832   fprintf (stdout, "** Test debug message not printed\n");
833   DebugMsg (NULL, 0, 0x00000001, NULL, NULL);
834   fprintf (stdout, "** Test warning with two strings and two args\n");
835   Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
836   fprintf (stdout, "** Test error with two strings and two args\n");
837   Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
838   fprintf (stdout, "** Test parser warning with nothing\n");
839   ParserWarning (0, NULL, NULL);
840   fprintf (stdout, "** Test parser error with nothing\n");
841   ParserError (0, NULL, NULL);
842   //
843   // Test with utility name set now
844   //
845   fprintf (stdout, "** Testingin with utility name set\n");
846   SetUtilityName ("MyUtilityName");
847   //
848   // Test debug prints
849   //
850   SetDebugMsgMask (2);
851   fprintf (stdout, "** Test debug message with one string\n");
852   DebugMsg (NULL, 0, 0x00000002, "Text1", NULL);
853   fprintf (stdout, "** Test debug message with one string\n");
854   DebugMsg (NULL, 0, 0x00000002, NULL, "Text2");
855   fprintf (stdout, "** Test debug message with two strings\n");
856   DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2");
857   fprintf (stdout, "** Test debug message with two strings and two args\n");
858   DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
859   //
860   // Test warning prints
861   //
862   fprintf (stdout, "** Test warning with no strings\n");
863   Warning (NULL, 0, 1234, NULL, NULL);
864   fprintf (stdout, "** Test warning with one string\n");
865   Warning (NULL, 0, 1234, "Text1", NULL);
866   fprintf (stdout, "** Test warning with one string\n");
867   Warning (NULL, 0, 1234, NULL, "Text2");
868   fprintf (stdout, "** Test warning with two strings and two args\n");
869   Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
870   //
871   // Test error prints
872   //
873   fprintf (stdout, "** Test error with no strings\n");
874   Error (NULL, 0, 1234, NULL, NULL);
875   fprintf (stdout, "** Test error with one string\n");
876   Error (NULL, 0, 1234, "Text1", NULL);
877   fprintf (stdout, "** Test error with one string\n");
878   Error (NULL, 0, 1234, NULL, "Text2");
879   fprintf (stdout, "** Test error with two strings and two args\n");
880   Error (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
881   //
882   // Test parser prints
883   //
884   fprintf (stdout, "** Test parser errors\n");
885   ParserSetPosition (__FILE__, __LINE__ + 1);
886   ParserError (1234, NULL, NULL);
887   ParserSetPosition (__FILE__, __LINE__ + 1);
888   ParserError (1234, "Text1", NULL);
889   ParserSetPosition (__FILE__, __LINE__ + 1);
890   ParserError (1234, NULL, "Text2");
891   ParserSetPosition (__FILE__, __LINE__ + 1);
892   ParserError (1234, "Text1", "Text2");
893   ParserSetPosition (__FILE__, __LINE__ + 1);
894   ParserError (1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
895 
896   fprintf (stdout, "** Test parser warnings\n");
897   ParserSetPosition (__FILE__, __LINE__ + 1);
898   ParserWarning (4321, NULL, NULL);
899   ParserSetPosition (__FILE__, __LINE__ + 1);
900   ParserWarning (4321, "Text1", NULL);
901   ParserSetPosition (__FILE__, __LINE__ + 1);
902   ParserWarning (4321, NULL, "Text2");
903   ParserSetPosition (__FILE__, __LINE__ + 1);
904   ParserWarning (4321, "Text1", "Text2");
905   ParserSetPosition (__FILE__, __LINE__ + 1);
906   ParserWarning (4321, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
907 }
908 #endif
909