--- /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
+ UtilsMsgs.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 <Common/UefiBaseTypes.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 INT8 mUtilityName[50] = { 0 };\r
+static INT8 *mSourceFileName = NULL;\r
+static UINT32 mSourceFileLineNum = 0;\r
+static UINT32 mErrorCount = 0;\r
+static UINT32 mWarningCount = 0;\r
+static UINT32 mDebugMsgMask = 0;\r
+\r
+static\r
+void\r
+PrintMessage (\r
+ INT8 *Type,\r
+ INT8 *FileName,\r
+ UINT32 LineNumber,\r
+ UINT32 MessageCode,\r
+ INT8 *Text,\r
+ INT8 *MsgFmt,\r
+ va_list List\r
+ );\r
+\r
+void\r
+Error (\r
+ INT8 *FileName,\r
+ UINT32 LineNumber,\r
+ UINT32 MessageCode,\r
+ INT8 *Text,\r
+ INT8 *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
+ 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
+ INT8 *Text,\r
+ INT8 *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
+\r
+Returns:\r
+ NA\r
+\r
+--*/\r
+{\r
+ va_list List;\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
+ INT8 *OffendingText,\r
+ INT8 *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
+\r
+Returns:\r
+ NA\r
+\r
+--*/\r
+{\r
+ va_list List;\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
+ INT8 *FileName,\r
+ UINT32 LineNumber,\r
+ UINT32 MessageCode,\r
+ INT8 *Text,\r
+ INT8 *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
+ ...\r
+ \r
+Returns:\r
+ None.\r
+\r
+--*/\r
+{\r
+ va_list List;\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
+ INT8 *FileName,\r
+ UINT32 LineNumber,\r
+ UINT32 MsgMask,\r
+ INT8 *Text,\r
+ INT8 *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
+ ... \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
+ INT8 *Type,\r
+ INT8 *FileName,\r
+ UINT32 LineNumber,\r
+ UINT32 MessageCode,\r
+ INT8 *Text,\r
+ INT8 *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
+\r
+ List - Variable function parameter list. \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
+ INT8 Line[MAX_LINE_LEN];\r
+ INT8 Line2[MAX_LINE_LEN];\r
+ INT8 *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
+ INT8 *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
+ INT8 *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