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
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     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
PrintSimpleMessage(CHAR8 * MsgFmt,va_list List)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
ParserSetPosition(CHAR8 * SourceFileName,UINT32 LineNum)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
SetUtilityName(CHAR8 * UtilityName)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
GetUtilityStatus(VOID)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
SetPrintLevel(UINT64 LogLevel)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
VerboseMsg(CHAR8 * MsgFmt,...)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
NormalMsg(CHAR8 * MsgFmt,...)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
KeyMsg(CHAR8 * MsgFmt,...)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
SetPrintLimits(UINT32 MaxErrors,UINT32 MaxWarnings,UINT32 MaxWarningsPlusErrors)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
PrintLimitExceeded(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