1 /** @file 2 EFI tools utility functions to display warning, error, and informational messages 3 4 Copyright (c) 2004 - 2016, 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 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 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 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 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 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 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 if (NewTime != NULL) { 455 fprintf (stdout, "%04d-%02d-%02d %02d:%02d:%02d", 456 NewTime->tm_year + 1900, 457 NewTime->tm_mon + 1, 458 NewTime->tm_mday, 459 NewTime->tm_hour, 460 NewTime->tm_min, 461 NewTime->tm_sec 462 ); 463 } 464 if (Cptr != NULL) { 465 sprintf (Line, ": %s", Cptr); 466 if (LineNumber != 0) { 467 sprintf (Line2, "(%u)", (unsigned) LineNumber); 468 strcat (Line, Line2); 469 } 470 } 471 } else { 472 // 473 // Error and Warning Information. 474 // 475 if (Cptr != NULL) { 476 if (mUtilityName[0] != '\0') { 477 fprintf (stdout, "%s...\n", mUtilityName); 478 } 479 sprintf (Line, "%s", Cptr); 480 if (LineNumber != 0) { 481 sprintf (Line2, "(%u)", (unsigned) LineNumber); 482 strcat (Line, Line2); 483 } 484 } else { 485 if (mUtilityName[0] != '\0') { 486 sprintf (Line, "%s", mUtilityName); 487 } 488 } 489 490 if (strcmp (Type, "ERROR") == 0) { 491 // 492 // Set status accordingly for ERROR information. 493 // 494 if (mStatus < STATUS_ERROR) { 495 mStatus = STATUS_ERROR; 496 } 497 } 498 } 499 500 // 501 // Have to print an error code or Visual Studio won't find the 502 // message for you. It has to be decimal digits too. 503 // 504 if (MessageCode != 0) { 505 sprintf (Line2, ": %s %04u", Type, (unsigned) MessageCode); 506 } else { 507 sprintf (Line2, ": %s", Type); 508 } 509 strcat (Line, Line2); 510 fprintf (stdout, "%s", Line); 511 // 512 // If offending text was provided, then print it 513 // 514 if (Text != NULL) { 515 fprintf (stdout, ": %s", Text); 516 } 517 fprintf (stdout, "\n"); 518 519 // 520 // Print formatted message if provided 521 // 522 if (MsgFmt != NULL) { 523 vsprintf (Line2, MsgFmt, List); 524 fprintf (stdout, " %s\n", Line2); 525 } 526 527 } 528 529 STATIC 530 VOID 531 PrintSimpleMessage ( 532 CHAR8 *MsgFmt, 533 va_list List 534 ) 535 /*++ 536 Routine Description: 537 Print message into stdout. 538 539 Arguments: 540 MsgFmt - the format string for the message. Can contain formatting 541 controls for use with varargs. 542 List - the variable list. 543 544 Returns: 545 None. 546 --*/ 547 { 548 CHAR8 Line[MAX_LINE_LEN]; 549 // 550 // Print formatted message if provided 551 // 552 if (MsgFmt != NULL) { 553 vsprintf (Line, MsgFmt, List); 554 fprintf (stdout, "%s\n", Line); 555 } 556 } 557 558 VOID 559 ParserSetPosition ( 560 CHAR8 *SourceFileName, 561 UINT32 LineNum 562 ) 563 /*++ 564 565 Routine Description: 566 Set the position in a file being parsed. This can be used to 567 print error messages deeper down in a parser. 568 569 Arguments: 570 SourceFileName - name of the source file being parsed 571 LineNum - line number of the source file being parsed 572 573 Returns: 574 NA 575 576 --*/ 577 { 578 mSourceFileName = SourceFileName; 579 mSourceFileLineNum = LineNum; 580 } 581 582 VOID 583 SetUtilityName ( 584 CHAR8 *UtilityName 585 ) 586 /*++ 587 588 Routine Description: 589 All printed error/warning/debug messages follow the same format, and 590 typically will print a filename or utility name followed by the error 591 text. However if a filename is not passed to the print routines, then 592 they'll print the utility name if you call this function early in your 593 app to set the utility name. 594 595 Arguments: 596 UtilityName - name of the utility, which will be printed with all 597 error/warning/debug messags. 598 599 Returns: 600 NA 601 602 --*/ 603 { 604 // 605 // Save the name of the utility in our local variable. Make sure its 606 // length does not exceed our buffer. 607 // 608 if (UtilityName != NULL) { 609 if (strlen (UtilityName) >= sizeof (mUtilityName)) { 610 Error (UtilityName, 0, 0, "application error", "utility name length exceeds internal buffer size"); 611 strncpy (mUtilityName, UtilityName, sizeof (mUtilityName) - 1); 612 mUtilityName[sizeof (mUtilityName) - 1] = 0; 613 return ; 614 } else { 615 strcpy (mUtilityName, UtilityName); 616 } 617 } else { 618 Error (NULL, 0, 0, "application error", "SetUtilityName() called with NULL utility name"); 619 } 620 } 621 622 STATUS 623 GetUtilityStatus ( 624 VOID 625 ) 626 /*++ 627 628 Routine Description: 629 When you call Error() or Warning(), this module keeps track of it and 630 sets a local mStatus to STATUS_ERROR or STATUS_WARNING. When the utility 631 exits, it can call this function to get the status and use it as a return 632 value. 633 634 Arguments: 635 None. 636 637 Returns: 638 Worst-case status reported, as defined by which print function was called. 639 640 --*/ 641 { 642 return mStatus; 643 } 644 645 VOID 646 SetPrintLevel ( 647 UINT64 LogLevel 648 ) 649 /*++ 650 651 Routine Description: 652 Set the printing message Level. This is used by the PrintMsg() function 653 to determine when/if a message should be printed. 654 655 Arguments: 656 LogLevel - 0~50 to specify the different level message. 657 658 Returns: 659 NA 660 661 --*/ 662 { 663 mPrintLogLevel = LogLevel; 664 } 665 666 VOID 667 VerboseMsg ( 668 CHAR8 *MsgFmt, 669 ... 670 ) 671 /*++ 672 673 Routine Description: 674 Print a verbose level message. 675 676 Arguments: 677 MsgFmt - the format string for the message. Can contain formatting 678 controls for use with varargs. 679 List - the variable list. 680 681 Returns: 682 NA 683 684 --*/ 685 { 686 va_list List; 687 // 688 // If the debug level is less than current print level, then do nothing. 689 // 690 if (VERBOSE_LOG_LEVEL < mPrintLogLevel) { 691 return ; 692 } 693 694 va_start (List, MsgFmt); 695 PrintSimpleMessage (MsgFmt, List); 696 va_end (List); 697 } 698 699 VOID 700 NormalMsg ( 701 CHAR8 *MsgFmt, 702 ... 703 ) 704 /*++ 705 706 Routine Description: 707 Print a default level message. 708 709 Arguments: 710 MsgFmt - the format string for the message. Can contain formatting 711 controls for use with varargs. 712 List - the variable list. 713 714 Returns: 715 NA 716 717 --*/ 718 { 719 va_list List; 720 // 721 // If the debug level is less than current print level, then do nothing. 722 // 723 if (INFO_LOG_LEVEL < mPrintLogLevel) { 724 return ; 725 } 726 727 va_start (List, MsgFmt); 728 PrintSimpleMessage (MsgFmt, List); 729 va_end (List); 730 } 731 732 VOID 733 KeyMsg ( 734 CHAR8 *MsgFmt, 735 ... 736 ) 737 /*++ 738 739 Routine Description: 740 Print a key level message. 741 742 Arguments: 743 MsgFmt - the format string for the message. Can contain formatting 744 controls for use with varargs. 745 List - the variable list. 746 747 Returns: 748 NA 749 750 --*/ 751 { 752 va_list List; 753 // 754 // If the debug level is less than current print level, then do nothing. 755 // 756 if (KEY_LOG_LEVEL < mPrintLogLevel) { 757 return ; 758 } 759 760 va_start (List, MsgFmt); 761 PrintSimpleMessage (MsgFmt, List); 762 va_end (List); 763 } 764 765 VOID 766 SetPrintLimits ( 767 UINT32 MaxErrors, 768 UINT32 MaxWarnings, 769 UINT32 MaxWarningsPlusErrors 770 ) 771 /*++ 772 773 Routine Description: 774 Set the limits of how many errors, warnings, and errors+warnings 775 we will print. 776 777 Arguments: 778 MaxErrors - maximum number of error messages to print 779 MaxWarnings - maximum number of warning messages to print 780 MaxWarningsPlusErrors 781 - maximum number of errors+warnings to print 782 783 Returns: 784 NA 785 786 --*/ 787 { 788 mMaxErrors = MaxErrors; 789 mMaxWarnings = MaxWarnings; 790 mMaxWarningsPlusErrors = MaxWarningsPlusErrors; 791 mPrintLimitsSet = 1; 792 } 793 794 STATIC 795 VOID 796 PrintLimitExceeded ( 797 VOID 798 ) 799 { 800 STATIC INT8 mPrintLimitExceeded = 0; 801 // 802 // If we've already printed the message, do nothing. Otherwise 803 // temporarily increase our print limits so we can pass one 804 // more message through. 805 // 806 if (mPrintLimitExceeded == 0) { 807 mPrintLimitExceeded++; 808 mMaxErrors++; 809 mMaxWarnings++; 810 mMaxWarningsPlusErrors++; 811 Error (NULL, 0, 0, "error/warning print limit exceeded", NULL); 812 mMaxErrors--; 813 mMaxWarnings--; 814 mMaxWarningsPlusErrors--; 815 } 816 } 817 818 #if 0 819 VOID 820 TestUtilityMessages ( 821 VOID 822 ) 823 { 824 CHAR8 *ArgStr = "ArgString"; 825 int ArgInt; 826 827 ArgInt = 0x12345678; 828 // 829 // Test without setting utility name 830 // 831 fprintf (stdout, "* Testing without setting utility name\n"); 832 fprintf (stdout, "** Test debug message not printed\n"); 833 DebugMsg (NULL, 0, 0x00000001, NULL, NULL); 834 fprintf (stdout, "** Test warning with two strings and two args\n"); 835 Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt); 836 fprintf (stdout, "** Test error with two strings and two args\n"); 837 Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt); 838 fprintf (stdout, "** Test parser warning with nothing\n"); 839 ParserWarning (0, NULL, NULL); 840 fprintf (stdout, "** Test parser error with nothing\n"); 841 ParserError (0, NULL, NULL); 842 // 843 // Test with utility name set now 844 // 845 fprintf (stdout, "** Testingin with utility name set\n"); 846 SetUtilityName ("MyUtilityName"); 847 // 848 // Test debug prints 849 // 850 SetDebugMsgMask (2); 851 fprintf (stdout, "** Test debug message with one string\n"); 852 DebugMsg (NULL, 0, 0x00000002, "Text1", NULL); 853 fprintf (stdout, "** Test debug message with one string\n"); 854 DebugMsg (NULL, 0, 0x00000002, NULL, "Text2"); 855 fprintf (stdout, "** Test debug message with two strings\n"); 856 DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2"); 857 fprintf (stdout, "** Test debug message with two strings and two args\n"); 858 DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt); 859 // 860 // Test warning prints 861 // 862 fprintf (stdout, "** Test warning with no strings\n"); 863 Warning (NULL, 0, 1234, NULL, NULL); 864 fprintf (stdout, "** Test warning with one string\n"); 865 Warning (NULL, 0, 1234, "Text1", NULL); 866 fprintf (stdout, "** Test warning with one string\n"); 867 Warning (NULL, 0, 1234, NULL, "Text2"); 868 fprintf (stdout, "** Test warning with two strings and two args\n"); 869 Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt); 870 // 871 // Test error prints 872 // 873 fprintf (stdout, "** Test error with no strings\n"); 874 Error (NULL, 0, 1234, NULL, NULL); 875 fprintf (stdout, "** Test error with one string\n"); 876 Error (NULL, 0, 1234, "Text1", NULL); 877 fprintf (stdout, "** Test error with one string\n"); 878 Error (NULL, 0, 1234, NULL, "Text2"); 879 fprintf (stdout, "** Test error with two strings and two args\n"); 880 Error (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt); 881 // 882 // Test parser prints 883 // 884 fprintf (stdout, "** Test parser errors\n"); 885 ParserSetPosition (__FILE__, __LINE__ + 1); 886 ParserError (1234, NULL, NULL); 887 ParserSetPosition (__FILE__, __LINE__ + 1); 888 ParserError (1234, "Text1", NULL); 889 ParserSetPosition (__FILE__, __LINE__ + 1); 890 ParserError (1234, NULL, "Text2"); 891 ParserSetPosition (__FILE__, __LINE__ + 1); 892 ParserError (1234, "Text1", "Text2"); 893 ParserSetPosition (__FILE__, __LINE__ + 1); 894 ParserError (1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt); 895 896 fprintf (stdout, "** Test parser warnings\n"); 897 ParserSetPosition (__FILE__, __LINE__ + 1); 898 ParserWarning (4321, NULL, NULL); 899 ParserSetPosition (__FILE__, __LINE__ + 1); 900 ParserWarning (4321, "Text1", NULL); 901 ParserSetPosition (__FILE__, __LINE__ + 1); 902 ParserWarning (4321, NULL, "Text2"); 903 ParserSetPosition (__FILE__, __LINE__ + 1); 904 ParserWarning (4321, "Text1", "Text2"); 905 ParserSetPosition (__FILE__, __LINE__ + 1); 906 ParserWarning (4321, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt); 907 } 908 #endif 909