3
Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>
4
This program and the accompanying materials
5
are licensed and made available under the terms and conditions of the BSD License
6
which accompanies this distribution. The full text of the license may be found at
7
http://opensource.org/licenses/bsd-license.php
9
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18
EFI tools utility functions to display warning, error, and informational
29
#include "EfiUtilityMsgs.h"
32
// Declare module globals for keeping track of the the utility's
33
// name and other settings.
35
STATIC STATUS mStatus = STATUS_SUCCESS;
36
STATIC CHAR8 mUtilityName[50] = { 0 };
37
STATIC UINT64 mPrintLogLevel = INFO_LOG_LEVEL;
38
STATIC CHAR8 *mSourceFileName = NULL;
39
STATIC UINT32 mSourceFileLineNum = 0;
40
STATIC UINT32 mErrorCount = 0;
41
STATIC UINT32 mWarningCount = 0;
42
STATIC UINT32 mMaxErrors = 0;
43
STATIC UINT32 mMaxWarnings = 0;
44
STATIC UINT32 mMaxWarningsPlusErrors = 0;
45
STATIC INT8 mPrintLimitsSet = 0;
65
Prints an error message.
68
All arguments are optional, though the printed message may be useless if
69
at least something valid is not specified.
71
FileName - name of the file or application. If not specified, then the
72
utilty name (as set by the utility calling SetUtilityName()
73
earlier) is used. Otherwise "Unknown utility" is used.
75
LineNumber - the line number of error, typically used by parsers. If the
76
utility is not a parser, then 0 should be specified. Otherwise
77
the FileName and LineNumber info can be used to cause
78
MS Visual Studio to jump to the error.
80
MessageCode - an application-specific error code that can be referenced in
83
Text - the text in question, typically used by parsers.
85
MsgFmt - the format string for the error message. Can contain formatting
86
controls for use with the varargs.
92
We print the following (similar to the Warn() and Debug()
94
Typical error/warning message format:
96
bin\VfrCompile.cpp(330) : error C2660: 'AddVfrDataStructField' : function does not take 2 parameters
98
BUGBUG -- these three utility functions are almost identical, and
99
should be modified to share code.
101
Visual Studio does not find error messages with:
115
// If limits have been set, then check that we have not exceeded them
117
if (mPrintLimitsSet) {
119
// See if we've exceeded our total count
121
if (mMaxWarningsPlusErrors != 0) {
122
if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {
123
PrintLimitExceeded ();
128
// See if we've exceeded our error count
130
if (mMaxErrors != 0) {
131
if (mErrorCount > mMaxErrors) {
132
PrintLimitExceeded ();
139
va_start (List, MsgFmt);
140
PrintMessage ("ERROR", FileName, LineNumber, MessageCode, Text, MsgFmt, List);
154
Print a parser error, using the source file name and line number
155
set by a previous call to SetParserPosition().
158
MessageCode - application-specific error code
159
Text - text to print in the error message
160
MsgFmt - format string to print at the end of the error message
169
// If limits have been set, then check them
171
if (mPrintLimitsSet) {
173
// See if we've exceeded our total count
175
if (mMaxWarningsPlusErrors != 0) {
176
if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {
177
PrintLimitExceeded ();
182
// See if we've exceeded our error count
184
if (mMaxErrors != 0) {
185
if (mErrorCount > mMaxErrors) {
186
PrintLimitExceeded ();
193
va_start (List, MsgFmt);
194
PrintMessage ("ERROR", mSourceFileName, mSourceFileLineNum, MessageCode, Text, MsgFmt, List);
201
CHAR8 *OffendingText,
208
Print a parser warning, using the source file name and line number
209
set by a previous call to SetParserPosition().
212
ErrorCode - application-specific error code
213
OffendingText - text to print in the warning message
214
MsgFmt - format string to print at the end of the warning message
223
// If limits have been set, then check them
225
if (mPrintLimitsSet) {
227
// See if we've exceeded our total count
229
if (mMaxWarningsPlusErrors != 0) {
230
if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {
231
PrintLimitExceeded ();
236
// See if we've exceeded our warning count
238
if (mMaxWarnings != 0) {
239
if (mWarningCount > mMaxWarnings) {
240
PrintLimitExceeded ();
247
va_start (List, MsgFmt);
248
PrintMessage ("WARNING", mSourceFileName, mSourceFileLineNum, ErrorCode, OffendingText, MsgFmt, List);
251
// Don't set warning status accordingly
253
// if (mStatus < STATUS_WARNING) {
254
// mStatus = STATUS_WARNING;
270
Print a warning message.
273
FileName - name of the file where the warning was detected, or the name
274
of the application that detected the warning
276
LineNumber - the line number where the warning was detected (parsers).
277
0 should be specified if the utility is not a parser.
279
MessageCode - an application-specific warning code that can be referenced in
282
Text - the text in question (parsers)
284
MsgFmt - the format string for the warning message. Can contain formatting
285
controls for use with varargs.
295
// Current Print Level not output warning information.
297
if (WARNING_LOG_LEVEL < mPrintLogLevel) {
301
// If limits have been set, then check them
303
if (mPrintLimitsSet) {
305
// See if we've exceeded our total count
307
if (mMaxWarningsPlusErrors != 0) {
308
if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {
309
PrintLimitExceeded ();
314
// See if we've exceeded our warning count
316
if (mMaxWarnings != 0) {
317
if (mWarningCount > mMaxWarnings) {
318
PrintLimitExceeded ();
325
va_start (List, MsgFmt);
326
PrintMessage ("WARNING", FileName, LineNumber, MessageCode, Text, MsgFmt, List);
342
Print a Debug message.
345
FileName - typically the name of the utility printing the debug message, but
346
can be the name of a file being parsed.
348
LineNumber - the line number in FileName (parsers)
350
MsgLevel - Debug message print level (0~9)
352
Text - the text in question (parsers)
354
MsgFmt - the format string for the debug message. Can contain formatting
355
controls for use with varargs.
364
// If the debug level is less than current print level, then do nothing.
366
if (MsgLevel < mPrintLogLevel) {
370
va_start (List, MsgFmt);
371
PrintMessage ("DEBUG", FileName, LineNumber, 0, Text, MsgFmt, List);
388
Worker routine for all the utility printing services. Prints the message in
389
a format that Visual Studio will find when scanning build outputs for
393
Type - "warning" or "error" string to insert into the message to be
394
printed. The first character of this string (converted to uppercase)
395
is used to preceed the MessageCode value in the output string.
397
FileName - name of the file where the warning was detected, or the name
398
of the application that detected the warning
400
LineNumber - the line number where the warning was detected (parsers).
401
0 should be specified if the utility is not a parser.
403
MessageCode - an application-specific warning code that can be referenced in
406
Text - part of the message to print
408
MsgFmt - the format string for the message. Can contain formatting
409
controls for use with varargs.
410
List - the variable list.
416
If FileName == NULL then this utility will use the string passed into SetUtilityName().
418
LineNumber is only used if the caller is a parser, in which case FileName refers to the
421
Text and MsgFmt are both optional, though it would be of little use calling this function with
424
Output will typically be of the form:
425
<FileName>(<LineNumber>) : <Type> <Type[0]><MessageCode>: <Text> : <MsgFmt>
427
Parser (LineNumber != 0)
428
VfrCompile.cpp(330) : error E2660: AddVfrDataStructField : function does not take 2 parameters
429
Generic utility (LineNumber == 0)
430
UtilityName : error E1234 : Text string : MsgFmt string and args
434
CHAR8 Line[MAX_LINE_LEN];
435
CHAR8 Line2[MAX_LINE_LEN];
441
// init local variable
447
// If given a filename, then add it (and the line number) to the string.
448
// If there's no filename, then use the program name if provided.
450
if (FileName != NULL) {
456
if (strcmp (Type, "DEBUG") == 0) {
458
// Debug Message requires current time.
461
NewTime = localtime (&CurrentTime);
462
fprintf (stdout, "%04d-%02d-%02d %02d:%02d:%02d",
463
NewTime->tm_year + 1900,
471
sprintf (Line, ": %s", Cptr);
472
if (LineNumber != 0) {
473
sprintf (Line2, "(%u)", (unsigned) LineNumber);
474
strcat (Line, Line2);
479
// Error and Warning Information.
482
if (mUtilityName[0] != '\0') {
483
fprintf (stdout, "%s...\n", mUtilityName);
485
sprintf (Line, "%s", Cptr);
486
if (LineNumber != 0) {
487
sprintf (Line2, "(%u)", (unsigned) LineNumber);
488
strcat (Line, Line2);
491
if (mUtilityName[0] != '\0') {
492
sprintf (Line, "%s", mUtilityName);
496
if (strcmp (Type, "ERROR") == 0) {
498
// Set status accordingly for ERROR information.
500
if (mStatus < STATUS_ERROR) {
501
mStatus = STATUS_ERROR;
507
// Have to print an error code or Visual Studio won't find the
508
// message for you. It has to be decimal digits too.
510
if (MessageCode != 0) {
511
sprintf (Line2, ": %s %04u", Type, (unsigned) MessageCode);
513
sprintf (Line2, ": %s", Type);
515
strcat (Line, Line2);
516
fprintf (stdout, "%s", Line);
518
// If offending text was provided, then print it
521
fprintf (stdout, ": %s", Text);
523
fprintf (stdout, "\n");
526
// Print formatted message if provided
528
if (MsgFmt != NULL) {
529
vsprintf (Line2, MsgFmt, List);
530
fprintf (stdout, " %s\n", Line2);
543
Print message into stdout.
546
MsgFmt - the format string for the message. Can contain formatting
547
controls for use with varargs.
548
List - the variable list.
554
CHAR8 Line[MAX_LINE_LEN];
556
// Print formatted message if provided
558
if (MsgFmt != NULL) {
559
vsprintf (Line, MsgFmt, List);
560
fprintf (stdout, "%s\n", Line);
566
CHAR8 *SourceFileName,
572
Set the position in a file being parsed. This can be used to
573
print error messages deeper down in a parser.
576
SourceFileName - name of the source file being parsed
577
LineNum - line number of the source file being parsed
584
mSourceFileName = SourceFileName;
585
mSourceFileLineNum = LineNum;
595
All printed error/warning/debug messages follow the same format, and
596
typically will print a filename or utility name followed by the error
597
text. However if a filename is not passed to the print routines, then
598
they'll print the utility name if you call this function early in your
599
app to set the utility name.
602
UtilityName - name of the utility, which will be printed with all
603
error/warning/debug messags.
611
// Save the name of the utility in our local variable. Make sure its
612
// length does not exceed our buffer.
614
if (UtilityName != NULL) {
615
if (strlen (UtilityName) >= sizeof (mUtilityName)) {
616
Error (UtilityName, 0, 0, "application error", "utility name length exceeds internal buffer size");
617
strncpy (mUtilityName, UtilityName, sizeof (mUtilityName) - 1);
618
mUtilityName[sizeof (mUtilityName) - 1] = 0;
621
strcpy (mUtilityName, UtilityName);
624
Error (NULL, 0, 0, "application error", "SetUtilityName() called with NULL utility name");
635
When you call Error() or Warning(), this module keeps track of it and
636
sets a local mStatus to STATUS_ERROR or STATUS_WARNING. When the utility
637
exits, it can call this function to get the status and use it as a return
644
Worst-case status reported, as defined by which print function was called.
658
Set the printing message Level. This is used by the PrintMsg() function
659
to determine when/if a message should be printed.
662
LogLevel - 0~50 to specify the different level message.
669
mPrintLogLevel = LogLevel;
680
Print a verbose level message.
683
MsgFmt - the format string for the message. Can contain formatting
684
controls for use with varargs.
685
List - the variable list.
694
// If the debug level is less than current print level, then do nothing.
696
if (VERBOSE_LOG_LEVEL < mPrintLogLevel) {
700
va_start (List, MsgFmt);
701
PrintSimpleMessage (MsgFmt, List);
713
Print a default level message.
716
MsgFmt - the format string for the message. Can contain formatting
717
controls for use with varargs.
718
List - the variable list.
727
// If the debug level is less than current print level, then do nothing.
729
if (INFO_LOG_LEVEL < mPrintLogLevel) {
733
va_start (List, MsgFmt);
734
PrintSimpleMessage (MsgFmt, List);
746
Print a key level message.
749
MsgFmt - the format string for the message. Can contain formatting
750
controls for use with varargs.
751
List - the variable list.
760
// If the debug level is less than current print level, then do nothing.
762
if (KEY_LOG_LEVEL < mPrintLogLevel) {
766
va_start (List, MsgFmt);
767
PrintSimpleMessage (MsgFmt, List);
775
UINT32 MaxWarningsPlusErrors
780
Set the limits of how many errors, warnings, and errors+warnings
784
MaxErrors - maximum number of error messages to print
785
MaxWarnings - maximum number of warning messages to print
786
MaxWarningsPlusErrors
787
- maximum number of errors+warnings to print
794
mMaxErrors = MaxErrors;
795
mMaxWarnings = MaxWarnings;
796
mMaxWarningsPlusErrors = MaxWarningsPlusErrors;
806
STATIC INT8 mPrintLimitExceeded = 0;
808
// If we've already printed the message, do nothing. Otherwise
809
// temporarily increase our print limits so we can pass one
810
// more message through.
812
if (mPrintLimitExceeded == 0) {
813
mPrintLimitExceeded++;
816
mMaxWarningsPlusErrors++;
817
Error (NULL, 0, 0, "error/warning print limit exceeded", NULL);
820
mMaxWarningsPlusErrors--;
826
TestUtilityMessages (
830
CHAR8 *ArgStr = "ArgString";
835
// Test without setting utility name
837
fprintf (stdout, "* Testing without setting utility name\n");
838
fprintf (stdout, "** Test debug message not printed\n");
839
DebugMsg (NULL, 0, 0x00000001, NULL, NULL);
840
fprintf (stdout, "** Test warning with two strings and two args\n");
841
Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
842
fprintf (stdout, "** Test error with two strings and two args\n");
843
Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
844
fprintf (stdout, "** Test parser warning with nothing\n");
845
ParserWarning (0, NULL, NULL);
846
fprintf (stdout, "** Test parser error with nothing\n");
847
ParserError (0, NULL, NULL);
849
// Test with utility name set now
851
fprintf (stdout, "** Testingin with utility name set\n");
852
SetUtilityName ("MyUtilityName");
857
fprintf (stdout, "** Test debug message with one string\n");
858
DebugMsg (NULL, 0, 0x00000002, "Text1", NULL);
859
fprintf (stdout, "** Test debug message with one string\n");
860
DebugMsg (NULL, 0, 0x00000002, NULL, "Text2");
861
fprintf (stdout, "** Test debug message with two strings\n");
862
DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2");
863
fprintf (stdout, "** Test debug message with two strings and two args\n");
864
DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
866
// Test warning prints
868
fprintf (stdout, "** Test warning with no strings\n");
869
Warning (NULL, 0, 1234, NULL, NULL);
870
fprintf (stdout, "** Test warning with one string\n");
871
Warning (NULL, 0, 1234, "Text1", NULL);
872
fprintf (stdout, "** Test warning with one string\n");
873
Warning (NULL, 0, 1234, NULL, "Text2");
874
fprintf (stdout, "** Test warning with two strings and two args\n");
875
Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
879
fprintf (stdout, "** Test error with no strings\n");
880
Error (NULL, 0, 1234, NULL, NULL);
881
fprintf (stdout, "** Test error with one string\n");
882
Error (NULL, 0, 1234, "Text1", NULL);
883
fprintf (stdout, "** Test error with one string\n");
884
Error (NULL, 0, 1234, NULL, "Text2");
885
fprintf (stdout, "** Test error with two strings and two args\n");
886
Error (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
888
// Test parser prints
890
fprintf (stdout, "** Test parser errors\n");
891
ParserSetPosition (__FILE__, __LINE__ + 1);
892
ParserError (1234, NULL, NULL);
893
ParserSetPosition (__FILE__, __LINE__ + 1);
894
ParserError (1234, "Text1", NULL);
895
ParserSetPosition (__FILE__, __LINE__ + 1);
896
ParserError (1234, NULL, "Text2");
897
ParserSetPosition (__FILE__, __LINE__ + 1);
898
ParserError (1234, "Text1", "Text2");
899
ParserSetPosition (__FILE__, __LINE__ + 1);
900
ParserError (1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
902
fprintf (stdout, "** Test parser warnings\n");
903
ParserSetPosition (__FILE__, __LINE__ + 1);
904
ParserWarning (4321, NULL, NULL);
905
ParserSetPosition (__FILE__, __LINE__ + 1);
906
ParserWarning (4321, "Text1", NULL);
907
ParserSetPosition (__FILE__, __LINE__ + 1);
908
ParserWarning (4321, NULL, "Text2");
909
ParserSetPosition (__FILE__, __LINE__ + 1);
910
ParserWarning (4321, "Text1", "Text2");
911
ParserSetPosition (__FILE__, __LINE__ + 1);
912
ParserWarning (4321, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);