]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/Common/EfiUtilityMsgs.c
BaseTools/C/Common: Add/refine boundary checks for strcpy/strcat calls
[mirror_edk2.git] / BaseTools / Source / C / Common / EfiUtilityMsgs.c
1 /** @file
2 EFI tools utility functions to display warning, error, and informational messages
3
4 Copyright (c) 2004 - 2017, 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 }
612 strncpy (mUtilityName, UtilityName, sizeof (mUtilityName) - 1);
613 mUtilityName[sizeof (mUtilityName) - 1] = 0;
614 } else {
615 Error (NULL, 0, 0, "application error", "SetUtilityName() called with NULL utility name");
616 }
617 }
618
619 STATUS
620 GetUtilityStatus (
621 VOID
622 )
623 /*++
624
625 Routine Description:
626 When you call Error() or Warning(), this module keeps track of it and
627 sets a local mStatus to STATUS_ERROR or STATUS_WARNING. When the utility
628 exits, it can call this function to get the status and use it as a return
629 value.
630
631 Arguments:
632 None.
633
634 Returns:
635 Worst-case status reported, as defined by which print function was called.
636
637 --*/
638 {
639 return mStatus;
640 }
641
642 VOID
643 SetPrintLevel (
644 UINT64 LogLevel
645 )
646 /*++
647
648 Routine Description:
649 Set the printing message Level. This is used by the PrintMsg() function
650 to determine when/if a message should be printed.
651
652 Arguments:
653 LogLevel - 0~50 to specify the different level message.
654
655 Returns:
656 NA
657
658 --*/
659 {
660 mPrintLogLevel = LogLevel;
661 }
662
663 VOID
664 VerboseMsg (
665 CHAR8 *MsgFmt,
666 ...
667 )
668 /*++
669
670 Routine Description:
671 Print a verbose level message.
672
673 Arguments:
674 MsgFmt - the format string for the message. Can contain formatting
675 controls for use with varargs.
676 List - the variable list.
677
678 Returns:
679 NA
680
681 --*/
682 {
683 va_list List;
684 //
685 // If the debug level is less than current print level, then do nothing.
686 //
687 if (VERBOSE_LOG_LEVEL < mPrintLogLevel) {
688 return ;
689 }
690
691 va_start (List, MsgFmt);
692 PrintSimpleMessage (MsgFmt, List);
693 va_end (List);
694 }
695
696 VOID
697 NormalMsg (
698 CHAR8 *MsgFmt,
699 ...
700 )
701 /*++
702
703 Routine Description:
704 Print a default level message.
705
706 Arguments:
707 MsgFmt - the format string for the message. Can contain formatting
708 controls for use with varargs.
709 List - the variable list.
710
711 Returns:
712 NA
713
714 --*/
715 {
716 va_list List;
717 //
718 // If the debug level is less than current print level, then do nothing.
719 //
720 if (INFO_LOG_LEVEL < mPrintLogLevel) {
721 return ;
722 }
723
724 va_start (List, MsgFmt);
725 PrintSimpleMessage (MsgFmt, List);
726 va_end (List);
727 }
728
729 VOID
730 KeyMsg (
731 CHAR8 *MsgFmt,
732 ...
733 )
734 /*++
735
736 Routine Description:
737 Print a key level message.
738
739 Arguments:
740 MsgFmt - the format string for the message. Can contain formatting
741 controls for use with varargs.
742 List - the variable list.
743
744 Returns:
745 NA
746
747 --*/
748 {
749 va_list List;
750 //
751 // If the debug level is less than current print level, then do nothing.
752 //
753 if (KEY_LOG_LEVEL < mPrintLogLevel) {
754 return ;
755 }
756
757 va_start (List, MsgFmt);
758 PrintSimpleMessage (MsgFmt, List);
759 va_end (List);
760 }
761
762 VOID
763 SetPrintLimits (
764 UINT32 MaxErrors,
765 UINT32 MaxWarnings,
766 UINT32 MaxWarningsPlusErrors
767 )
768 /*++
769
770 Routine Description:
771 Set the limits of how many errors, warnings, and errors+warnings
772 we will print.
773
774 Arguments:
775 MaxErrors - maximum number of error messages to print
776 MaxWarnings - maximum number of warning messages to print
777 MaxWarningsPlusErrors
778 - maximum number of errors+warnings to print
779
780 Returns:
781 NA
782
783 --*/
784 {
785 mMaxErrors = MaxErrors;
786 mMaxWarnings = MaxWarnings;
787 mMaxWarningsPlusErrors = MaxWarningsPlusErrors;
788 mPrintLimitsSet = 1;
789 }
790
791 STATIC
792 VOID
793 PrintLimitExceeded (
794 VOID
795 )
796 {
797 STATIC INT8 mPrintLimitExceeded = 0;
798 //
799 // If we've already printed the message, do nothing. Otherwise
800 // temporarily increase our print limits so we can pass one
801 // more message through.
802 //
803 if (mPrintLimitExceeded == 0) {
804 mPrintLimitExceeded++;
805 mMaxErrors++;
806 mMaxWarnings++;
807 mMaxWarningsPlusErrors++;
808 Error (NULL, 0, 0, "error/warning print limit exceeded", NULL);
809 mMaxErrors--;
810 mMaxWarnings--;
811 mMaxWarningsPlusErrors--;
812 }
813 }
814
815 #if 0
816 VOID
817 TestUtilityMessages (
818 VOID
819 )
820 {
821 CHAR8 *ArgStr = "ArgString";
822 int ArgInt;
823
824 ArgInt = 0x12345678;
825 //
826 // Test without setting utility name
827 //
828 fprintf (stdout, "* Testing without setting utility name\n");
829 fprintf (stdout, "** Test debug message not printed\n");
830 DebugMsg (NULL, 0, 0x00000001, NULL, NULL);
831 fprintf (stdout, "** Test warning with two strings and two args\n");
832 Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
833 fprintf (stdout, "** Test error with two strings and two args\n");
834 Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
835 fprintf (stdout, "** Test parser warning with nothing\n");
836 ParserWarning (0, NULL, NULL);
837 fprintf (stdout, "** Test parser error with nothing\n");
838 ParserError (0, NULL, NULL);
839 //
840 // Test with utility name set now
841 //
842 fprintf (stdout, "** Testingin with utility name set\n");
843 SetUtilityName ("MyUtilityName");
844 //
845 // Test debug prints
846 //
847 SetDebugMsgMask (2);
848 fprintf (stdout, "** Test debug message with one string\n");
849 DebugMsg (NULL, 0, 0x00000002, "Text1", NULL);
850 fprintf (stdout, "** Test debug message with one string\n");
851 DebugMsg (NULL, 0, 0x00000002, NULL, "Text2");
852 fprintf (stdout, "** Test debug message with two strings\n");
853 DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2");
854 fprintf (stdout, "** Test debug message with two strings and two args\n");
855 DebugMsg (NULL, 0, 0x00000002, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
856 //
857 // Test warning prints
858 //
859 fprintf (stdout, "** Test warning with no strings\n");
860 Warning (NULL, 0, 1234, NULL, NULL);
861 fprintf (stdout, "** Test warning with one string\n");
862 Warning (NULL, 0, 1234, "Text1", NULL);
863 fprintf (stdout, "** Test warning with one string\n");
864 Warning (NULL, 0, 1234, NULL, "Text2");
865 fprintf (stdout, "** Test warning with two strings and two args\n");
866 Warning (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
867 //
868 // Test error prints
869 //
870 fprintf (stdout, "** Test error with no strings\n");
871 Error (NULL, 0, 1234, NULL, NULL);
872 fprintf (stdout, "** Test error with one string\n");
873 Error (NULL, 0, 1234, "Text1", NULL);
874 fprintf (stdout, "** Test error with one string\n");
875 Error (NULL, 0, 1234, NULL, "Text2");
876 fprintf (stdout, "** Test error with two strings and two args\n");
877 Error (NULL, 0, 1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
878 //
879 // Test parser prints
880 //
881 fprintf (stdout, "** Test parser errors\n");
882 ParserSetPosition (__FILE__, __LINE__ + 1);
883 ParserError (1234, NULL, NULL);
884 ParserSetPosition (__FILE__, __LINE__ + 1);
885 ParserError (1234, "Text1", NULL);
886 ParserSetPosition (__FILE__, __LINE__ + 1);
887 ParserError (1234, NULL, "Text2");
888 ParserSetPosition (__FILE__, __LINE__ + 1);
889 ParserError (1234, "Text1", "Text2");
890 ParserSetPosition (__FILE__, __LINE__ + 1);
891 ParserError (1234, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
892
893 fprintf (stdout, "** Test parser warnings\n");
894 ParserSetPosition (__FILE__, __LINE__ + 1);
895 ParserWarning (4321, NULL, NULL);
896 ParserSetPosition (__FILE__, __LINE__ + 1);
897 ParserWarning (4321, "Text1", NULL);
898 ParserSetPosition (__FILE__, __LINE__ + 1);
899 ParserWarning (4321, NULL, "Text2");
900 ParserSetPosition (__FILE__, __LINE__ + 1);
901 ParserWarning (4321, "Text1", "Text2");
902 ParserSetPosition (__FILE__, __LINE__ + 1);
903 ParserWarning (4321, "Text1", "Text2 %s 0x%X", ArgStr, ArgInt);
904 }
905 #endif