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