+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2004, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name: \r
-\r
- EfiUtilityMsgs.c\r
- \r
-Abstract:\r
-\r
- EFI tools utility functions to display warning, error, and informational\r
- messages.\r
- \r
---*/\r
-\r
-#include <stdio.h>\r
-#include <string.h>\r
-#include <ctype.h>\r
-#include <stdarg.h>\r
-\r
-#include "EfiUtilityMsgs.h"\r
-\r
-#define MAX_LINE_LEN 200\r
-\r
-//\r
-// Declare module globals for keeping track of the the utility's\r
-// name and other settings.\r
-//\r
-static STATUS mStatus = STATUS_SUCCESS;\r
-static CHAR8 mUtilityName[50] = { 0 };\r
-static UINT32 mDebugMsgMask = 0;\r
-static CHAR8 *mSourceFileName = NULL;\r
-static UINT32 mSourceFileLineNum = 0;\r
-static UINT32 mErrorCount = 0;\r
-static UINT32 mWarningCount = 0;\r
-static UINT32 mMaxErrors = 0;\r
-static UINT32 mMaxWarnings = 0;\r
-static UINT32 mMaxWarningsPlusErrors = 0;\r
-static INT8 mPrintLimitsSet = 0;\r
-\r
-static\r
-void\r
-PrintMessage (\r
- CHAR8 *Type,\r
- CHAR8 *FileName,\r
- UINT32 LineNumber,\r
- UINT32 MessageCode,\r
- CHAR8 *Text,\r
- CHAR8 *MsgFmt,\r
- va_list List\r
- );\r
-\r
-static\r
-void\r
-PrintLimitExceeded (\r
- VOID\r
- );\r
-\r
-void\r
-Error (\r
- CHAR8 *FileName,\r
- UINT32 LineNumber,\r
- UINT32 MessageCode,\r
- CHAR8 *Text,\r
- CHAR8 *MsgFmt,\r
- ...\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Prints an error message.\r
- \r
-Arguments:\r
- All arguments are optional, though the printed message may be useless if\r
- at least something valid is not specified.\r
- \r
- FileName - name of the file or application. If not specified, then the\r
- utilty name (as set by the utility calling SetUtilityName()\r
- earlier) is used. Otherwise "Unknown utility" is used.\r
- \r
- LineNumber - the line number of error, typically used by parsers. If the\r
- utility is not a parser, then 0 should be specified. Otherwise\r
- the FileName and LineNumber info can be used to cause\r
- MS Visual Studio to jump to the error.\r
- \r
- MessageCode - an application-specific error code that can be referenced in\r
- other documentation. \r
-\r
- Text - the text in question, typically used by parsers.\r
- \r
- MsgFmt - the format string for the error message. Can contain formatting\r
- controls for use with the varargs.\r
- \r
-Returns:\r
- None.\r
- \r
-Notes:\r
- We print the following (similar to the Warn() and Debug() \r
- W\r
- Typical error/warning message format:\r
-\r
- bin\VfrCompile.cpp(330) : error C2660: 'AddVfrDataStructField' : function does not take 2 parameters\r
-\r
- BUGBUG -- these three utility functions are almost identical, and\r
- should be modified to share code.\r
-\r
- Visual Studio does not find error messages with:\r
- \r
- " error :"\r
- " error 1:"\r
- " error c1:"\r
- " error 1000:"\r
- " error c100:"\r
-\r
- It does find:\r
- " error c1000:" \r
---*/\r
-{\r
- va_list List;\r
- //\r
- // If limits have been set, then check that we have not exceeded them\r
- //\r
- if (mPrintLimitsSet) {\r
- //\r
- // See if we've exceeded our total count\r
- //\r
- if (mMaxWarningsPlusErrors != 0) {\r
- if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {\r
- PrintLimitExceeded ();\r
- return ;\r
- }\r
- }\r
- //\r
- // See if we've exceeded our error count\r
- //\r
- if (mMaxErrors != 0) {\r
- if (mErrorCount > mMaxErrors) {\r
- PrintLimitExceeded ();\r
- return ;\r
- }\r
- }\r
- }\r
-\r
- mErrorCount++;\r
- va_start (List, MsgFmt);\r
- PrintMessage ("error", FileName, LineNumber, MessageCode, Text, MsgFmt, List);\r
- va_end (List);\r
- //\r
- // Set status accordingly\r
- //\r
- if (mStatus < STATUS_ERROR) {\r
- mStatus = STATUS_ERROR;\r
- }\r
-}\r
-\r
-void\r
-ParserError (\r
- UINT32 MessageCode,\r
- CHAR8 *Text,\r
- CHAR8 *MsgFmt,\r
- ...\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Print a parser error, using the source file name and line number\r
- set by a previous call to SetParserPosition().\r
-\r
-Arguments:\r
- MessageCode - application-specific error code\r
- Text - text to print in the error message\r
- MsgFmt - format string to print at the end of the error message\r
-\r
-Returns:\r
- NA\r
-\r
---*/\r
-{\r
- va_list List;\r
- //\r
- // If limits have been set, then check them\r
- //\r
- if (mPrintLimitsSet) {\r
- //\r
- // See if we've exceeded our total count\r
- //\r
- if (mMaxWarningsPlusErrors != 0) {\r
- if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {\r
- PrintLimitExceeded ();\r
- return ;\r
- }\r
- }\r
- //\r
- // See if we've exceeded our error count\r
- //\r
- if (mMaxErrors != 0) {\r
- if (mErrorCount > mMaxErrors) {\r
- PrintLimitExceeded ();\r
- return ;\r
- }\r
- }\r
- }\r
-\r
- mErrorCount++;\r
- va_start (List, MsgFmt);\r
- PrintMessage ("error", mSourceFileName, mSourceFileLineNum, MessageCode, Text, MsgFmt, List);\r
- va_end (List);\r
- //\r
- // Set status accordingly\r
- //\r
- if (mStatus < STATUS_ERROR) {\r
- mStatus = STATUS_ERROR;\r
- }\r
-}\r
-\r
-void\r
-ParserWarning (\r
- UINT32 ErrorCode,\r
- CHAR8 *OffendingText,\r
- CHAR8 *MsgFmt,\r
- ...\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Print a parser warning, using the source file name and line number\r
- set by a previous call to SetParserPosition().\r
-\r
-Arguments:\r
- ErrorCode - application-specific error code\r
- OffendingText - text to print in the warning message\r
- MsgFmt - format string to print at the end of the warning message\r
-\r
-Returns:\r
- NA\r
-\r
---*/\r
-{\r
- va_list List;\r
- //\r
- // If limits have been set, then check them\r
- //\r
- if (mPrintLimitsSet) {\r
- //\r
- // See if we've exceeded our total count\r
- //\r
- if (mMaxWarningsPlusErrors != 0) {\r
- if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {\r
- PrintLimitExceeded ();\r
- return ;\r
- }\r
- }\r
- //\r
- // See if we've exceeded our warning count\r
- //\r
- if (mMaxWarnings != 0) {\r
- if (mWarningCount > mMaxWarnings) {\r
- PrintLimitExceeded ();\r
- return ;\r
- }\r
- }\r
- }\r
-\r
- mWarningCount++;\r
- va_start (List, MsgFmt);\r
- PrintMessage ("warning", mSourceFileName, mSourceFileLineNum, ErrorCode, OffendingText, MsgFmt, List);\r
- va_end (List);\r
- //\r
- // Set status accordingly\r
- //\r
- if (mStatus < STATUS_WARNING) {\r
- mStatus = STATUS_WARNING;\r
- }\r
-}\r
-\r
-void\r
-Warning (\r
- CHAR8 *FileName,\r
- UINT32 LineNumber,\r
- UINT32 MessageCode,\r
- CHAR8 *Text,\r
- CHAR8 *MsgFmt,\r
- ...\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Print a warning message.\r
-\r
-Arguments:\r
- FileName - name of the file where the warning was detected, or the name\r
- of the application that detected the warning\r
- \r
- LineNumber - the line number where the warning was detected (parsers).\r
- 0 should be specified if the utility is not a parser.\r
- \r
- MessageCode - an application-specific warning code that can be referenced in\r
- other documentation. \r
-\r
- Text - the text in question (parsers)\r
- \r
- MsgFmt - the format string for the warning message. Can contain formatting\r
- controls for use with varargs.\r
- \r
-Returns:\r
- None.\r
-\r
---*/\r
-{\r
- va_list List;\r
- //\r
- // If limits have been set, then check them\r
- //\r
- if (mPrintLimitsSet) {\r
- //\r
- // See if we've exceeded our total count\r
- //\r
- if (mMaxWarningsPlusErrors != 0) {\r
- if (mErrorCount + mWarningCount > mMaxWarningsPlusErrors) {\r
- PrintLimitExceeded ();\r
- return ;\r
- }\r
- }\r
- //\r
- // See if we've exceeded our warning count\r
- //\r
- if (mMaxWarnings != 0) {\r
- if (mWarningCount > mMaxWarnings) {\r
- PrintLimitExceeded ();\r
- return ;\r
- }\r
- }\r
- }\r
-\r
- mWarningCount++;\r
- va_start (List, MsgFmt);\r
- PrintMessage ("warning", FileName, LineNumber, MessageCode, Text, MsgFmt, List);\r
- va_end (List);\r
- //\r
- // Set status accordingly\r
- //\r
- if (mStatus < STATUS_WARNING) {\r
- mStatus = STATUS_WARNING;\r
- }\r
-}\r
-\r
-void\r
-DebugMsg (\r
- CHAR8 *FileName,\r
- UINT32 LineNumber,\r
- UINT32 MsgMask,\r
- CHAR8 *Text,\r
- CHAR8 *MsgFmt,\r
- ...\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Print a warning message.\r
-\r
-Arguments:\r
- FileName - typically the name of the utility printing the debug message, but\r
- can be the name of a file being parsed.\r
- \r
- LineNumber - the line number in FileName (parsers) \r
- \r
- MsgMask - an application-specific bitmask that, in combination with mDebugMsgMask,\r
- determines if the debug message gets printed.\r
-\r
- Text - the text in question (parsers)\r
- \r
- MsgFmt - the format string for the debug message. Can contain formatting\r
- controls for use with varargs.\r
- \r
-Returns:\r
- None.\r
-\r
---*/\r
-{\r
- va_list List;\r
- //\r
- // If the debug mask is not applicable, then do nothing.\r
- //\r
- if ((MsgMask != 0) && ((mDebugMsgMask & MsgMask) == 0)) {\r
- return ;\r
- }\r
-\r
- va_start (List, MsgFmt);\r
- PrintMessage ("debug", FileName, LineNumber, 0, Text, MsgFmt, List);\r
- va_end (List);\r
-}\r
-\r
-static\r
-void\r
-PrintMessage (\r
- CHAR8 *Type,\r
- CHAR8 *FileName,\r
- UINT32 LineNumber,\r
- UINT32 MessageCode,\r
- CHAR8 *Text,\r
- CHAR8 *MsgFmt,\r
- va_list List\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Worker routine for all the utility printing services. Prints the message in\r
- a format that Visual Studio will find when scanning build outputs for\r
- errors or warnings.\r
-\r
-Arguments:\r
- Type - "warning" or "error" string to insert into the message to be\r
- printed. The first character of this string (converted to uppercase)\r
- is used to preceed the MessageCode value in the output string.\r
-\r
- FileName - name of the file where the warning was detected, or the name\r
- of the application that detected the warning\r
- \r
- LineNumber - the line number where the warning was detected (parsers).\r
- 0 should be specified if the utility is not a parser.\r
- \r
- MessageCode - an application-specific warning code that can be referenced in\r
- other documentation. \r
-\r
- Text - part of the message to print\r
- \r
- MsgFmt - the format string for the message. Can contain formatting\r
- controls for use with varargs.\r
- List - the variable list.\r
- \r
-Returns:\r
- None.\r
-\r
-Notes:\r
- If FileName == NULL then this utility will use the string passed into SetUtilityName(). \r
- \r
- LineNumber is only used if the caller is a parser, in which case FileName refers to the\r
- file being parsed.\r
-\r
- Text and MsgFmt are both optional, though it would be of little use calling this function with\r
- them both NULL.\r
-\r
- Output will typically be of the form:\r
- <FileName>(<LineNumber>) : <Type> <Type[0]><MessageCode>: <Text> : <MsgFmt>\r
-\r
- Parser (LineNumber != 0)\r
- VfrCompile.cpp(330) : error E2660: AddVfrDataStructField : function does not take 2 parameters\r
- Generic utility (LineNumber == 0) \r
- UtilityName : error E1234 : Text string : MsgFmt string and args\r
-\r
---*/\r
-{\r
- CHAR8 Line[MAX_LINE_LEN];\r
- CHAR8 Line2[MAX_LINE_LEN];\r
- CHAR8 *Cptr;\r
- //\r
- // If given a filename, then add it (and the line number) to the string.\r
- // If there's no filename, then use the program name if provided.\r
- //\r
- if (FileName != NULL) {\r
- Cptr = FileName;\r
- } else if (mUtilityName[0] != 0) {\r
- Cptr = mUtilityName;\r
- } else {\r
- Cptr = "Unknown utility";\r
- }\r
-\r
- strcpy (Line, Cptr);\r
- if (LineNumber != 0) {\r
- sprintf (Line2, "(%d)", LineNumber);\r
- strcat (Line, Line2);\r
- }\r
- //\r
- // Have to print an error code or Visual Studio won't find the\r
- // message for you. It has to be decimal digits too.\r
- //\r
- sprintf (Line2, " : %s %c%04d", Type, toupper (Type[0]), MessageCode);\r
- strcat (Line, Line2);\r
- fprintf (stdout, "%s", Line);\r
- //\r
- // If offending text was provided, then print it\r
- //\r
- if (Text != NULL) {\r
- fprintf (stdout, ": %s ", Text);\r
- }\r
- //\r
- // Print formatted message if provided\r
- //\r
- if (MsgFmt != NULL) {\r
- vsprintf (Line2, MsgFmt, List);\r
- fprintf (stdout, ": %s", Line2);\r
- }\r
-\r
- fprintf (stdout, "\n");\r
-}\r
-\r
-void\r
-ParserSetPosition (\r
- CHAR8 *SourceFileName,\r
- UINT32 LineNum\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Set the position in a file being parsed. This can be used to \r
- print error messages deeper down in a parser.\r
-\r
-Arguments:\r
- SourceFileName - name of the source file being parsed\r
- LineNum - line number of the source file being parsed\r
-\r
-Returns:\r
- NA\r
-\r
---*/\r
-{\r
- mSourceFileName = SourceFileName;\r
- mSourceFileLineNum = LineNum;\r
-}\r
-\r
-void\r
-SetUtilityName (\r
- CHAR8 *UtilityName\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- All printed error/warning/debug messages follow the same format, and\r
- typically will print a filename or utility name followed by the error\r
- text. However if a filename is not passed to the print routines, then\r
- they'll print the utility name if you call this function early in your\r
- app to set the utility name.\r
- \r
-Arguments:\r
- UtilityName - name of the utility, which will be printed with all\r
- error/warning/debug messags.\r
-\r
-Returns:\r
- NA\r
- \r
---*/\r
-{\r
- //\r
- // Save the name of the utility in our local variable. Make sure its\r
- // length does not exceed our buffer.\r
- //\r
- if (UtilityName != NULL) {\r
- if (strlen (UtilityName) >= sizeof (mUtilityName)) {\r
- Error (UtilityName, 0, 0, "application error", "utility name length exceeds internal buffer size");\r
- strncpy (mUtilityName, UtilityName, sizeof (mUtilityName) - 1);\r
- mUtilityName[sizeof (mUtilityName) - 1] = 0;\r
- return ;\r
- } else {\r
- strcpy (mUtilityName, UtilityName);\r
- }\r
- } else {\r
- Error (NULL, 0, 0, "application error", "SetUtilityName() called with NULL utility name");\r
- }\r
-}\r
-\r
-STATUS\r
-GetUtilityStatus (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- When you call Error() or Warning(), this module keeps track of it and\r
- sets a local mStatus to STATUS_ERROR or STATUS_WARNING. When the utility\r
- exits, it can call this function to get the status and use it as a return\r
- value.\r
- \r
-Arguments:\r
- None.\r
-\r
-Returns:\r
- Worst-case status reported, as defined by which print function was called.\r
- \r
---*/\r
-{\r
- return mStatus;\r
-}\r
-\r
-void\r
-SetDebugMsgMask (\r
- UINT32 DebugMask\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Set the debug printing mask. This is used by the DebugMsg() function\r
- to determine when/if a debug message should be printed.\r
-\r
-Arguments:\r
- DebugMask - bitmask, specific to the calling application\r
-\r
-Returns:\r
- NA\r
-\r
---*/\r
-{\r
- mDebugMsgMask = DebugMask;\r
-}\r
-\r
-void\r
-SetPrintLimits (\r
- UINT32 MaxErrors,\r
- UINT32 MaxWarnings,\r
- UINT32 MaxWarningsPlusErrors\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Set the limits of how many errors, warnings, and errors+warnings\r
- we will print.\r
-\r
-Arguments:\r
- MaxErrors - maximum number of error messages to print\r
- MaxWarnings - maximum number of warning messages to print\r
- MaxWarningsPlusErrors \r
- - maximum number of errors+warnings to print\r
-\r
-Returns:\r
- NA\r
-\r
---*/\r
-{\r
- mMaxErrors = MaxErrors;\r
- mMaxWarnings = MaxWarnings;\r
- mMaxWarningsPlusErrors = MaxWarningsPlusErrors;\r
- mPrintLimitsSet = 1;\r
-}\r
-\r
-static\r
-void\r
-PrintLimitExceeded (\r
- VOID\r
- )\r
-{\r
- static INT8 mPrintLimitExceeded = 0;\r
- //\r
- // If we've already printed the message, do nothing. Otherwise\r
- // temporarily increase our print limits so we can pass one\r
- // more message through.\r
- //\r
- if (mPrintLimitExceeded == 0) {\r
- mPrintLimitExceeded++;\r
- mMaxErrors++;\r
- mMaxWarnings++;\r
- mMaxWarningsPlusErrors++;\r
- Error (NULL, 0, 0, "error/warning print limit exceeded", NULL);\r
- mMaxErrors--;\r
- mMaxWarnings--;\r
- mMaxWarningsPlusErrors--;\r
- }\r
-}\r
-\r
-#if 0\r
-void\r
-TestUtilityMessages (\r
- VOID\r
- )\r
-{\r
- char *ArgStr = "ArgString";\r
- int ArgInt;\r
-\r
- ArgInt = 0x12345678;\r
- //\r
- // Test without setting utility name\r
- //\r
- fprintf (stdout, "* Testing without setting utility name\n");\r
- fprintf (stdout, "** Test debug message not printed\n");\r
- DebugMsg (NULL, 0, 0x00000001, NULL, NULL);\r
- fprintf (stdout, "** Test warning with two strings and two args\n");\r
- Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);\r
- fprintf (stdout, "** Test error with two strings and two args\n");\r
- Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);\r
- fprintf (stdout, "** Test parser warning with nothing\n");\r
- ParserWarning (0, NULL, NULL);\r
- fprintf (stdout, "** Test parser error with nothing\n");\r
- ParserError (0, NULL, NULL);\r
- //\r
- // Test with utility name set now\r
- //\r
- fprintf (stdout, "** Testingin with utility name set\n");\r
- SetUtilityName ("MyUtilityName");\r
- //\r
- // Test debug prints\r
- //\r
- SetDebugMsgMask (2);\r
- fprintf (stdout, "** Test debug message with one string\n");\r
- DebugMsg (NULL, 0, 0x00000002, "Text1", NULL);\r
- fprintf (stdout, "** Test debug message with one string\n");\r
- DebugMsg (NULL, 0, 0x00000002, NULL, "Text2");\r
- fprintf (stdout, "** Test debug message with two strings\n");\r
- DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2");\r
- fprintf (stdout, "** Test debug message with two strings and two args\n");\r
- DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);\r
- //\r
- // Test warning prints\r
- //\r
- fprintf (stdout, "** Test warning with no strings\n");\r
- Warning (NULL, 0, 1234, NULL, NULL);\r
- fprintf (stdout, "** Test warning with one string\n");\r
- Warning (NULL, 0, 1234, "Text1", NULL);\r
- fprintf (stdout, "** Test warning with one string\n");\r
- Warning (NULL, 0, 1234, NULL, "Text2");\r
- fprintf (stdout, "** Test warning with two strings and two args\n");\r
- Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);\r
- //\r
- // Test error prints\r
- //\r
- fprintf (stdout, "** Test error with no strings\n");\r
- Error (NULL, 0, 1234, NULL, NULL);\r
- fprintf (stdout, "** Test error with one string\n");\r
- Error (NULL, 0, 1234, "Text1", NULL);\r
- fprintf (stdout, "** Test error with one string\n");\r
- Error (NULL, 0, 1234, NULL, "Text2");\r
- fprintf (stdout, "** Test error with two strings and two args\n");\r
- Error (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);\r
- //\r
- // Test parser prints\r
- //\r
- fprintf (stdout, "** Test parser errors\n");\r
- ParserSetPosition (__FILE__, __LINE__ + 1);\r
- ParserError (1234, NULL, NULL);\r
- ParserSetPosition (__FILE__, __LINE__ + 1);\r
- ParserError (1234, "Text1", NULL);\r
- ParserSetPosition (__FILE__, __LINE__ + 1);\r
- ParserError (1234, NULL, "Text2");\r
- ParserSetPosition (__FILE__, __LINE__ + 1);\r
- ParserError (1234, "Text1", "Text2");\r
- ParserSetPosition (__FILE__, __LINE__ + 1);\r
- ParserError (1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);\r
-\r
- fprintf (stdout, "** Test parser warnings\n");\r
- ParserSetPosition (__FILE__, __LINE__ + 1);\r
- ParserWarning (4321, NULL, NULL);\r
- ParserSetPosition (__FILE__, __LINE__ + 1);\r
- ParserWarning (4321, "Text1", NULL);\r
- ParserSetPosition (__FILE__, __LINE__ + 1);\r
- ParserWarning (4321, NULL, "Text2");\r
- ParserSetPosition (__FILE__, __LINE__ + 1);\r
- ParserWarning (4321, "Text1", "Text2");\r
- ParserSetPosition (__FILE__, __LINE__ + 1);\r
- ParserWarning (4321, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);\r
-}\r
-#endif\r