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