]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/TianoTools/VfrCompile/VfrServices.cpp
Initial import.
[mirror_edk2.git] / Tools / Source / TianoTools / VfrCompile / VfrServices.cpp
1 /*++
2
3 Copyright (c) 2004 - 2005, Intel Corporation
4 All rights reserved. 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
8
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.
11
12 Module Name:
13
14 VfrServices.cpp
15
16 Abstract:
17
18 Support routines for the VFR compiler
19
20 --*/
21
22 #include <stdio.h> // for FILE routines
23 #include <stdlib.h> // for malloc() and free()
24
25 #include <Base.h>
26 #include <UefiBaseTypes.h>
27 #include <MultiPhase.h>
28 #include "EfiUtilityMsgs.h"
29 #include "EfiVfr.h"
30 #include "VfrServices.h"
31
32 #include <UgaDraw.h>
33 #include <Hii.h>
34
35 static const char *mSourceFileHeader[] = {
36 "//",
37 "// DO NOT EDIT -- auto-generated file",
38 "//",
39 "// This file is generated by the VFR compiler.",
40 "//",
41 NULL
42 };
43
44 typedef struct {
45 CHAR8 *Name;
46 INT32 Size;
47 } IFR_OPCODE_SIZES;
48
49 //
50 // Create a table that can be used to do internal checking on the IFR
51 // bytes we emit.
52 //
53 static const IFR_OPCODE_SIZES mOpcodeSizes[] = {
54 { 0, 0 }, // invalid
55 { "EFI_IFR_FORM", sizeof (EFI_IFR_FORM) },
56 { "EFI_IFR_SUBTITLE", sizeof (EFI_IFR_SUBTITLE) },
57 { "EFI_IFR_TEXT", -6 }, //sizeof (EFI_IFR_TEXT) },
58 { "unused 0x04 opcode", 0 }, // EFI_IFR_GRAPHIC_OP
59 { "EFI_IFR_ONE_OF", sizeof (EFI_IFR_ONE_OF) },
60 { "EFI_IFR_CHECKBOX", sizeof (EFI_IFR_CHECKBOX) },
61 { "EFI_IFR_NUMERIC", sizeof (EFI_IFR_NUMERIC) },
62 { "EFI_IFR_PASSWORD", sizeof (EFI_IFR_PASSWORD) },
63 { "EFI_IFR_ONE_OF_OPTION", sizeof (EFI_IFR_ONE_OF_OPTION) },
64 { "EFI_IFR_SUPPRESS", sizeof (EFI_IFR_SUPPRESS) },
65 { "EFI_IFR_END_FORM", sizeof (EFI_IFR_END_FORM) },
66 { "EFI_IFR_HIDDEN", sizeof (EFI_IFR_HIDDEN) },
67 { "EFI_IFR_END_FORM_SET", sizeof (EFI_IFR_END_FORM_SET) },
68 { "EFI_IFR_FORM_SET", sizeof (EFI_IFR_FORM_SET) },
69 { "EFI_IFR_REF", sizeof (EFI_IFR_REF) },
70 { "EFI_IFR_END_ONE_OF", sizeof (EFI_IFR_END_ONE_OF) },
71 { "EFI_IFR_INCONSISTENT", sizeof (EFI_IFR_INCONSISTENT) },
72 { "EFI_IFR_EQ_ID_VAL", sizeof (EFI_IFR_EQ_ID_VAL) },
73 { "EFI_IFR_EQ_ID_ID", sizeof (EFI_IFR_EQ_ID_ID) },
74 { "EFI_IFR_EQ_ID_LIST", -sizeof (EFI_IFR_EQ_ID_LIST) },
75 { "EFI_IFR_AND", sizeof (EFI_IFR_AND) },
76 { "EFI_IFR_OR", sizeof (EFI_IFR_OR) },
77 { "EFI_IFR_NOT", sizeof (EFI_IFR_NOT) },
78 { "EFI_IFR_END_EXPR", sizeof (EFI_IFR_END_EXPR) },
79 { "EFI_IFR_GRAY_OUT", sizeof (EFI_IFR_GRAY_OUT) },
80 { "EFI_IFR_DATE", sizeof (EFI_IFR_DATE) / 3 },
81 { "EFI_IFR_TIME", sizeof (EFI_IFR_TIME) / 3 },
82 { "EFI_IFR_STRING", sizeof (EFI_IFR_STRING) },
83 { "EFI_IFR_LABEL", sizeof (EFI_IFR_LABEL) },
84 { "EFI_IFR_SAVE_DEFAULTS", sizeof (EFI_IFR_SAVE_DEFAULTS) },
85 { "EFI_IFR_RESTORE_DEFAULTS", sizeof (EFI_IFR_RESTORE_DEFAULTS) },
86 { "EFI_IFR_BANNER", sizeof (EFI_IFR_BANNER) },
87 { "EFI_IFR_INVENTORY", sizeof (EFI_IFR_INVENTORY) },
88 { "EFI_IFR_EQ_VAR_VAL_OP", sizeof (EFI_IFR_EQ_VAR_VAL) },
89 { "EFI_IFR_ORDERED_LIST_OP", sizeof (EFI_IFR_ORDERED_LIST) },
90 { "EFI_IFR_VARSTORE_OP", -sizeof (EFI_IFR_VARSTORE) },
91 { "EFI_IFR_VARSTORE_SELECT_OP", sizeof (EFI_IFR_VARSTORE_SELECT) },
92 { "EFI_IFR_VARSTORE_SELECT_PAIR_OP", sizeof (EFI_IFR_VARSTORE_SELECT_PAIR) },
93 { "EFI_IFR_TRUE", sizeof (EFI_IFR_TRUE)},
94 { "EFI_IFR_FALSE", sizeof (EFI_IFR_FALSE)},
95 { "EFI_IFR_GT", sizeof (EFI_IFR_GT)},
96 { "EFI_IFR_GE", sizeof (EFI_IFR_GE)},
97 { "EFI_IFR_OEM_DEFINED_OP", -2 },
98 };
99
100
101 VfrOpcodeHandler::VfrOpcodeHandler (
102 )
103 /*++
104
105 Routine Description:
106 Constructor for the VFR opcode handling class.
107
108 Arguments:
109 None
110
111 Returns:
112 None
113
114 --*/
115 {
116 mIfrBytes = NULL;
117 mLastIfrByte = NULL;
118 mBytesWritten = 0;
119 mQueuedByteCount = 0;
120 mQueuedOpcodeByteValid = 0;
121 mPrimaryVarStoreId = 0;
122 mSecondaryVarStoreId = 0;
123 mSecondaryVarStoreIdSet = 0;
124 mPrimaryVarStoreIdSet = 0;
125 mDefaultVarStoreId = 0;
126 }
127
128 VOID
129 VfrOpcodeHandler::SetVarStoreId (
130 UINT16 VarStoreId
131 )
132 /*++
133
134 Routine Description:
135 This function is invoked by the parser when a variable is referenced in the
136 VFR. Save the variable store (and set a flag) so that we can later determine
137 if we need to emit a varstore-select or varstore-select-pair opcode.
138
139 Arguments:
140 VarStoreId - ID of the variable store referenced in the VFR
141
142 Returns:
143 None
144
145 --*/
146 {
147 mPrimaryVarStoreId = VarStoreId;
148 mPrimaryVarStoreIdSet = 1;
149 }
150
151 VOID
152 VfrOpcodeHandler::SetSecondaryVarStoreId (
153 UINT16 VarStoreId
154 )
155 /*++
156
157 Routine Description:
158 This function is invoked by the parser when a secondary variable is
159 referenced in the VFR. Save the variable store (and set a flag) so
160 that we can later determine if we need to emit a varstore-select or
161 varstore-pair opcode.
162
163 Arguments:
164 VarStoreId - ID of the variable store referenced in the VFR
165
166 Returns:
167 None
168
169 --*/
170 {
171 mSecondaryVarStoreId = VarStoreId;
172 mSecondaryVarStoreIdSet = 1;
173 }
174
175 VOID
176 VfrOpcodeHandler::WriteIfrBytes (
177 )
178 /*++
179
180 Routine Description:
181 This function is invoked at the end of parsing. Its purpose
182 is to write out all the IFR bytes that were queued up while
183 parsing.
184
185 Arguments:
186 None
187
188 Returns:
189 None
190
191 --*/
192 {
193 IFR_BYTE *Curr;
194 IFR_BYTE *Next;
195 UINT32 Count;
196 UINT32 LineCount;
197 UINT32 PoundLines;
198 UINT32 ByteCount;
199 CHAR8 Line[MAX_LINE_LEN];
200 CHAR8 *Cptr;
201 FILE *InFptr;
202 FILE *OutFptr;
203 UINT32 ListFile;
204 EFI_HII_IFR_PACK_HEADER IfrHeader;
205 UINT8 *Ptr;
206 FILE *IfrBinFptr;
207 UINT32 BytesLeftThisOpcode;
208 //
209 // If someone added a new opcode and didn't update our opcode sizes structure, error out.
210 //
211 if (sizeof(mOpcodeSizes) / sizeof (mOpcodeSizes[0]) != EFI_IFR_LAST_OPCODE + 1) {
212 Error (__FILE__, __LINE__, 0, "application error", "internal IFR binary table size is incorrect");
213 return;
214 }
215 //
216 // Flush the queue
217 //
218 FlushQueue ();
219 //
220 // If there have been any errors to this point, then skip dumping the IFR
221 // binary data. This way doing an nmake again will try to build it again, and
222 // the build will fail if they did not fix the problem.
223 //
224 if (GetUtilityStatus () != STATUS_ERROR) {
225 if ((IfrBinFptr = fopen (gOptions.IfrOutputFileName, "w")) == NULL) {
226 Error (PROGRAM_NAME, 0, 0, gOptions.IfrOutputFileName, "could not open file for writing");
227 return;
228 }
229 //
230 // Write the standard file header to the output file
231 //
232 WriteStandardFileHeader (IfrBinFptr);
233 //
234 // Write the structure header
235 //
236 fprintf (IfrBinFptr, "\nunsigned char %sBin[] = {", gOptions.VfrBaseFileName);
237 //
238 // Write the header
239 //
240 memset ((char *)&IfrHeader, 0, sizeof (IfrHeader));
241 IfrHeader.Header.Type = EFI_HII_IFR;
242 IfrHeader.Header.Length = mBytesWritten + sizeof (IfrHeader);
243 Ptr = (UINT8 *)&IfrHeader;
244 for (Count = 0; Count < sizeof (IfrHeader); Count++, Ptr++) {
245 if ((Count & 0x03) == 0) {
246 fprintf (IfrBinFptr, "\n ");
247 }
248 fprintf (IfrBinFptr, "0x%02X, ", *Ptr);
249 }
250 //
251 //
252 // Write all the IFR bytes
253 //
254 fprintf (IfrBinFptr, "\n // start of IFR data");
255 Curr = mIfrBytes;
256 Count = 0;
257 while (Curr != NULL) {
258 if ((Count & 0x0F) == 0) {
259 fprintf (IfrBinFptr, "\n ");
260 }
261 if (Curr->KeyByte != 0) {
262 fprintf (IfrBinFptr, "/*%c*/ ", Curr->KeyByte);
263 }
264 fprintf (IfrBinFptr, "0x%02X, ", Curr->OpcodeByte);
265 Count++;
266 Curr = Curr->Next;
267 }
268 fprintf (IfrBinFptr, "\n};\n\n");
269 //
270 //
271 // Close the file
272 //
273 fclose (IfrBinFptr);
274 IfrBinFptr = NULL;
275 }
276 //
277 // Write the bytes as binary data if the user specified to do so
278 //
279 if ((GetUtilityStatus () != STATUS_ERROR) && (gOptions.CreateIfrBinFile != 0)) {
280 //
281 // Use the Ifr output file name with a ".hpk" extension.
282 //
283 for (Cptr = gOptions.IfrOutputFileName + strlen (gOptions.IfrOutputFileName) - 1;
284 (*Cptr != '.') && (Cptr > gOptions.IfrOutputFileName) && (*Cptr != '\\');
285 Cptr--) {
286 //
287 // do nothing
288 //
289 }
290 if (*Cptr == '.') {
291 strcpy (Cptr, ".hpk");
292 } else {
293 strcat (gOptions.IfrOutputFileName, ".hpk");
294 }
295 if ((IfrBinFptr = fopen (gOptions.IfrOutputFileName, "wb")) == NULL) {
296 Error (PROGRAM_NAME, 0, 0, gOptions.IfrOutputFileName, "could not open file for writing");
297 return;
298 }
299 //
300 // Write the structure header
301 //
302 memset ((char *)&IfrHeader, 0, sizeof (IfrHeader));
303 IfrHeader.Header.Type = EFI_HII_IFR;
304 IfrHeader.Header.Length = mBytesWritten + sizeof (IfrHeader);
305 Ptr = (UINT8 *)&IfrHeader;
306 for (Count = 0; Count < sizeof (IfrHeader); Count++, Ptr++) {
307 fwrite (Ptr, 1, 1, IfrBinFptr);
308 }
309 //
310 //
311 // Write all the IFR bytes
312 //
313 Curr = mIfrBytes;
314 Count = 0;
315 while (Curr != NULL) {
316 fwrite (&Curr->OpcodeByte, 1, 1, IfrBinFptr);
317 Curr = Curr->Next;
318 }
319 //
320 //
321 // Close the file
322 //
323 fclose (IfrBinFptr);
324 IfrBinFptr = NULL;
325 }
326 //
327 // If creating a listing file, then open the input and output files
328 //
329 ListFile = 0;
330 if (gOptions.CreateListFile) {
331 //
332 // Open the input VFR file and the output list file
333 //
334 if ((InFptr = fopen (gOptions.PreprocessorOutputFileName, "r")) == NULL) {
335 Warning (PROGRAM_NAME, 0, 0, gOptions.PreprocessorOutputFileName, "could not open file for creating a list file");
336 } else {
337 if ((OutFptr = fopen (gOptions.VfrListFileName, "w")) == NULL) {
338 Warning (PROGRAM_NAME, 0, 0, gOptions.VfrListFileName, "could not open output list file for writing");
339 fclose (InFptr);
340 InFptr = NULL;
341 } else {
342 LineCount = 0;
343 ListFile = 1;
344 PoundLines = 0;
345 ByteCount = 0;
346 }
347 }
348 }
349 //
350 // Write the list file
351 //
352 if (ListFile) {
353 //
354 // Write out the VFR compiler version
355 //
356 fprintf (OutFptr, "//\n// VFR compiler version " VFR_COMPILER_VERSION "\n//\n");
357 Curr = mIfrBytes;
358 while (Curr != NULL) {
359 //
360 // Print lines until we reach the line of the current opcode
361 //
362 while (LineCount < PoundLines + Curr->LineNum) {
363 if (fgets (Line, sizeof (Line), InFptr) != NULL) {
364 //
365 // We should check for line length exceeded on the fgets(). Otherwise it
366 // throws the listing file output off. Future enhancement perhaps.
367 //
368 fprintf (OutFptr, "%s", Line);
369 if (strncmp (Line, "#line", 5) == 0) {
370 PoundLines++;
371 }
372 }
373 LineCount++;
374 }
375 //
376 // Print all opcodes with line numbers less than where we are now
377 //
378 BytesLeftThisOpcode = 0;
379 while ((Curr != NULL) && ((Curr->LineNum == 0) || (LineCount >= PoundLines + Curr->LineNum))) {
380 if (BytesLeftThisOpcode == 0) {
381 fprintf (OutFptr, ">%08X: ", ByteCount);
382 if (Curr->Next != NULL) {
383 BytesLeftThisOpcode = (UINT32)Curr->Next->OpcodeByte;
384 }
385 }
386 fprintf (OutFptr, "%02X ", (UINT32)Curr->OpcodeByte);
387 ByteCount++;
388 BytesLeftThisOpcode--;
389 if (BytesLeftThisOpcode == 0) {
390 fprintf (OutFptr, "\n");
391 }
392 Curr = Curr->Next;
393 }
394 }
395 //
396 // Dump any remaining lines from the input file
397 //
398 while (fgets (Line, sizeof (Line), InFptr) != NULL) {
399 fprintf (OutFptr, "%s", Line);
400 }
401 fclose (InFptr);
402 fclose (OutFptr);
403 }
404 //
405 // Debug code to make sure that each opcode we write out has as many
406 // bytes as the IFR structure requires. If there were errors, then
407 // don't do this step.
408 //
409 if (GetUtilityStatus () != STATUS_ERROR) {
410 Curr = mIfrBytes;
411 ByteCount = 0;
412 while (Curr != NULL) {
413 //
414 // First byte is the opcode, second byte is the length
415 //
416 if (Curr->Next == NULL) {
417 Error (__FILE__, __LINE__, 0, "application error", "last opcode written does not contain a length byte");
418 break;
419 }
420 Count = (UINT32)Curr->Next->OpcodeByte;
421 if (Count == 0) {
422 Error (
423 __FILE__,
424 __LINE__,
425 0,
426 "application error",
427 "opcode with 0 length specified in output at offset 0x%X",
428 ByteCount
429 );
430 break;
431 }
432 //
433 // Check the length
434 //
435 if ((Curr->OpcodeByte > EFI_IFR_LAST_OPCODE) || (Curr->OpcodeByte == 0)) {
436 Error (
437 __FILE__,
438 __LINE__,
439 0,
440 "application error",
441 "invalid opcode 0x%X in output at offset 0x%X",
442 (UINT32) Curr->OpcodeByte, ByteCount
443 );
444 } else if (mOpcodeSizes[Curr->OpcodeByte].Size < 0) {
445 //
446 // For those cases where the length is variable, the size is negative, and indicates
447 // the miniumum size.
448 //
449 if ((mOpcodeSizes[Curr->OpcodeByte].Size * -1) > Count) {
450 Error (
451 __FILE__,
452 __LINE__,
453 0,
454 "application error",
455 "insufficient number of bytes written for %s at offset 0x%X",
456 mOpcodeSizes[Curr->OpcodeByte].Name,
457 ByteCount
458 );
459 }
460 } else {
461 //
462 // Check for gaps
463 //
464 if (mOpcodeSizes[Curr->OpcodeByte].Size == 0) {
465 Error (
466 __FILE__,
467 __LINE__,
468 0,
469 "application error",
470 "invalid opcode 0x%X in output at offset 0x%X",
471 (UINT32)Curr->OpcodeByte,
472 ByteCount
473 );
474 } else {
475 //
476 // Check size
477 //
478 if (mOpcodeSizes[Curr->OpcodeByte].Size != Count) {
479 Error (
480 __FILE__,
481 __LINE__,
482 0,
483 "application error",
484 "invalid number of bytes (%d written s/b %d) written for %s at offset 0x%X",
485 Count,
486 mOpcodeSizes[Curr->OpcodeByte].Size,
487 mOpcodeSizes[Curr->OpcodeByte].Name,
488 ByteCount
489 );
490 }
491 }
492 }
493 //
494 // Skip to next opcode
495 //
496 while (Count > 0) {
497 ByteCount++;
498 if (Curr == NULL) {
499 Error (__FILE__, __LINE__, 0, "application error", "last opcode written has invalid length");
500 break;
501 }
502 Curr = Curr->Next;
503 Count--;
504 }
505 }
506 }
507 }
508
509 VfrOpcodeHandler::~VfrOpcodeHandler(
510 )
511 /*++
512
513 Routine Description:
514 Destructor for the VFR opcode handler. Free up memory allocated
515 while parsing the VFR script.
516
517 Arguments:
518 None
519
520 Returns:
521 None
522
523 --*/
524 {
525 IFR_BYTE *Curr;
526 IFR_BYTE *Next;
527 //
528 // Free up the IFR bytes
529 //
530 Curr = mIfrBytes;
531 while (Curr != NULL) {
532 Next = Curr->Next;
533 free (Curr);
534 Curr = Next;
535 }
536 }
537
538 int
539 VfrOpcodeHandler::AddOpcodeByte (
540 UINT8 OpcodeByte,
541 UINT32 LineNum
542 )
543 /*++
544
545 Routine Description:
546 This function is invoked by the parser when a new IFR
547 opcode should be emitted.
548
549 Arguments:
550 OpcodeByte - the IFR opcode
551 LineNum - the line number from the source file that resulted
552 in the opcode being emitted.
553
554 Returns:
555 0 always
556
557 --*/
558 {
559 UINT32 Count;
560
561 FlushQueue();
562 //
563 // Now add this new byte
564 //
565 mQueuedOpcodeByte = OpcodeByte;
566 mQueuedLineNum = LineNum;
567 mQueuedOpcodeByteValid = 1;
568 return 0;
569 }
570
571 VOID
572 VfrOpcodeHandler::AddByte (
573 UINT8 ByteVal,
574 UINT8 KeyByte
575 )
576 /*++
577
578 Routine Description:
579 This function is invoked by the parser when it determines
580 that more raw IFR bytes should be emitted to the output stream.
581 Here we just queue them up into an output buffer.
582
583 Arguments:
584 ByteVal - the raw byte to emit to the output IFR stream
585 KeyByte - a value that can be used for debug.
586
587 Returns:
588 None
589
590 --*/
591 {
592 //
593 // Check for buffer overflow
594 //
595 if (mQueuedByteCount > MAX_QUEUE_COUNT) {
596 Error (PROGRAM_NAME, 0, 0, NULL, "opcode queue overflow");
597 } else {
598 mQueuedBytes[mQueuedByteCount] = ByteVal;
599 mQueuedKeyBytes[mQueuedByteCount] = KeyByte;
600 mQueuedByteCount++;
601 }
602 }
603
604 int
605 VfrOpcodeHandler::FlushQueue (
606 )
607 /*++
608
609 Routine Description:
610 This function is invoked to flush the internal IFR buffer.
611
612 Arguments:
613 None
614
615 Returns:
616 0 always
617
618 --*/
619 {
620 UINT32 Count;
621 UINT32 EmitNoneOnePair;
622
623 EmitNoneOnePair = 0;
624 //
625 // If the secondary varstore was specified, then we have to emit
626 // a varstore-select-pair opcode, which only applies to the following
627 // statement.
628 //
629 if (mSecondaryVarStoreIdSet) {
630 mSecondaryVarStoreIdSet = 0;
631 //
632 // If primary and secondary are the same as the current default
633 // varstore, then we don't have to do anything.
634 // Note that the varstore-select-pair only applies to the following
635 // opcode.
636 //
637 if ((mPrimaryVarStoreId != mSecondaryVarStoreId) || (mPrimaryVarStoreId != mDefaultVarStoreId)) {
638 IAddByte (EFI_IFR_VARSTORE_SELECT_PAIR_OP, 'O', mQueuedLineNum);
639 IAddByte ((UINT8)sizeof (EFI_IFR_VARSTORE_SELECT_PAIR), 'L', 0);
640 IAddByte ((UINT8)mPrimaryVarStoreId, 0, 0);
641 IAddByte ((UINT8)(mPrimaryVarStoreId >> 8), 0, 0);
642 IAddByte ((UINT8)mSecondaryVarStoreId, 0, 0);
643 IAddByte ((UINT8)(mSecondaryVarStoreId >> 8), 0, 0);
644 }
645 } else if (mPrimaryVarStoreIdSet != 0) {
646 mPrimaryVarStoreIdSet = 0;
647 if (mDefaultVarStoreId != mPrimaryVarStoreId) {
648 //
649 // The VFR statement referenced a different variable store
650 // than the last one we reported. Insert a new varstore select
651 // statement.
652 //
653 IAddByte (EFI_IFR_VARSTORE_SELECT_OP, 'O', mQueuedLineNum);
654 IAddByte ((UINT8)sizeof (EFI_IFR_VARSTORE_SELECT), 'L', 0);
655 IAddByte ((UINT8)mPrimaryVarStoreId, 0, 0);
656 IAddByte ((UINT8)(mPrimaryVarStoreId >> 8), 0, 0);
657 mDefaultVarStoreId = mPrimaryVarStoreId;
658 }
659 }
660 //
661 // Likely a new opcode is being added. Since each opcode item in the IFR has
662 // a header that specifies the size of the opcode item (which we don't
663 // know until we find the next opcode in the VFR), we queue up bytes
664 // until we know the size. Then we write them out. So flush the queue
665 // now.
666 //
667 if (mQueuedOpcodeByteValid != 0) {
668 //
669 // Add the previous opcode byte, the length byte, and the binary
670 // data.
671 //
672 IAddByte (mQueuedOpcodeByte, 'O', mQueuedLineNum);
673 IAddByte ((UINT8)(mQueuedByteCount + 2), 'L', 0);
674 for (Count = 0; Count < mQueuedByteCount; Count++) {
675 IAddByte (mQueuedBytes[Count], mQueuedKeyBytes[Count], 0);
676 }
677 mQueuedByteCount = 0;
678 mQueuedOpcodeByteValid = 0;
679 }
680 return 0;
681 }
682
683 int
684 VfrOpcodeHandler::IAddByte (
685 UINT8 ByteVal,
686 UINT8 KeyByte,
687 UINT32 LineNum
688 )
689 /*++
690
691 Routine Description:
692 This internal function is used to add actual IFR bytes to
693 the output stream. Most other functions queue up the bytes
694 in an internal buffer. Once they come here, there's no
695 going back.
696
697
698 Arguments:
699 ByteVal - value to write to output
700 KeyByte - key value tied to the byte -- useful for debug
701 LineNum - line number from source file the byte resulted from
702
703 Returns:
704 0 - if successful
705 1 - failed due to memory allocation failure
706
707 --*/
708 {
709 IFR_BYTE *NewByte;
710 NewByte = (IFR_BYTE *)malloc (sizeof (IFR_BYTE));
711 if (NewByte == NULL) {
712 return 1;
713 }
714 memset ((char *)NewByte, 0, sizeof (IFR_BYTE));
715 NewByte->OpcodeByte = ByteVal;
716 NewByte->KeyByte = KeyByte;
717 NewByte->LineNum = LineNum;
718 //
719 // Add to the list
720 //
721 if (mIfrBytes == NULL) {
722 mIfrBytes = NewByte;
723 } else {
724 mLastIfrByte->Next = NewByte;
725 }
726 mLastIfrByte = NewByte;
727 mBytesWritten++;
728 return 0;
729 }
730
731 VOID
732 WriteStandardFileHeader (
733 FILE *OutFptr
734 )
735 /*++
736
737 Routine Description:
738 This function is invoked to emit a standard header to an
739 output text file.
740
741 Arguments:
742 OutFptr - file to write the header to
743
744 Returns:
745 None
746
747 --*/
748 {
749 UINT32 TempIndex;
750 for (TempIndex = 0; mSourceFileHeader[TempIndex] != NULL; TempIndex++) {
751 fprintf (OutFptr, "%s\n", mSourceFileHeader[TempIndex]);
752 }
753 //
754 // Write out the VFR compiler version
755 //
756 fprintf (OutFptr, "// VFR compiler version " VFR_COMPILER_VERSION "\n//\n");
757 }